globals.pas 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473
  1. {
  2. $Id$
  3. Copyright (C) 1993-98 by Florian Klaempfl
  4. This unit implements some support functions and global variables
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {$ifdef tp}
  19. {$E+,N+}
  20. {$endif}
  21. unit globals;
  22. interface
  23. uses
  24. {$ifdef Delphi4}
  25. dmisc,
  26. sysutils,
  27. {$else}
  28. strings,dos,
  29. {$endif}
  30. {$ifdef linux}
  31. {$ifdef TP}
  32. objects,
  33. {$endif}
  34. linux,
  35. {$endif}
  36. globtype,version,tokens,systems,cobjects;
  37. const
  38. {$ifdef linux}
  39. DirSep = '/';
  40. {$else}
  41. {$ifdef amiga}
  42. DirSep = '/';
  43. {$else}
  44. DirSep = '\';
  45. {$endif}
  46. {$endif}
  47. {$ifdef Splitheap}
  48. testsplit : boolean = false;
  49. {$endif Splitheap}
  50. delphimodeswitches : tmodeswitches=
  51. [m_delphi,m_tp,m_all,m_class,m_objpas,m_result,m_string_pchar,
  52. m_pointer_2_procedure,m_autoderef,m_tp_procvar,m_initfinal];
  53. fpcmodeswitches : tmodeswitches=
  54. [m_fpc,m_all,m_string_pchar,m_nested_comment,m_repeat_forward,
  55. m_cvar_support,m_initfinal,m_add_pointer];
  56. objfpcmodeswitches : tmodeswitches=
  57. [m_objfpc,m_fpc,m_all,m_class,m_objpas,m_result,m_string_pchar,m_nested_comment,
  58. m_repeat_forward,m_cvar_support,m_initfinal,m_add_pointer];
  59. tpmodeswitches : tmodeswitches=
  60. [m_tp,m_all,m_tp_procvar];
  61. gpcmodeswitches : tmodeswitches=
  62. [m_gpc,m_all];
  63. type
  64. TSearchPathList = object(TStringQueue)
  65. procedure AddPath(s:string;addfirst:boolean);
  66. procedure AddList(list:TSearchPathList;addfirst:boolean);
  67. function FindFile(const f : string;var b : boolean) : string;
  68. end;
  69. var
  70. { specified inputfile }
  71. inputdir : dirstr;
  72. inputfile : namestr;
  73. inputextension : extstr;
  74. { specified outputfile with -o parameter }
  75. outputfile : namestr;
  76. { specified with -FE or -FU }
  77. outputexedir : dirstr;
  78. outputunitdir : dirstr;
  79. { things specified with parameters }
  80. paralinkoptions,
  81. paradynamiclinker : string;
  82. parapreprocess : boolean;
  83. { directory where the utils can be found (options -FD) }
  84. utilsdirectory : dirstr;
  85. { some flags for global compiler switches }
  86. do_build,
  87. do_make : boolean;
  88. not_unit_proc : boolean;
  89. { path for searching units, different paths can be seperated by ; }
  90. exepath : dirstr; { Path to ppc }
  91. librarysearchpath,
  92. unitsearchpath,
  93. objectsearchpath,
  94. includesearchpath : TSearchPathList;
  95. { deffile }
  96. usewindowapi : boolean;
  97. description : string;
  98. { current position }
  99. token, { current token being parsed }
  100. idtoken : ttoken; { holds the token if the pattern is a known word }
  101. tokenpos, { last postion of the read token }
  102. aktfilepos : tfileposinfo; { current position }
  103. { type of currently parsed block }
  104. { isn't full implemented (FK) }
  105. block_type : tblock_type;
  106. in_args : boolean; { arguments must be checked especially }
  107. parsing_para_level : longint; { parameter level, used to convert
  108. proc calls to proc loads in firstcalln }
  109. { Must_be_valid : boolean; should the variable already have a value
  110. obsolete replace by set_varstate function }
  111. compile_level : word;
  112. make_ref : boolean;
  113. resolving_forward : boolean; { used to add forward reference as second ref }
  114. use_esp_stackframe : boolean; { to test for call with ESP as stack frame }
  115. {$ifdef TP}
  116. use_big : boolean;
  117. {$endif}
  118. { commandline values }
  119. initdefines : tlinkedlist;
  120. initglobalswitches : tglobalswitches;
  121. initmoduleswitches : tmoduleswitches;
  122. initlocalswitches : tlocalswitches;
  123. initmodeswitches : tmodeswitches;
  124. initpackenum : longint;
  125. initpackrecords : tpackrecords;
  126. initoutputformat : tasm;
  127. initoptprocessor : tprocessors;
  128. initasmmode : tasmmode;
  129. { current state values }
  130. aktglobalswitches : tglobalswitches;
  131. aktmoduleswitches : tmoduleswitches;
  132. aktlocalswitches : tlocalswitches;
  133. aktmodeswitches : tmodeswitches;
  134. aktpackenum : longint;
  135. aktpackrecords : tpackrecords;
  136. aktoutputformat : tasm;
  137. aktoptprocessor : tprocessors;
  138. aktasmmode : tasmmode;
  139. { Memory sizes }
  140. heapsize,
  141. maxheapsize,
  142. stacksize : longint;
  143. {$Ifdef EXTDEBUG}
  144. total_of_firstpass,
  145. firstpass_several : longint;
  146. {$ifdef FPC}
  147. EntryMemUsed : longint;
  148. {$endif FPC}
  149. { parameter switches }
  150. debugstop,
  151. only_one_pass : boolean;
  152. {$EndIf EXTDEBUG}
  153. { windows application type }
  154. apptype : tapptype;
  155. const
  156. RelocSection : boolean = true;
  157. RelocSectionSetExplicitly : boolean = false;
  158. DLLsource : boolean = false;
  159. DLLImageBase : pstring = nil;
  160. { used to set all registers used for each global function
  161. this should dramatically decrease the number of
  162. recompilations needed PM }
  163. simplify_ppu : boolean = false;
  164. { should we allow non static members ? }
  165. allow_only_static : boolean = false;
  166. Inside_asm_statement : boolean = false;
  167. { for error info in pp.pas }
  168. const
  169. parser_current_file : string = '';
  170. {$ifdef debug}
  171. { if the pointer don't point to the heap then write an error }
  172. function assigned(p : pointer) : boolean;
  173. {$endif}
  174. function min(a,b : longint) : longint;
  175. function max(a,b : longint) : longint;
  176. function align(i,a:longint):longint;
  177. procedure Replace(var s:string;s1:string;const s2:string);
  178. procedure ReplaceCase(var s:string;const s1,s2:string);
  179. function upper(const s : string) : string;
  180. function lower(const s : string) : string;
  181. function trimspace(const s:string):string;
  182. {$ifdef FPC}
  183. function tostru(i:cardinal) : string;
  184. {$else}
  185. function tostru(i:longint) : string;
  186. {$endif}
  187. procedure uppervar(var s : string);
  188. function tostr(i : longint) : string;
  189. function tostr_with_plus(i : longint) : string;
  190. procedure valint(S : string;var V : longint;var code : integer);
  191. function is_number(const s : string) : boolean;
  192. function ispowerof2(value : longint;var power : longint) : boolean;
  193. { enable ansistring comparison }
  194. function compareansistrings(p1,p2 : pchar;length1,length2 : longint) : longint;
  195. function concatansistrings(p1,p2 : pchar;length1,length2 : longint) : pchar;
  196. function bstoslash(const s : string) : string;
  197. procedure abstract;
  198. function getdatestr:string;
  199. function gettimestr:string;
  200. function filetimestring( t : longint) : string;
  201. procedure DefaultReplacements(var s:string);
  202. function path_absolute(const s : string) : boolean;
  203. Function FileExists ( Const F : String) : Boolean;
  204. Function RemoveFile(const f:string):boolean;
  205. Function RemoveDir(d:string):boolean;
  206. Function GetFileTime ( Var F : File) : Longint;
  207. Function GetNamedFileTime ( Const F : String) : Longint;
  208. Function SplitFileName(const s:string):string;
  209. Function SplitName(const s:string):string;
  210. Function SplitExtension(Const HStr:String):String;
  211. Function AddExtension(Const HStr,ext:String):String;
  212. Function ForceExtension(Const HStr,ext:String):String;
  213. Function FixPath(s:string;allowdot:boolean):string;
  214. function FixFileName(const s:string):string;
  215. procedure SplitBinCmd(const s:string;var bstr,cstr:string);
  216. procedure SynchronizeFileTime(const fn1,fn2:string);
  217. function FindFile(const f : string;path : string;var b : boolean) : string;
  218. function FindExe(bin:string;var found:boolean):string;
  219. Procedure Shell(const command:string);
  220. procedure InitGlobals;
  221. procedure DoneGlobals;
  222. procedure strdispose(var p : pchar);
  223. implementation
  224. uses
  225. comphook;
  226. procedure strdispose(var p : pchar);
  227. begin
  228. if assigned(p) then
  229. begin
  230. freemem(p,strlen(p)+1);
  231. p:=nil;
  232. end;
  233. end;
  234. function ngraphsearchvalue(const s1,s2 : string) : double;
  235. const
  236. n = 3;
  237. var
  238. equals,i,j : longint;
  239. hs : string;
  240. begin
  241. equals:=0;
  242. { is the string long enough ? }
  243. if min(length(s1),length(s2))-n+1<1 then
  244. begin
  245. ngraphsearchvalue:=0.0;
  246. exit;
  247. end;
  248. for i:=1 to length(s1)-n+1 do
  249. begin
  250. hs:=copy(s1,i,n);
  251. for j:=1 to length(s2)-n+1 do
  252. if hs=copy(s2,j,n) then
  253. inc(equals);
  254. end;
  255. {$ifdef fpc}
  256. ngraphsearchvalue:=equals/double(max(length(s1),length(s2))-n+1);
  257. {$else}
  258. ngraphsearchvalue:=equals/(max(length(s1),length(s2))-n+1);
  259. {$endif}
  260. end;
  261. function bstoslash(const s : string) : string;
  262. {
  263. return string s with all \ changed into /
  264. }
  265. var
  266. i : longint;
  267. begin
  268. for i:=1to length(s) do
  269. if s[i]='\' then
  270. bstoslash[i]:='/'
  271. else
  272. bstoslash[i]:=s[i];
  273. {$ifndef TP}
  274. {$ifopt H+}
  275. setlength(bstoslash,length(s));
  276. {$else}
  277. bstoslash[0]:=s[0];
  278. {$endif}
  279. {$else}
  280. bstoslash[0]:=s[0];
  281. {$endif}
  282. end;
  283. {$ifdef debug}
  284. function assigned(p : pointer) : boolean;
  285. {$ifndef FPC}
  286. {$ifndef DPMI}
  287. type
  288. ptrrec = record
  289. ofs,seg : word;
  290. end;
  291. var
  292. lp : longint;
  293. {$endif DPMI}
  294. {$endif FPC}
  295. begin
  296. {$ifdef FPC}
  297. { Assigned is used for procvar and
  298. stack stored temp records !! PM }
  299. (* if (p<>nil) {and
  300. ((p<heaporg) or
  301. (p>heapptr))} then
  302. do_internalerror(230); *)
  303. {$else}
  304. {$ifdef DPMI}
  305. assigned:=(p<>nil);
  306. exit;
  307. {$else DPMI}
  308. if p=nil then
  309. lp:=0
  310. else
  311. lp:=longint(ptrrec(p).seg)*16+longint(ptrrec(p).ofs);
  312. if (lp<>0) and
  313. ((lp<longint(seg(heaporg^))*16+longint(ofs(heaporg^))) or
  314. (lp>longint(seg(heapptr^))*16+longint(ofs(heapptr^)))) then
  315. do_internalerror(230);
  316. {$endif DPMI}
  317. {$endif FPC}
  318. assigned:=(p<>nil);
  319. end;
  320. {$endif}
  321. function min(a,b : longint) : longint;
  322. {
  323. return the minimal of a and b
  324. }
  325. begin
  326. if a>b then
  327. min:=b
  328. else
  329. min:=a;
  330. end;
  331. function max(a,b : longint) : longint;
  332. {
  333. return the maximum of a and b
  334. }
  335. begin
  336. if a<b then
  337. max:=b
  338. else
  339. max:=a;
  340. end;
  341. function align(i,a:longint):longint;
  342. {
  343. return value <i> aligned <a> boundary
  344. }
  345. begin
  346. align:=(i+a-1) and not(a-1);
  347. end;
  348. procedure Replace(var s:string;s1:string;const s2:string);
  349. var
  350. last,
  351. i : longint;
  352. begin
  353. s1:=upper(s1);
  354. last:=0;
  355. repeat
  356. i:=pos(s1,upper(s));
  357. if i=last then
  358. i:=0;
  359. if (i>0) then
  360. begin
  361. Delete(s,i,length(s1));
  362. Insert(s2,s,i);
  363. last:=i;
  364. end;
  365. until (i=0);
  366. end;
  367. procedure ReplaceCase(var s:string;const s1,s2:string);
  368. var
  369. last,
  370. i : longint;
  371. begin
  372. last:=0;
  373. repeat
  374. i:=pos(s1,s);
  375. if i=last then
  376. i:=0;
  377. if (i>0) then
  378. begin
  379. Delete(s,i,length(s1));
  380. Insert(s2,s,i);
  381. last:=i;
  382. end;
  383. until (i=0);
  384. end;
  385. function upper(const s : string) : string;
  386. {
  387. return uppercased string of s
  388. }
  389. var
  390. i : longint;
  391. begin
  392. for i:=1 to length(s) do
  393. if s[i] in ['a'..'z'] then
  394. upper[i]:=char(byte(s[i])-32)
  395. else
  396. upper[i]:=s[i];
  397. {$ifdef FPC}
  398. {$ifopt H+}
  399. setlength(upper,length(s));
  400. {$else}
  401. upper[0]:=s[0];
  402. {$endif}
  403. {$else}
  404. upper[0]:=s[0];
  405. {$endif}
  406. end;
  407. function lower(const s : string) : string;
  408. {
  409. return lowercased string of s
  410. }
  411. var
  412. i : longint;
  413. begin
  414. for i:=1 to length(s) do
  415. if s[i] in ['A'..'Z'] then
  416. lower[i]:=char(byte(s[i])+32)
  417. else
  418. lower[i]:=s[i];
  419. {$ifndef TP}
  420. {$ifopt H+}
  421. setlength(lower,length(s));
  422. {$else}
  423. lower[0]:=s[0];
  424. {$endif}
  425. {$else}
  426. lower[0]:=s[0];
  427. {$endif}
  428. end;
  429. procedure uppervar(var s : string);
  430. {
  431. uppercase string s
  432. }
  433. var
  434. i : longint;
  435. begin
  436. for i:=1 to length(s) do
  437. if s[i] in ['a'..'z'] then
  438. s[i]:=char(byte(s[i])-32);
  439. end;
  440. {$ifdef FPC}
  441. function tostru(i:cardinal):string;
  442. {
  443. return string of value i, but for cardinals
  444. }
  445. var hs:string;
  446. begin
  447. str(i,hs);
  448. tostru:=hs;
  449. end;
  450. {$else FPC}
  451. function tostru(i:longint):string;
  452. begin
  453. tostru:=tostr(i);
  454. end;
  455. {$endif FPC}
  456. function trimspace(const s:string):string;
  457. {
  458. return s with all leading and ending spaces and tabs removed
  459. }
  460. var
  461. i,j : longint;
  462. begin
  463. i:=length(s);
  464. while (i>0) and (s[i] in [#9,' ']) do
  465. dec(i);
  466. j:=1;
  467. while (j<i) and (s[j] in [#9,' ']) do
  468. inc(j);
  469. trimspace:=Copy(s,j,i-j+1);
  470. end;
  471. function tostr(i : longint) : string;
  472. {
  473. return string of value i
  474. }
  475. var
  476. hs : string;
  477. begin
  478. str(i,hs);
  479. tostr:=hs;
  480. end;
  481. function tostr_with_plus(i : longint) : string;
  482. {
  483. return string of value i, but always include a + when i>=0
  484. }
  485. var
  486. hs : string;
  487. begin
  488. str(i,hs);
  489. if i>=0 then
  490. tostr_with_plus:='+'+hs
  491. else
  492. tostr_with_plus:=hs;
  493. end;
  494. procedure valint(S : string;var V : longint;var code : integer);
  495. {
  496. val() with support for octal, which is not supported under tp7
  497. }
  498. {$ifndef FPC}
  499. var
  500. vs : longint;
  501. c : byte;
  502. begin
  503. if s[1]='%' then
  504. begin
  505. vs:=0;
  506. longint(v):=0;
  507. for c:=2 to length(s) do
  508. begin
  509. if s[c]='0' then
  510. vs:=vs shl 1
  511. else
  512. if s[c]='1' then
  513. vs:=vs shl 1+1
  514. else
  515. begin
  516. code:=c;
  517. exit;
  518. end;
  519. end;
  520. code:=0;
  521. longint(v):=vs;
  522. end
  523. else
  524. system.val(S,V,code);
  525. end;
  526. {$else not FPC}
  527. begin
  528. system.val(S,V,code);
  529. end;
  530. {$endif not FPC}
  531. function is_number(const s : string) : boolean;
  532. {
  533. is string a correct number ?
  534. }
  535. var
  536. w : integer;
  537. l : longint;
  538. begin
  539. valint(s,l,w);
  540. is_number:=(w=0);
  541. end;
  542. function ispowerof2(value : longint;var power : longint) : boolean;
  543. {
  544. return if value is a power of 2. And if correct return the power
  545. }
  546. var
  547. hl : longint;
  548. i : longint;
  549. begin
  550. hl:=1;
  551. ispowerof2:=true;
  552. for i:=0 to 31 do
  553. begin
  554. if hl=value then
  555. begin
  556. power:=i;
  557. exit;
  558. end;
  559. hl:=hl shl 1;
  560. end;
  561. ispowerof2:=false;
  562. end;
  563. { enable ansistring comparison }
  564. { 0 means equal }
  565. { 1 means p1 > p2 }
  566. { -1 means p1 < p2 }
  567. function compareansistrings(p1,p2 : pchar;length1,length2 : longint) : longint;
  568. var
  569. i,j : longint;
  570. begin
  571. compareansistrings:=0;
  572. j:=min(length1,length2);
  573. i:=0;
  574. while (i<j) do
  575. begin
  576. if p1[i]>p2[i] then
  577. begin
  578. compareansistrings:=1;
  579. exit;
  580. end
  581. else
  582. if p1[i]<p2[i] then
  583. begin
  584. compareansistrings:=-1;
  585. exit;
  586. end;
  587. inc(i);
  588. end;
  589. if length1>length2 then
  590. compareansistrings:=1
  591. else
  592. if length1<length2 then
  593. compareansistrings:=-1;
  594. end;
  595. function concatansistrings(p1,p2 : pchar;length1,length2 : longint) : pchar;
  596. var
  597. p : pchar;
  598. begin
  599. getmem(p,length1+length2+1);
  600. move(p1[0],p[0],length1);
  601. move(p2[0],p[length1],length2+1);
  602. concatansistrings:=p;
  603. end;
  604. {****************************************************************************
  605. Time Handling
  606. ****************************************************************************}
  607. Function L0(l:longint):string;
  608. {
  609. return the string of value l, if l<10 then insert a zero, so
  610. the string is always at least 2 chars '01','02',etc
  611. }
  612. var
  613. s : string;
  614. begin
  615. Str(l,s);
  616. if l<10 then
  617. s:='0'+s;
  618. L0:=s;
  619. end;
  620. function gettimestr:string;
  621. {
  622. get the current time in a string HH:MM:SS
  623. }
  624. var
  625. hour,min,sec,hsec : word;
  626. begin
  627. {$ifdef delphi}
  628. dmisc.gettime(hour,min,sec,hsec);
  629. {$else delphi}
  630. dos.gettime(hour,min,sec,hsec);
  631. {$endif delphi}
  632. gettimestr:=L0(Hour)+':'+L0(min)+':'+L0(sec);
  633. end;
  634. function getdatestr:string;
  635. {
  636. get the current date in a string YY/MM/DD
  637. }
  638. var
  639. Year,Month,Day,Wday : Word;
  640. begin
  641. {$ifdef delphi}
  642. dmisc.getdate(year,month,day,wday);
  643. {$else}
  644. dos.getdate(year,month,day,wday);
  645. {$endif}
  646. getdatestr:=L0(Year)+'/'+L0(Month)+'/'+L0(Day);
  647. end;
  648. function filetimestring( t : longint) : string;
  649. {
  650. convert dos datetime t to a string YY/MM/DD HH:MM:SS
  651. }
  652. var
  653. {$ifndef linux}
  654. DT : DateTime;
  655. {$endif}
  656. Year,Month,Day,Hour,Min,Sec : Word;
  657. begin
  658. if t=-1 then
  659. begin
  660. FileTimeString:='Not Found';
  661. exit;
  662. end;
  663. {$ifndef linux}
  664. unpacktime(t,DT);
  665. Year:=dT.year;month:=dt.month;day:=dt.day;
  666. Hour:=dt.hour;min:=dt.min;sec:=dt.sec;
  667. {$else}
  668. EpochToLocal (t,year,month,day,hour,min,sec);
  669. {$endif}
  670. filetimestring:=L0(Year)+'/'+L0(Month)+'/'+L0(Day)+' '+L0(Hour)+':'+L0(min)+':'+L0(sec);
  671. end;
  672. {****************************************************************************
  673. Default Macro Handling
  674. ****************************************************************************}
  675. procedure DefaultReplacements(var s:string);
  676. begin
  677. { Replace some macro's }
  678. Replace(s,'$FPCVER',full_version_string);
  679. Replace(s,'$FPCDATE',date_string);
  680. Replace(s,'$FPCTARGET',target_cpu_string);
  681. Replace(s,'$FPCCPU',target_cpu_string);
  682. Replace(s,'$TARGET',target_path);
  683. Replace(s,'$FPCOS',target_path);
  684. end;
  685. {****************************************************************************
  686. File Handling
  687. ****************************************************************************}
  688. function path_absolute(const s : string) : boolean;
  689. {
  690. is path s an absolute path?
  691. }
  692. begin
  693. path_absolute:=false;
  694. {$ifdef linux}
  695. if (length(s)>0) and (s[1]='/') then
  696. path_absolute:=true;
  697. {$else linux}
  698. {$ifdef amiga}
  699. if ((length(s)>0) and ((s[1]='\') or (s[1]='/'))) or (Pos(':',s) = length(s)) then
  700. path_absolute:=true;
  701. {$else}
  702. if ((length(s)>0) and ((s[1]='\') or (s[1]='/'))) or
  703. ((length(s)>2) and (s[2]=':') and ((s[3]='\') or (s[3]='/'))) then
  704. path_absolute:=true;
  705. {$endif amiga}
  706. {$endif linux}
  707. end;
  708. {$ifndef FPC}
  709. Procedure FindClose(var Info : SearchRec);
  710. Begin
  711. End;
  712. {$endif not FPC}
  713. {$ifdef delphi}
  714. Function FileExists ( Const F : String) : Boolean;
  715. begin
  716. FileExists:=sysutils.FileExists(f);
  717. end;
  718. {$else}
  719. Function FileExists ( Const F : String) : Boolean;
  720. Var
  721. {$ifdef linux}
  722. Info : Stat;
  723. {$else}
  724. Info : SearchRec;
  725. {$endif}
  726. begin
  727. {$ifdef linux}
  728. FileExists:=FStat(F,info);
  729. {$else}
  730. findfirst(F,readonly+archive+hidden,info);
  731. FileExists:=(doserror=0);
  732. findclose(Info);
  733. {$endif}
  734. end;
  735. {$endif}
  736. Function RemoveFile(const f:string):boolean;
  737. var
  738. g : file;
  739. begin
  740. assign(g,f);
  741. {$I-}
  742. erase(g);
  743. {$I+}
  744. RemoveFile:=(ioresult=0);
  745. end;
  746. Function RemoveDir(d:string):boolean;
  747. begin
  748. if d[length(d)]=DirSep then
  749. Delete(d,length(d),1);
  750. {$I-}
  751. rmdir(d);
  752. {$I+}
  753. RemoveDir:=(ioresult=0);
  754. end;
  755. Function SplitFileName(const s:string):string;
  756. var
  757. p : dirstr;
  758. n : namestr;
  759. e : extstr;
  760. begin
  761. FSplit(s,p,n,e);
  762. SplitFileName:=n+e;
  763. end;
  764. Function SplitName(const s:string):string;
  765. var
  766. i,j : longint;
  767. begin
  768. i:=Length(s);
  769. j:=Length(s);
  770. while (i>0) and not(s[i] in ['/','\']) do
  771. dec(i);
  772. while (j>0) and (s[j]<>'.') do
  773. dec(j);
  774. if j<=i then
  775. j:=255;
  776. SplitName:=Copy(s,i+1,j-(i+1));
  777. end;
  778. Function SplitExtension(Const HStr:String):String;
  779. var
  780. j : longint;
  781. begin
  782. j:=length(Hstr);
  783. while (j>0) and (Hstr[j]<>'.') do
  784. begin
  785. if hstr[j]=DirSep then
  786. j:=0
  787. else
  788. dec(j);
  789. end;
  790. if j=0 then
  791. j:=254;
  792. SplitExtension:=Copy(Hstr,j,255);
  793. end;
  794. Function AddExtension(Const HStr,ext:String):String;
  795. begin
  796. if (Ext<>'') and (SplitExtension(HStr)='') then
  797. AddExtension:=Hstr+Ext
  798. else
  799. AddExtension:=Hstr;
  800. end;
  801. Function ForceExtension(Const HStr,ext:String):String;
  802. var
  803. j : longint;
  804. begin
  805. j:=length(Hstr);
  806. while (j>0) and (Hstr[j]<>'.') do
  807. dec(j);
  808. if j=0 then
  809. j:=255;
  810. ForceExtension:=Copy(Hstr,1,j-1)+Ext;
  811. end;
  812. Function FixPath(s:string;allowdot:boolean):string;
  813. var
  814. i : longint;
  815. begin
  816. { Fix separator }
  817. for i:=1 to length(s) do
  818. if s[i] in ['/','\'] then
  819. s[i]:=DirSep;
  820. { Fix ending / }
  821. if (length(s)>0) and (s[length(s)]<>DirSep) and
  822. (s[length(s)]<>':') then
  823. s:=s+DirSep;
  824. { Remove ./ }
  825. if (not allowdot) and (s='.'+DirSep) then
  826. s:='';
  827. { return }
  828. FixPath:=s;
  829. end;
  830. function FixFileName(const s:string):string;
  831. var
  832. i : longint;
  833. {$ifdef Linux}
  834. NoPath : boolean;
  835. {$endif Linux}
  836. begin
  837. {$ifdef Linux}
  838. NoPath:=true;
  839. {$endif Linux}
  840. for i:=length(s) downto 1 do
  841. begin
  842. case s[i] of
  843. {$ifdef Linux}
  844. '/','\' : begin
  845. FixFileName[i]:='/';
  846. NoPath:=false; {Skip lowercasing path: 'X11'<>'x11' }
  847. end;
  848. 'A'..'Z' : if NoPath then
  849. FixFileName[i]:=char(byte(s[i])+32)
  850. else
  851. FixFileName[i]:=s[i];
  852. {$else}
  853. '/' : FixFileName[i]:='\';
  854. 'A'..'Z' : FixFileName[i]:=char(byte(s[i])+32);
  855. {$endif}
  856. else
  857. FixFileName[i]:=s[i];
  858. end;
  859. end;
  860. {$ifndef TP}
  861. {$ifopt H+}
  862. SetLength(FixFileName,length(s));
  863. {$else}
  864. FixFileName[0]:=s[0];
  865. {$endif}
  866. {$else}
  867. FixFileName[0]:=s[0];
  868. {$endif}
  869. end;
  870. procedure SplitBinCmd(const s:string;var bstr,cstr:string);
  871. var
  872. i : longint;
  873. begin
  874. i:=pos(' ',s);
  875. if i>0 then
  876. begin
  877. bstr:=Copy(s,1,i-1);
  878. cstr:=Copy(s,i+1,length(s)-i);
  879. end
  880. else
  881. begin
  882. bstr:='';
  883. cstr:='';
  884. end;
  885. end;
  886. procedure TSearchPathList.AddPath(s:string;addfirst:boolean);
  887. var
  888. j : longint;
  889. CurrentDir,
  890. CurrPath : string;
  891. hp : PStringQueueItem;
  892. begin
  893. if s='' then
  894. exit;
  895. { Support default macro's }
  896. DefaultReplacements(s);
  897. { get current dir }
  898. GetDir(0,CurrentDir);
  899. CurrentDir:=FixPath(CurrentDir,false);
  900. repeat
  901. j:=Pos(';',s);
  902. if j=0 then
  903. j:=255;
  904. {Get Pathname}
  905. CurrPath:=FixPath(Copy(s,1,j-1),false);
  906. if CurrPath='' then
  907. CurrPath:='.'+DirSep
  908. else
  909. begin
  910. CurrPath:=FixPath(FExpand(CurrPath),false);
  911. if (Copy(CurrPath,1,length(CurrentDir))=CurrentDir) then
  912. CurrPath:='.'+DirSep+Copy(CurrPath,length(CurrentDir)+1,255);
  913. end;
  914. System.Delete(s,1,j);
  915. if addfirst then
  916. begin
  917. Delete(currPath);
  918. Insert(currPath);
  919. end
  920. else
  921. begin
  922. { Check if already in path, then we don't add it }
  923. hp:=Find(currPath);
  924. if not assigned(hp) then
  925. Concat(currPath);
  926. end;
  927. until (s='');
  928. end;
  929. procedure TSearchPathList.AddList(list:TSearchPathList;addfirst:boolean);
  930. var
  931. s : string;
  932. hl : TSearchPathList;
  933. hp,hp2 : PStringQueueItem;
  934. begin
  935. if list.empty then
  936. exit;
  937. { create temp and reverse the list }
  938. if addfirst then
  939. begin
  940. hl.Init;
  941. hp:=list.first;
  942. while assigned(hp) do
  943. begin
  944. hl.insert(hp^.data^);
  945. hp:=hp^.next;
  946. end;
  947. while not hl.empty do
  948. begin
  949. s:=hl.Get;
  950. Delete(s);
  951. Insert(s);
  952. end;
  953. hl.done;
  954. end
  955. else
  956. begin
  957. hp:=list.first;
  958. while assigned(hp) do
  959. begin
  960. hp2:=Find(hp^.data^);
  961. { Check if already in path, then we don't add it }
  962. if not assigned(hp2) then
  963. Concat(hp^.data^);
  964. hp:=hp^.next;
  965. end;
  966. end;
  967. end;
  968. function TSearchPathList.FindFile(const f : string;var b : boolean) : string;
  969. Var
  970. p : PStringQueueItem;
  971. begin
  972. FindFile:='';
  973. b:=false;
  974. p:=first;
  975. while assigned(p) do
  976. begin
  977. If FileExists(p^.data^+f) then
  978. begin
  979. FindFile:=p^.data^;
  980. b:=true;
  981. exit;
  982. end;
  983. p:=p^.next;
  984. end;
  985. end;
  986. Function GetFileTime ( Var F : File) : Longint;
  987. Var
  988. {$ifdef linux}
  989. Info : Stat;
  990. {$endif}
  991. L : longint;
  992. begin
  993. {$ifdef linux}
  994. FStat (F,Info);
  995. L:=Info.Mtime;
  996. {$else}
  997. GetFTime(f,l);
  998. {$endif}
  999. GetFileTime:=L;
  1000. end;
  1001. Function GetNamedFileTime (Const F : String) : Longint;
  1002. var
  1003. L : Longint;
  1004. {$ifndef linux}
  1005. info : SearchRec;
  1006. {$else}
  1007. info : stat;
  1008. {$endif}
  1009. begin
  1010. l:=-1;
  1011. {$ifdef linux}
  1012. if FStat (F,Info) then
  1013. L:=info.mtime;
  1014. {$else}
  1015. {$ifdef delphi}
  1016. dmisc.FindFirst (F,archive+readonly+hidden,info);
  1017. {$else delphi}
  1018. FindFirst (F,archive+readonly+hidden,info);
  1019. {$endif delphi}
  1020. if DosError=0 then
  1021. l:=info.time;
  1022. {$ifdef Linux}
  1023. FindClose(info);
  1024. {$endif}
  1025. {$ifdef Win32}
  1026. FindClose(info);
  1027. {$endif}
  1028. {$endif}
  1029. GetNamedFileTime:=l;
  1030. end;
  1031. {Touch Assembler and object time to ppu time is there is a ppufilename}
  1032. procedure SynchronizeFileTime(const fn1,fn2:string);
  1033. var
  1034. f : file;
  1035. l : longint;
  1036. begin
  1037. Assign(f,fn1);
  1038. {$I-}
  1039. reset(f,1);
  1040. {$I+}
  1041. if ioresult=0 then
  1042. begin
  1043. getftime(f,l);
  1044. close(f);
  1045. assign(f,fn2);
  1046. {$I-}
  1047. reset(f,1);
  1048. {$I+}
  1049. if ioresult=0 then
  1050. begin
  1051. setftime(f,l);
  1052. close(f);
  1053. end;
  1054. end;
  1055. end;
  1056. function FindFile(const f : string;path : string;var b : boolean) : string;
  1057. Var
  1058. singlepathstring : string;
  1059. i : longint;
  1060. begin
  1061. {$ifdef linux}
  1062. for i:=1 to length(path) do
  1063. if path[i]=':' then
  1064. path[i]:=';';
  1065. {$endif}
  1066. b:=false;
  1067. FindFile:='';
  1068. repeat
  1069. i:=pos(';',path);
  1070. if i=0 then
  1071. i:=255;
  1072. singlepathstring:=FixPath(copy(path,1,i-1),false);
  1073. delete(path,1,i);
  1074. If FileExists (singlepathstring+f) then
  1075. begin
  1076. FindFile:=singlepathstring;
  1077. b:=true;
  1078. exit;
  1079. end;
  1080. until path='';
  1081. end;
  1082. function FindExe(bin:string;var found:boolean):string;
  1083. begin
  1084. bin:=FixFileName(bin)+source_os.exeext;
  1085. {$ifdef delphi}
  1086. FindExe:=FindFile(bin,'.;'+exepath+';'+dmisc.getenv('PATH'),found)+bin;
  1087. {$else delphi}
  1088. FindExe:=FindFile(bin,'.;'+exepath+';'+dos.getenv('PATH'),found)+bin;
  1089. {$endif delphi}
  1090. end;
  1091. procedure abstract;
  1092. begin
  1093. do_internalerror(255);
  1094. end;
  1095. Procedure Shell(const command:string);
  1096. { This is already defined in the linux.ppu for linux, need for the *
  1097. expansion under linux }
  1098. {$ifdef linux}
  1099. begin
  1100. Linux.Shell(command);
  1101. end;
  1102. {$else}
  1103. var
  1104. comspec : string;
  1105. begin
  1106. comspec:=getenv('COMSPEC');
  1107. Exec(comspec,' /C '+command);
  1108. end;
  1109. {$endif}
  1110. {****************************************************************************
  1111. Init
  1112. ****************************************************************************}
  1113. procedure get_exepath;
  1114. var
  1115. hs1 : namestr;
  1116. hs2 : extstr;
  1117. begin
  1118. {$ifdef delphi}
  1119. exepath:=dmisc.getenv('PPC_EXEC_PATH');
  1120. {$else delphi}
  1121. exepath:=dos.getenv('PPC_EXEC_PATH');
  1122. {$endif delphi}
  1123. if exepath='' then
  1124. fsplit(FixFileName(paramstr(0)),exepath,hs1,hs2);
  1125. {$ifdef linux}
  1126. if exepath='' then
  1127. fsearch(hs1,dos.getenv('PATH'));
  1128. {$endif}
  1129. exepath:=FixPath(exepath,false);
  1130. end;
  1131. procedure DoneGlobals;
  1132. begin
  1133. initdefines.done;
  1134. if assigned(DLLImageBase) then
  1135. StringDispose(DLLImageBase);
  1136. librarysearchpath.Done;
  1137. unitsearchpath.Done;
  1138. objectsearchpath.Done;
  1139. includesearchpath.Done;
  1140. end;
  1141. procedure InitGlobals;
  1142. begin
  1143. { set global switches }
  1144. do_build:=false;
  1145. do_make:=true;
  1146. {$ifdef tp}
  1147. use_big:=false;
  1148. {$endif tp}
  1149. compile_level:=0;
  1150. { Output }
  1151. OutputFile:='';
  1152. OutputExeDir:='';
  1153. OutputUnitDir:='';
  1154. { Utils directory }
  1155. utilsdirectory:='';
  1156. { Search Paths }
  1157. librarysearchpath.Init;
  1158. unitsearchpath.Init;
  1159. includesearchpath.Init;
  1160. objectsearchpath.Init;
  1161. { Def file }
  1162. usewindowapi:=false;
  1163. description:='Compiled by FPC '+version_string+' - '+target_cpu_string;
  1164. { Init values }
  1165. initmodeswitches:=fpcmodeswitches;
  1166. initlocalswitches:=[cs_check_io];
  1167. initmoduleswitches:=[cs_extsyntax,cs_browser];
  1168. initglobalswitches:=[cs_check_unit_name,cs_link_static];
  1169. {$ifdef i386}
  1170. initoptprocessor:=Class386;
  1171. initpackenum:=4;
  1172. initpackrecords:=packrecord_2;
  1173. initoutputformat:=target_asm.id;
  1174. initasmmode:=asmmode_i386_att;
  1175. {$else not i386}
  1176. {$ifdef m68k}
  1177. initoptprocessor:=MC68000;
  1178. include(initmoduleswitches,cs_fp_emulation);
  1179. initpackenum:=4;
  1180. initpackrecords:=packrecord_2;
  1181. initoutputformat:=as_m68k_as;
  1182. initasmmode:=asmmode_m68k_mot;
  1183. {$endif m68k}
  1184. {$endif i386}
  1185. initdefines.init;
  1186. { memory sizes, will be overriden by parameter or default for target
  1187. in options or init_parser }
  1188. stacksize:=0;
  1189. heapsize:=0;
  1190. maxheapsize:=0;
  1191. { compile state }
  1192. in_args:=false;
  1193. { must_be_valid:=true; obsolete PM }
  1194. not_unit_proc:=true;
  1195. apptype:=at_cui;
  1196. end;
  1197. begin
  1198. get_exepath;
  1199. {$ifdef EXTDEBUG}
  1200. {$ifdef FPC}
  1201. EntryMemUsed:=system.HeapSize-MemAvail;
  1202. {$endif FPC}
  1203. {$endif}
  1204. end.
  1205. {
  1206. $Log$
  1207. Revision 1.37 1999-12-02 17:34:34 peter
  1208. * preprocessor support. But it fails on the caret in type blocks
  1209. Revision 1.36 1999/11/18 15:34:45 pierre
  1210. * Notes/Hints for local syms changed to
  1211. Set_varstate function
  1212. Revision 1.35 1999/11/17 17:04:59 pierre
  1213. * Notes/hints changes
  1214. Revision 1.34 1999/11/15 17:42:41 pierre
  1215. * -g disables reloc section for win32
  1216. Revision 1.33 1999/11/12 11:03:50 peter
  1217. * searchpaths changed to stringqueue object
  1218. Revision 1.32 1999/11/09 23:34:46 pierre
  1219. + resolving_forward boolean used for references
  1220. Revision 1.31 1999/11/09 13:00:38 peter
  1221. * define FPC_DELPHI,FPC_OBJFPC,FPC_TP,FPC_GPC
  1222. * initial support for ansistring default with modes
  1223. Revision 1.30 1999/11/08 16:27:20 pierre
  1224. + Reset AnsiStrings to clean up memory
  1225. Revision 1.29 1999/11/06 14:34:20 peter
  1226. * truncated log to 20 revs
  1227. Revision 1.28 1999/11/04 10:55:31 peter
  1228. * TSearchPathList for the string type of the searchpaths, which is
  1229. ansistring under FPC/Delphi
  1230. Revision 1.27 1999/10/26 12:30:41 peter
  1231. * const parameter is now checked
  1232. * better and generic check if a node can be used for assigning
  1233. * export fixes
  1234. * procvar equal works now (it never had worked at least from 0.99.8)
  1235. * defcoll changed to linkedlist with pparaitem so it can easily be
  1236. walked both directions
  1237. Revision 1.26 1999/10/21 14:29:34 peter
  1238. * redesigned linker object
  1239. + library support for linux (only procedures can be exported)
  1240. Revision 1.25 1999/09/10 18:48:02 florian
  1241. * some bug fixes (e.g. must_be_valid and procinfo.funcret_is_valid)
  1242. * most things for stored properties fixed
  1243. Revision 1.24 1999/09/08 16:05:31 peter
  1244. * pointer add/sub is now as expected and the same results as inc/dec
  1245. Revision 1.23 1999/09/07 15:11:00 pierre
  1246. * use do_internalerror insetead of runerror
  1247. Revision 1.22 1999/08/30 10:17:56 peter
  1248. * fixed crash in psub
  1249. * ansistringcompare fixed
  1250. * support for #$0b8
  1251. Revision 1.21 1999/08/27 10:45:00 pierre
  1252. options -Ca sets simply_ppu to true
  1253. Revision 1.20 1999/08/19 13:02:12 pierre
  1254. + label faillabel added for _FAIL support
  1255. Revision 1.19 1999/08/16 15:35:21 pierre
  1256. * fix for DLL relocation problems
  1257. * external bss vars had wrong stabs for pecoff
  1258. + -WB11000000 to specify default image base, allows to
  1259. load several DLLs with debugging info included
  1260. (relocatable DLL are stripped because the relocation
  1261. of the .Stab section is misplaced by ldw)
  1262. Revision 1.18 1999/08/11 17:26:32 peter
  1263. * tlinker object is now inherited for win32 and dos
  1264. * postprocessexecutable is now a method of tlinker
  1265. Revision 1.17 1999/08/10 12:51:14 pierre
  1266. * bind_win32_dll removed (Relocsection used instead)
  1267. * now relocsection is true by default ! (needs dlltool
  1268. for DLL generation)
  1269. Revision 1.16 1999/08/05 20:54:19 daniel
  1270. * Changes for new symtable.
  1271. Revision 1.15 1999/08/03 17:09:35 florian
  1272. * the alpha compiler can be compiled now
  1273. Revision 1.14 1999/07/23 16:05:19 peter
  1274. * alignment is now saved in the symtable
  1275. * C alignment added for records
  1276. * PPU version increased to solve .12 <-> .13 probs
  1277. Revision 1.13 1999/07/18 10:19:52 florian
  1278. * made it compilable with Dlephi 4 again
  1279. + fixed problem with large stack allocations on win32
  1280. Revision 1.12 1999/07/13 19:14:44 michael
  1281. + Defaultreplacemens now more logical
  1282. Revision 1.11 1999/07/10 10:26:18 peter
  1283. * merged
  1284. Revision 1.8.2.2 1999/07/10 10:03:04 peter
  1285. * fixed initialization/finalization in fpc mode
  1286. * allow $TARGET also in search paths
  1287. Revision 1.8.2.1 1999/07/07 07:53:21 michael
  1288. + Merged patches from florian
  1289. }