globals.pas 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731
  1. {
  2. $Id$
  3. Copyright (C) 1998-2000 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 win32}
  25. windows,
  26. {$endif}
  27. {$ifdef linux}
  28. linux,
  29. {$endif}
  30. {$ifdef Delphi}
  31. sysutils,
  32. dmisc,
  33. {$else}
  34. strings,dos,
  35. {$endif}
  36. {$ifdef TP}
  37. objects,
  38. {$endif}
  39. globtype,version,tokens,systems,cobjects;
  40. const
  41. {$ifdef linux}
  42. DirSep = '/';
  43. {$else}
  44. {$ifdef amiga}
  45. DirSep = '/';
  46. {$else}
  47. DirSep = '\';
  48. {$endif}
  49. {$endif}
  50. {$ifdef Splitheap}
  51. testsplit : boolean = false;
  52. {$endif Splitheap}
  53. delphimodeswitches : tmodeswitches=
  54. [m_delphi,m_tp,m_all,m_class,m_objpas,m_result,m_string_pchar,
  55. m_pointer_2_procedure,m_autoderef,m_tp_procvar,m_initfinal,m_default_ansistring];
  56. fpcmodeswitches : tmodeswitches=
  57. [m_fpc,m_all,m_string_pchar,m_nested_comment,m_repeat_forward,
  58. m_cvar_support,m_initfinal,m_add_pointer];
  59. objfpcmodeswitches : tmodeswitches=
  60. [m_objfpc,m_fpc,m_all,m_class,m_objpas,m_result,m_string_pchar,m_nested_comment,
  61. m_repeat_forward,m_cvar_support,m_initfinal,m_add_pointer];
  62. tpmodeswitches : tmodeswitches=
  63. [m_tp7,m_tp,m_all,m_tp_procvar];
  64. gpcmodeswitches : tmodeswitches=
  65. [m_gpc,m_all];
  66. type
  67. TSearchPathList = object(TStringQueue)
  68. procedure AddPath(s:string;addfirst:boolean);
  69. procedure AddList(list:TSearchPathList;addfirst:boolean);
  70. function FindFile(const f : string;var b : boolean) : string;
  71. end;
  72. var
  73. { specified inputfile }
  74. inputdir : dirstr;
  75. inputfile : namestr;
  76. inputextension : extstr;
  77. { specified outputfile with -o parameter }
  78. outputfile : namestr;
  79. { specified with -FE or -FU }
  80. outputexedir : dirstr;
  81. outputunitdir : dirstr;
  82. { things specified with parameters }
  83. paralinkoptions,
  84. paradynamiclinker : string;
  85. parapreprocess : boolean;
  86. { directory where the utils can be found (options -FD) }
  87. utilsdirectory : dirstr;
  88. { some flags for global compiler switches }
  89. do_build,
  90. do_make : boolean;
  91. not_unit_proc : boolean;
  92. { path for searching units, different paths can be seperated by ; }
  93. exepath : dirstr; { Path to ppc }
  94. librarysearchpath,
  95. unitsearchpath,
  96. objectsearchpath,
  97. includesearchpath : TSearchPathList;
  98. { deffile }
  99. usewindowapi : boolean;
  100. description : string;
  101. dllversion : string;
  102. dllmajor,dllminor : word;
  103. { current position }
  104. token, { current token being parsed }
  105. idtoken : ttoken; { holds the token if the pattern is a known word }
  106. tokenpos, { last postion of the read token }
  107. aktfilepos : tfileposinfo; { current position }
  108. { type of currently parsed block }
  109. { isn't full implemented (FK) }
  110. block_type : tblock_type;
  111. in_args : boolean; { arguments must be checked especially }
  112. parsing_para_level : longint; { parameter level, used to convert
  113. proc calls to proc loads in firstcalln }
  114. { Must_be_valid : boolean; should the variable already have a value
  115. obsolete replace by set_varstate function }
  116. compile_level : word;
  117. make_ref : boolean;
  118. resolving_forward : boolean; { used to add forward reference as second ref }
  119. use_esp_stackframe : boolean; { to test for call with ESP as stack frame }
  120. inlining_procedure : boolean; { are we inlining a procedure }
  121. {$ifdef TP}
  122. use_big : boolean;
  123. {$endif}
  124. { commandline values }
  125. initdefines : tlinkedlist;
  126. initglobalswitches : tglobalswitches;
  127. initmoduleswitches : tmoduleswitches;
  128. initlocalswitches : tlocalswitches;
  129. initmodeswitches : tmodeswitches;
  130. {$IFDEF testvarsets}
  131. Initsetalloc, {0=fixed, 1 =var}
  132. {$ENDIF}
  133. initpackenum : longint;
  134. initpackrecords : tpackrecords;
  135. initoutputformat : tasm;
  136. initoptprocessor,
  137. initspecificoptprocessor : tprocessors;
  138. initasmmode : tasmmode;
  139. { current state values }
  140. aktglobalswitches : tglobalswitches;
  141. aktmoduleswitches : tmoduleswitches;
  142. aktlocalswitches : tlocalswitches;
  143. nextaktlocalswitches : tlocalswitches;
  144. localswitcheschanged : boolean;
  145. aktmodeswitches : tmodeswitches;
  146. {$IFDEF testvarsets}
  147. aktsetalloc,
  148. {$ENDIF}
  149. aktpackenum : longint;
  150. aktmaxfpuregisters: longint;
  151. aktpackrecords : tpackrecords;
  152. aktoutputformat : tasm;
  153. aktoptprocessor,
  154. aktspecificoptprocessor : tprocessors;
  155. aktasmmode : tasmmode;
  156. { Memory sizes }
  157. heapsize,
  158. maxheapsize,
  159. stacksize : longint;
  160. {$Ifdef EXTDEBUG}
  161. total_of_firstpass,
  162. firstpass_several : longint;
  163. {$ifdef FPC}
  164. EntryMemUsed : longint;
  165. {$endif FPC}
  166. { parameter switches }
  167. debugstop,
  168. only_one_pass : boolean;
  169. {$EndIf EXTDEBUG}
  170. { windows application type }
  171. apptype : tapptype;
  172. const
  173. RelocSection : boolean = true;
  174. RelocSectionSetExplicitly : boolean = false;
  175. DLLsource : boolean = false;
  176. DLLImageBase : pstring = nil;
  177. UseDeffileForExport : boolean = true;
  178. ForceDeffileForExport : boolean = false;
  179. { used to set all registers used for each global function
  180. this should dramatically decrease the number of
  181. recompilations needed PM }
  182. simplify_ppu : boolean = false;
  183. { should we allow non static members ? }
  184. allow_only_static : boolean = false;
  185. Inside_asm_statement : boolean = false;
  186. { for error info in pp.pas }
  187. const
  188. parser_current_file : string = '';
  189. {$ifdef debug}
  190. { if the pointer don't point to the heap then write an error }
  191. function assigned(p : pointer) : boolean;
  192. {$endif}
  193. function min(a,b : longint) : longint;
  194. function max(a,b : longint) : longint;
  195. function align(i,a:longint):longint;
  196. function align_from_size(datasize:longint;length:longint):longint;
  197. procedure Replace(var s:string;s1:string;const s2:string);
  198. procedure ReplaceCase(var s:string;const s1,s2:string);
  199. function upper(const s : string) : string;
  200. function lower(const s : string) : string;
  201. function trimspace(const s:string):string;
  202. {$ifdef FPC}
  203. function tostru(i:cardinal) : string;
  204. {$else}
  205. function tostru(i:longint) : string;
  206. {$endif}
  207. procedure uppervar(var s : string);
  208. function hexstr(val : longint;cnt : byte) : string;
  209. function tostr(i : longint) : string;
  210. function tostr_with_plus(i : longint) : string;
  211. procedure valint(S : string;var V : longint;var code : integer);
  212. function is_number(const s : string) : boolean;
  213. function ispowerof2(value : longint;var power : longint) : boolean;
  214. { enable ansistring comparison }
  215. function compareansistrings(p1,p2 : pchar;length1,length2 : longint) : longint;
  216. function concatansistrings(p1,p2 : pchar;length1,length2 : longint) : pchar;
  217. function bstoslash(const s : string) : string;
  218. procedure abstract;
  219. function getdatestr:string;
  220. function gettimestr:string;
  221. function filetimestring( t : longint) : string;
  222. procedure DefaultReplacements(var s:string);
  223. function GetCurrentDir:string;
  224. function path_absolute(const s : string) : boolean;
  225. Function PathExists ( F : String) : Boolean;
  226. Function FileExists ( Const F : String) : Boolean;
  227. Function RemoveFile(const f:string):boolean;
  228. Function RemoveDir(d:string):boolean;
  229. Function GetFileTime ( Var F : File) : Longint;
  230. Function GetNamedFileTime ( Const F : String) : Longint;
  231. Function SplitPath(const s:string):string;
  232. Function SplitFileName(const s:string):string;
  233. Function SplitName(const s:string):string;
  234. Function SplitExtension(Const HStr:String):String;
  235. Function AddExtension(Const HStr,ext:String):String;
  236. Function ForceExtension(Const HStr,ext:String):String;
  237. Function FixPath(s:string;allowdot:boolean):string;
  238. function FixFileName(const s:string):string;
  239. procedure SplitBinCmd(const s:string;var bstr,cstr:string);
  240. procedure SynchronizeFileTime(const fn1,fn2:string);
  241. function FindFile(const f : string;path : string;var b : boolean) : string;
  242. function FindExe(bin:string;var found:boolean):string;
  243. function GetShortName(const n:string):string;
  244. Procedure Shell(const command:string);
  245. function GetEnvPChar(const envname:string):pchar;
  246. procedure FreeEnvPChar(p:pchar);
  247. procedure InitGlobals;
  248. procedure DoneGlobals;
  249. implementation
  250. uses
  251. comphook;
  252. procedure abstract;
  253. begin
  254. do_internalerror(255);
  255. end;
  256. function ngraphsearchvalue(const s1,s2 : string) : double;
  257. const
  258. n = 3;
  259. var
  260. equals,i,j : longint;
  261. hs : string;
  262. begin
  263. equals:=0;
  264. { is the string long enough ? }
  265. if min(length(s1),length(s2))-n+1<1 then
  266. begin
  267. ngraphsearchvalue:=0.0;
  268. exit;
  269. end;
  270. for i:=1 to length(s1)-n+1 do
  271. begin
  272. hs:=copy(s1,i,n);
  273. for j:=1 to length(s2)-n+1 do
  274. if hs=copy(s2,j,n) then
  275. inc(equals);
  276. end;
  277. {$ifdef fpc}
  278. ngraphsearchvalue:=equals/double(max(length(s1),length(s2))-n+1);
  279. {$else}
  280. ngraphsearchvalue:=equals/(max(length(s1),length(s2))-n+1);
  281. {$endif}
  282. end;
  283. function bstoslash(const s : string) : string;
  284. {
  285. return string s with all \ changed into /
  286. }
  287. var
  288. i : longint;
  289. begin
  290. for i:=1to length(s) do
  291. if s[i]='\' then
  292. bstoslash[i]:='/'
  293. else
  294. bstoslash[i]:=s[i];
  295. {$ifndef TP}
  296. {$ifopt H+}
  297. setlength(bstoslash,length(s));
  298. {$else}
  299. bstoslash[0]:=s[0];
  300. {$endif}
  301. {$else}
  302. bstoslash[0]:=s[0];
  303. {$endif}
  304. end;
  305. {$ifdef debug}
  306. function assigned(p : pointer) : boolean;
  307. {$ifndef FPC}
  308. {$ifndef DPMI}
  309. type
  310. ptrrec = record
  311. ofs,seg : word;
  312. end;
  313. var
  314. lp : longint;
  315. {$endif DPMI}
  316. {$endif FPC}
  317. begin
  318. {$ifdef FPC}
  319. { Assigned is used for procvar and
  320. stack stored temp records !! PM }
  321. (* if (p<>nil) {and
  322. ((p<heaporg) or
  323. (p>heapptr))} then
  324. do_internalerror(230); *)
  325. {$else}
  326. {$ifdef DPMI}
  327. assigned:=(p<>nil);
  328. exit;
  329. {$else DPMI}
  330. if p=nil then
  331. lp:=0
  332. else
  333. lp:=longint(ptrrec(p).seg)*16+longint(ptrrec(p).ofs);
  334. if (lp<>0) and
  335. ((lp<longint(seg(heaporg^))*16+longint(ofs(heaporg^))) or
  336. (lp>longint(seg(heapptr^))*16+longint(ofs(heapptr^)))) then
  337. do_internalerror(230);
  338. {$endif DPMI}
  339. {$endif FPC}
  340. assigned:=(p<>nil);
  341. end;
  342. {$endif}
  343. function min(a,b : longint) : longint;
  344. {
  345. return the minimal of a and b
  346. }
  347. begin
  348. if a>b then
  349. min:=b
  350. else
  351. min:=a;
  352. end;
  353. function max(a,b : longint) : longint;
  354. {
  355. return the maximum of a and b
  356. }
  357. begin
  358. if a<b then
  359. max:=b
  360. else
  361. max:=a;
  362. end;
  363. function align_from_size(datasize:longint;length:longint):longint;
  364. {Increases the datasize with the required alignment; i.e. on pentium
  365. words should be aligned word; and dwords should be aligned dword.
  366. So for a word (len=2), datasize is increased to the nearest multiple
  367. of 2, and for len=4, datasize is increased to the nearest multiple of
  368. 4.}
  369. var data_align:word;
  370. begin
  371. {$IFDEF I386}
  372. if length>2 then
  373. data_align:=4
  374. else if length>1 then
  375. data_align:=2
  376. else
  377. data_align:=1;
  378. {$ENDIF}
  379. {$IFDEF M68K}
  380. data_align:=2;
  381. {$ENDIF}
  382. align_from_size:=(datasize+data_align-1) and not(data_align-1);
  383. end;
  384. function align(i,a:longint):longint;
  385. {
  386. return value <i> aligned <a> boundary
  387. }
  388. begin
  389. align:=(i+a-1) and not(a-1);
  390. end;
  391. procedure Replace(var s:string;s1:string;const s2:string);
  392. var
  393. last,
  394. i : longint;
  395. begin
  396. s1:=upper(s1);
  397. last:=0;
  398. repeat
  399. i:=pos(s1,upper(s));
  400. if i=last then
  401. i:=0;
  402. if (i>0) then
  403. begin
  404. Delete(s,i,length(s1));
  405. Insert(s2,s,i);
  406. last:=i;
  407. end;
  408. until (i=0);
  409. end;
  410. procedure ReplaceCase(var s:string;const s1,s2:string);
  411. var
  412. last,
  413. i : longint;
  414. begin
  415. last:=0;
  416. repeat
  417. i:=pos(s1,s);
  418. if i=last then
  419. i:=0;
  420. if (i>0) then
  421. begin
  422. Delete(s,i,length(s1));
  423. Insert(s2,s,i);
  424. last:=i;
  425. end;
  426. until (i=0);
  427. end;
  428. function upper(const s : string) : string;
  429. {
  430. return uppercased string of s
  431. }
  432. var
  433. i : longint;
  434. begin
  435. for i:=1 to length(s) do
  436. if s[i] in ['a'..'z'] then
  437. upper[i]:=char(byte(s[i])-32)
  438. else
  439. upper[i]:=s[i];
  440. upper[0]:=s[0];
  441. end;
  442. function lower(const s : string) : string;
  443. {
  444. return lowercased string of s
  445. }
  446. var
  447. i : longint;
  448. begin
  449. for i:=1 to length(s) do
  450. if s[i] in ['A'..'Z'] then
  451. lower[i]:=char(byte(s[i])+32)
  452. else
  453. lower[i]:=s[i];
  454. lower[0]:=s[0];
  455. end;
  456. procedure uppervar(var s : string);
  457. {
  458. uppercase string s
  459. }
  460. var
  461. i : longint;
  462. begin
  463. for i:=1 to length(s) do
  464. if s[i] in ['a'..'z'] then
  465. s[i]:=char(byte(s[i])-32);
  466. end;
  467. function hexstr(val : longint;cnt : byte) : string;
  468. const
  469. HexTbl : array[0..15] of char='0123456789ABCDEF';
  470. var
  471. i : longint;
  472. begin
  473. hexstr[0]:=char(cnt);
  474. for i:=cnt downto 1 do
  475. begin
  476. hexstr[i]:=hextbl[val and $f];
  477. val:=val shr 4;
  478. end;
  479. end;
  480. {$ifdef FPC}
  481. function tostru(i:cardinal):string;
  482. {
  483. return string of value i, but for cardinals
  484. }
  485. var
  486. hs : string;
  487. begin
  488. str(i,hs);
  489. tostru:=hs;
  490. end;
  491. {$else FPC}
  492. function tostru(i:longint):string;
  493. begin
  494. tostru:=tostr(i);
  495. end;
  496. {$endif FPC}
  497. function trimspace(const s:string):string;
  498. {
  499. return s with all leading and ending spaces and tabs removed
  500. }
  501. var
  502. i,j : longint;
  503. begin
  504. i:=length(s);
  505. while (i>0) and (s[i] in [#9,' ']) do
  506. dec(i);
  507. j:=1;
  508. while (j<i) and (s[j] in [#9,' ']) do
  509. inc(j);
  510. trimspace:=Copy(s,j,i-j+1);
  511. end;
  512. function tostr(i : longint) : string;
  513. {
  514. return string of value i
  515. }
  516. var
  517. hs : string;
  518. begin
  519. str(i,hs);
  520. tostr:=hs;
  521. end;
  522. function tostr_with_plus(i : longint) : string;
  523. {
  524. return string of value i, but always include a + when i>=0
  525. }
  526. var
  527. hs : string;
  528. begin
  529. str(i,hs);
  530. if i>=0 then
  531. tostr_with_plus:='+'+hs
  532. else
  533. tostr_with_plus:=hs;
  534. end;
  535. procedure valint(S : string;var V : longint;var code : integer);
  536. {
  537. val() with support for octal, which is not supported under tp7
  538. }
  539. {$ifndef FPC}
  540. var
  541. vs : longint;
  542. c : byte;
  543. begin
  544. if s[1]='%' then
  545. begin
  546. vs:=0;
  547. longint(v):=0;
  548. for c:=2 to length(s) do
  549. begin
  550. if s[c]='0' then
  551. vs:=vs shl 1
  552. else
  553. if s[c]='1' then
  554. vs:=vs shl 1+1
  555. else
  556. begin
  557. code:=c;
  558. exit;
  559. end;
  560. end;
  561. code:=0;
  562. longint(v):=vs;
  563. end
  564. else
  565. system.val(S,V,code);
  566. end;
  567. {$else not FPC}
  568. begin
  569. system.val(S,V,code);
  570. end;
  571. {$endif not FPC}
  572. function is_number(const s : string) : boolean;
  573. {
  574. is string a correct number ?
  575. }
  576. var
  577. w : integer;
  578. l : longint;
  579. begin
  580. valint(s,l,w);
  581. is_number:=(w=0);
  582. end;
  583. function ispowerof2(value : longint;var power : longint) : boolean;
  584. {
  585. return if value is a power of 2. And if correct return the power
  586. }
  587. var
  588. hl : longint;
  589. i : longint;
  590. begin
  591. hl:=1;
  592. ispowerof2:=true;
  593. for i:=0 to 31 do
  594. begin
  595. if hl=value then
  596. begin
  597. power:=i;
  598. exit;
  599. end;
  600. hl:=hl shl 1;
  601. end;
  602. ispowerof2:=false;
  603. end;
  604. { enable ansistring comparison }
  605. { 0 means equal }
  606. { 1 means p1 > p2 }
  607. { -1 means p1 < p2 }
  608. function compareansistrings(p1,p2 : pchar;length1,length2 : longint) : longint;
  609. var
  610. i,j : longint;
  611. begin
  612. compareansistrings:=0;
  613. j:=min(length1,length2);
  614. i:=0;
  615. while (i<j) do
  616. begin
  617. if p1[i]>p2[i] then
  618. begin
  619. compareansistrings:=1;
  620. exit;
  621. end
  622. else
  623. if p1[i]<p2[i] then
  624. begin
  625. compareansistrings:=-1;
  626. exit;
  627. end;
  628. inc(i);
  629. end;
  630. if length1>length2 then
  631. compareansistrings:=1
  632. else
  633. if length1<length2 then
  634. compareansistrings:=-1;
  635. end;
  636. function concatansistrings(p1,p2 : pchar;length1,length2 : longint) : pchar;
  637. var
  638. p : pchar;
  639. begin
  640. getmem(p,length1+length2+1);
  641. move(p1[0],p[0],length1);
  642. move(p2[0],p[length1],length2+1);
  643. concatansistrings:=p;
  644. end;
  645. {****************************************************************************
  646. Time Handling
  647. ****************************************************************************}
  648. Function L0(l:longint):string;
  649. {
  650. return the string of value l, if l<10 then insert a zero, so
  651. the string is always at least 2 chars '01','02',etc
  652. }
  653. var
  654. s : string;
  655. begin
  656. Str(l,s);
  657. if l<10 then
  658. s:='0'+s;
  659. L0:=s;
  660. end;
  661. function gettimestr:string;
  662. {
  663. get the current time in a string HH:MM:SS
  664. }
  665. var
  666. hour,min,sec,hsec : word;
  667. begin
  668. {$ifdef delphi}
  669. dmisc.gettime(hour,min,sec,hsec);
  670. {$else delphi}
  671. dos.gettime(hour,min,sec,hsec);
  672. {$endif delphi}
  673. gettimestr:=L0(Hour)+':'+L0(min)+':'+L0(sec);
  674. end;
  675. function getdatestr:string;
  676. {
  677. get the current date in a string YY/MM/DD
  678. }
  679. var
  680. Year,Month,Day,Wday : Word;
  681. begin
  682. {$ifdef delphi}
  683. dmisc.getdate(year,month,day,wday);
  684. {$else}
  685. dos.getdate(year,month,day,wday);
  686. {$endif}
  687. getdatestr:=L0(Year)+'/'+L0(Month)+'/'+L0(Day);
  688. end;
  689. function filetimestring( t : longint) : string;
  690. {
  691. convert dos datetime t to a string YY/MM/DD HH:MM:SS
  692. }
  693. var
  694. {$ifndef linux}
  695. DT : DateTime;
  696. {$endif}
  697. Year,Month,Day,Hour,Min,Sec : Word;
  698. begin
  699. if t=-1 then
  700. begin
  701. FileTimeString:='Not Found';
  702. exit;
  703. end;
  704. {$ifndef linux}
  705. unpacktime(t,DT);
  706. Year:=dT.year;month:=dt.month;day:=dt.day;
  707. Hour:=dt.hour;min:=dt.min;sec:=dt.sec;
  708. {$else}
  709. EpochToLocal (t,year,month,day,hour,min,sec);
  710. {$endif}
  711. filetimestring:=L0(Year)+'/'+L0(Month)+'/'+L0(Day)+' '+L0(Hour)+':'+L0(min)+':'+L0(sec);
  712. end;
  713. {****************************************************************************
  714. Default Macro Handling
  715. ****************************************************************************}
  716. procedure DefaultReplacements(var s:string);
  717. begin
  718. { Replace some macro's }
  719. Replace(s,'$FPCVER',version_string);
  720. Replace(s,'$VERSION',version_string);
  721. Replace(s,'$FULLVERSION',full_version_string);
  722. Replace(s,'$FPCDATE',date_string);
  723. Replace(s,'$FPCTARGET',target_cpu_string);
  724. Replace(s,'$FPCCPU',target_cpu_string);
  725. Replace(s,'$TARGET',target_path);
  726. Replace(s,'$FPCOS',target_path);
  727. end;
  728. {****************************************************************************
  729. File Handling
  730. ****************************************************************************}
  731. function GetCurrentDir:string;
  732. var
  733. CurrentDir : string;
  734. begin
  735. GetDir(0,CurrentDir);
  736. GetCurrentDir:=FixPath(CurrentDir,false);
  737. end;
  738. function path_absolute(const s : string) : boolean;
  739. {
  740. is path s an absolute path?
  741. }
  742. begin
  743. path_absolute:=false;
  744. {$ifdef linux}
  745. if (length(s)>0) and (s[1]='/') then
  746. path_absolute:=true;
  747. {$else linux}
  748. {$ifdef amiga}
  749. if ((length(s)>0) and ((s[1]='\') or (s[1]='/'))) or (Pos(':',s) = length(s)) then
  750. path_absolute:=true;
  751. {$else}
  752. if ((length(s)>0) and ((s[1]='\') or (s[1]='/'))) or
  753. ((length(s)>2) and (s[2]=':') and ((s[3]='\') or (s[3]='/'))) then
  754. path_absolute:=true;
  755. {$endif amiga}
  756. {$endif linux}
  757. end;
  758. {$ifndef FPC}
  759. Procedure FindClose(var Info : SearchRec);
  760. Begin
  761. End;
  762. {$endif not FPC}
  763. Function FileExists ( Const F : String) : Boolean;
  764. {$ifndef delphi}
  765. Var
  766. Info : SearchRec;
  767. {$endif}
  768. begin
  769. {$ifdef delphi}
  770. FileExists:=sysutils.FileExists(f);
  771. {$else}
  772. findfirst(F,readonly+archive+hidden,info);
  773. FileExists:=(doserror=0);
  774. findclose(Info);
  775. {$endif delphi}
  776. end;
  777. Function PathExists ( F : String) : Boolean;
  778. Var
  779. Info : SearchRec;
  780. begin
  781. if F[Length(f)] in ['/','\'] then
  782. Delete(f,length(f),1);
  783. findfirst(F,readonly+archive+hidden+directory,info);
  784. PathExists:=(doserror=0) and ((info.attr and directory)=directory);
  785. findclose(Info);
  786. end;
  787. Function RemoveFile(const f:string):boolean;
  788. var
  789. g : file;
  790. begin
  791. assign(g,f);
  792. {$I-}
  793. erase(g);
  794. {$I+}
  795. RemoveFile:=(ioresult=0);
  796. end;
  797. Function RemoveDir(d:string):boolean;
  798. begin
  799. if d[length(d)]=DirSep then
  800. Delete(d,length(d),1);
  801. {$I-}
  802. rmdir(d);
  803. {$I+}
  804. RemoveDir:=(ioresult=0);
  805. end;
  806. Function SplitPath(const s:string):string;
  807. var
  808. i : longint;
  809. begin
  810. i:=Length(s);
  811. while (i>0) and not(s[i] in ['/','\']) do
  812. dec(i);
  813. SplitPath:=Copy(s,1,i);
  814. end;
  815. Function SplitFileName(const s:string):string;
  816. var
  817. p : dirstr;
  818. n : namestr;
  819. e : extstr;
  820. begin
  821. FSplit(s,p,n,e);
  822. SplitFileName:=n+e;
  823. end;
  824. Function SplitName(const s:string):string;
  825. var
  826. i,j : longint;
  827. begin
  828. i:=Length(s);
  829. j:=Length(s);
  830. while (i>0) and not(s[i] in ['/','\']) do
  831. dec(i);
  832. while (j>0) and (s[j]<>'.') do
  833. dec(j);
  834. if j<=i then
  835. j:=255;
  836. SplitName:=Copy(s,i+1,j-(i+1));
  837. end;
  838. Function SplitExtension(Const HStr:String):String;
  839. var
  840. j : longint;
  841. begin
  842. j:=length(Hstr);
  843. while (j>0) and (Hstr[j]<>'.') do
  844. begin
  845. if hstr[j]=DirSep then
  846. j:=0
  847. else
  848. dec(j);
  849. end;
  850. if j=0 then
  851. j:=254;
  852. SplitExtension:=Copy(Hstr,j,255);
  853. end;
  854. Function AddExtension(Const HStr,ext:String):String;
  855. begin
  856. if (Ext<>'') and (SplitExtension(HStr)='') then
  857. AddExtension:=Hstr+Ext
  858. else
  859. AddExtension:=Hstr;
  860. end;
  861. Function ForceExtension(Const HStr,ext:String):String;
  862. var
  863. j : longint;
  864. begin
  865. j:=length(Hstr);
  866. while (j>0) and (Hstr[j]<>'.') do
  867. dec(j);
  868. if j=0 then
  869. j:=255;
  870. ForceExtension:=Copy(Hstr,1,j-1)+Ext;
  871. end;
  872. Function FixPath(s:string;allowdot:boolean):string;
  873. var
  874. i : longint;
  875. begin
  876. { Fix separator }
  877. for i:=1 to length(s) do
  878. if s[i] in ['/','\'] then
  879. s[i]:=DirSep;
  880. { Fix ending / }
  881. if (length(s)>0) and (s[length(s)]<>DirSep) and
  882. (s[length(s)]<>':') then
  883. s:=s+DirSep;
  884. { Remove ./ }
  885. if (not allowdot) and (s='.'+DirSep) then
  886. s:='';
  887. { return }
  888. {$ifdef linux}
  889. FixPath:=s;
  890. {$else}
  891. FixPath:=Lower(s);
  892. {$endif}
  893. end;
  894. function FixFileName(const s:string):string;
  895. var
  896. i : longint;
  897. {$ifdef Linux}
  898. NoPath : boolean;
  899. {$endif Linux}
  900. begin
  901. {$ifdef Linux}
  902. NoPath:=true;
  903. {$endif Linux}
  904. for i:=length(s) downto 1 do
  905. begin
  906. case s[i] of
  907. {$ifdef Linux}
  908. '/','\' : begin
  909. FixFileName[i]:='/';
  910. NoPath:=false; {Skip lowercasing path: 'X11'<>'x11' }
  911. end;
  912. 'A'..'Z' : if NoPath then
  913. FixFileName[i]:=char(byte(s[i])+32)
  914. else
  915. FixFileName[i]:=s[i];
  916. {$else}
  917. '/' : FixFileName[i]:='\';
  918. 'A'..'Z' : FixFileName[i]:=char(byte(s[i])+32);
  919. {$endif}
  920. else
  921. FixFileName[i]:=s[i];
  922. end;
  923. end;
  924. {$ifndef TP}
  925. {$ifopt H+}
  926. SetLength(FixFileName,length(s));
  927. {$else}
  928. FixFileName[0]:=s[0];
  929. {$endif}
  930. {$else}
  931. FixFileName[0]:=s[0];
  932. {$endif}
  933. end;
  934. procedure SplitBinCmd(const s:string;var bstr,cstr:string);
  935. var
  936. i : longint;
  937. begin
  938. i:=pos(' ',s);
  939. if i>0 then
  940. begin
  941. bstr:=Copy(s,1,i-1);
  942. cstr:=Copy(s,i+1,length(s)-i);
  943. end
  944. else
  945. begin
  946. bstr:='';
  947. cstr:='';
  948. end;
  949. end;
  950. procedure TSearchPathList.AddPath(s:string;addfirst:boolean);
  951. var
  952. j : longint;
  953. hs,hsd,
  954. CurrentDir,
  955. CurrPath : string;
  956. dir : searchrec;
  957. {$IFDEF NEWST}
  958. hp : PStringItem;
  959. {$ELSE}
  960. hp : PStringQueueItem;
  961. {$ENDIF}
  962. procedure addcurrpath;
  963. begin
  964. if addfirst then
  965. begin
  966. Delete(currPath);
  967. Insert(currPath);
  968. end
  969. else
  970. begin
  971. { Check if already in path, then we don't add it }
  972. hp:=Find(currPath);
  973. if not assigned(hp) then
  974. Concat(currPath);
  975. end;
  976. end;
  977. begin
  978. if s='' then
  979. exit;
  980. { Support default macro's }
  981. DefaultReplacements(s);
  982. { get current dir }
  983. CurrentDir:=GetCurrentDir;
  984. repeat
  985. { get currpath }
  986. if addfirst then
  987. begin
  988. j:=length(s);
  989. while (j>0) and (s[j]<>';') do
  990. dec(j);
  991. CurrPath:=FixPath(Copy(s,j+1,length(s)-j),false);
  992. if j=0 then
  993. s:=''
  994. else
  995. System.Delete(s,j,length(s)-j+1);
  996. end
  997. else
  998. begin
  999. j:=Pos(';',s);
  1000. if j=0 then
  1001. j:=255;
  1002. CurrPath:=FixPath(Copy(s,1,j-1),false);
  1003. System.Delete(s,1,j);
  1004. end;
  1005. { fix pathname }
  1006. if CurrPath='' then
  1007. CurrPath:='.'+DirSep
  1008. else
  1009. begin
  1010. CurrPath:=FixPath(FExpand(CurrPath),false);
  1011. if (CurrentDir<>'') and (Copy(CurrPath,1,length(CurrentDir))=CurrentDir) then
  1012. CurrPath:='.'+DirSep+Copy(CurrPath,length(CurrentDir)+1,255);
  1013. end;
  1014. { wildcard adding ? }
  1015. if pos('*',currpath)>0 then
  1016. begin
  1017. if currpath[length(currpath)]=dirsep then
  1018. hs:=Copy(currpath,1,length(CurrPath)-1)
  1019. else
  1020. hs:=currpath;
  1021. hsd:=SplitPath(hs);
  1022. findfirst(hs,directory,dir);
  1023. while doserror=0 do
  1024. begin
  1025. if (dir.name<>'.') and
  1026. (dir.name<>'..') and
  1027. ((dir.attr and directory)<>0) then
  1028. begin
  1029. currpath:=hsd+dir.name+dirsep;
  1030. hp:=Find(currPath);
  1031. if not assigned(hp) then
  1032. AddCurrPath;
  1033. end;
  1034. findnext(dir);
  1035. end;
  1036. FindClose(dir);
  1037. end
  1038. else
  1039. begin
  1040. if PathExists(currpath) then
  1041. addcurrpath;
  1042. end;
  1043. until (s='');
  1044. end;
  1045. procedure TSearchPathList.AddList(list:TSearchPathList;addfirst:boolean);
  1046. var
  1047. s : string;
  1048. hl : TSearchPathList;
  1049. {$IFDEF NEWST}
  1050. hp,hp2 : PStringItem;
  1051. {$ELSE}
  1052. hp,hp2 : PStringQueueItem;
  1053. {$ENDIF}
  1054. begin
  1055. if list.empty then
  1056. exit;
  1057. { create temp and reverse the list }
  1058. if addfirst then
  1059. begin
  1060. hl.Init;
  1061. hp:=list.first;
  1062. while assigned(hp) do
  1063. begin
  1064. hl.insert(hp^.data^);
  1065. hp:=hp^.next;
  1066. end;
  1067. while not hl.empty do
  1068. begin
  1069. s:=hl.Get;
  1070. Delete(s);
  1071. Insert(s);
  1072. end;
  1073. hl.done;
  1074. end
  1075. else
  1076. begin
  1077. hp:=list.first;
  1078. while assigned(hp) do
  1079. begin
  1080. hp2:=Find(hp^.data^);
  1081. { Check if already in path, then we don't add it }
  1082. if not assigned(hp2) then
  1083. Concat(hp^.data^);
  1084. hp:=hp^.next;
  1085. end;
  1086. end;
  1087. end;
  1088. function TSearchPathList.FindFile(const f : string;var b : boolean) : string;
  1089. Var
  1090. {$IFDEF NEWST}
  1091. p : PStringItem;
  1092. {$ELSE}
  1093. p : PStringQueueItem;
  1094. {$ENDIF}
  1095. begin
  1096. FindFile:='';
  1097. b:=false;
  1098. p:=first;
  1099. while assigned(p) do
  1100. begin
  1101. If FileExists(p^.data^+f) then
  1102. begin
  1103. FindFile:=p^.data^;
  1104. b:=true;
  1105. exit;
  1106. end;
  1107. p:=p^.next;
  1108. end;
  1109. end;
  1110. Function GetFileTime ( Var F : File) : Longint;
  1111. Var
  1112. {$ifdef linux}
  1113. Info : Stat;
  1114. {$endif}
  1115. L : longint;
  1116. begin
  1117. {$ifdef linux}
  1118. FStat (F,Info);
  1119. L:=Info.Mtime;
  1120. {$else}
  1121. GetFTime(f,l);
  1122. {$endif}
  1123. GetFileTime:=L;
  1124. end;
  1125. Function GetNamedFileTime (Const F : String) : Longint;
  1126. var
  1127. L : Longint;
  1128. {$ifndef linux}
  1129. info : SearchRec;
  1130. {$else}
  1131. info : stat;
  1132. {$endif}
  1133. begin
  1134. l:=-1;
  1135. {$ifdef linux}
  1136. if FStat (F,Info) then
  1137. L:=info.mtime;
  1138. {$else}
  1139. {$ifdef delphi}
  1140. dmisc.FindFirst (F,archive+readonly+hidden,info);
  1141. {$else delphi}
  1142. FindFirst (F,archive+readonly+hidden,info);
  1143. {$endif delphi}
  1144. if DosError=0 then
  1145. l:=info.time;
  1146. {$ifdef Linux}
  1147. FindClose(info);
  1148. {$endif}
  1149. {$ifdef Win32}
  1150. FindClose(info);
  1151. {$endif}
  1152. {$endif}
  1153. GetNamedFileTime:=l;
  1154. end;
  1155. {Touch Assembler and object time to ppu time is there is a ppufilename}
  1156. procedure SynchronizeFileTime(const fn1,fn2:string);
  1157. var
  1158. f : file;
  1159. l : longint;
  1160. begin
  1161. Assign(f,fn1);
  1162. {$I-}
  1163. reset(f,1);
  1164. {$I+}
  1165. if ioresult=0 then
  1166. begin
  1167. getftime(f,l);
  1168. { just to be sure in case there are rounding errors }
  1169. setftime(f,l);
  1170. close(f);
  1171. assign(f,fn2);
  1172. {$I-}
  1173. reset(f,1);
  1174. {$I+}
  1175. if ioresult=0 then
  1176. begin
  1177. setftime(f,l);
  1178. close(f);
  1179. end;
  1180. end;
  1181. end;
  1182. function FindFile(const f : string;path : string;var b : boolean) : string;
  1183. Var
  1184. singlepathstring : string;
  1185. i : longint;
  1186. begin
  1187. {$ifdef linux}
  1188. for i:=1 to length(path) do
  1189. if path[i]=':' then
  1190. path[i]:=';';
  1191. {$endif}
  1192. b:=false;
  1193. FindFile:='';
  1194. repeat
  1195. i:=pos(';',path);
  1196. if i=0 then
  1197. i:=256;
  1198. singlepathstring:=FixPath(copy(path,1,i-1),false);
  1199. delete(path,1,i);
  1200. If FileExists (singlepathstring+f) then
  1201. begin
  1202. FindFile:=singlepathstring;
  1203. b:=true;
  1204. exit;
  1205. end;
  1206. until path='';
  1207. end;
  1208. function FindExe(bin:string;var found:boolean):string;
  1209. begin
  1210. bin:=FixFileName(bin)+source_os.exeext;
  1211. {$ifdef delphi}
  1212. FindExe:=FindFile(bin,'.;'+exepath+';'+dmisc.getenv('PATH'),found)+bin;
  1213. {$else delphi}
  1214. FindExe:=FindFile(bin,'.;'+exepath+';'+dos.getenv('PATH'),found)+bin;
  1215. {$endif delphi}
  1216. end;
  1217. function GetShortName(const n:string):string;
  1218. {$ifdef win32}
  1219. var
  1220. hs,hs2 : string;
  1221. i : longint;
  1222. {$endif}
  1223. {$ifdef go32v2}
  1224. var
  1225. hs : string;
  1226. {$endif}
  1227. begin
  1228. GetShortName:=n;
  1229. {$ifdef win32}
  1230. hs:=n+#0;
  1231. i:=Windows.GetShortPathName(@hs[1],@hs2[1],high(hs2));
  1232. if (i>0) and (i<=high(hs2)) then
  1233. begin
  1234. hs2[0]:=chr(strlen(@hs2[1]));
  1235. GetShortName:=hs2;
  1236. end;
  1237. {$endif}
  1238. {$ifdef go32v2}
  1239. hs:=n;
  1240. if Dos.GetShortName(hs) then
  1241. GetShortName:=hs;
  1242. {$endif}
  1243. end;
  1244. {****************************************************************************
  1245. OS Dependent things
  1246. ****************************************************************************}
  1247. function GetEnvPChar(const envname:string):pchar;
  1248. {$ifdef win32}
  1249. var
  1250. s : string;
  1251. i,len : longint;
  1252. hp,p,p2 : pchar;
  1253. {$endif}
  1254. begin
  1255. {$ifdef linux}
  1256. GetEnvPchar:=Linux.Getenv(envname);
  1257. {$define GETENVOK}
  1258. {$endif}
  1259. {$ifdef win32}
  1260. GetEnvPchar:=nil;
  1261. p:=GetEnvironmentStrings;
  1262. hp:=p;
  1263. while hp^<>#0 do
  1264. begin
  1265. s:=strpas(hp);
  1266. i:=pos('=',s);
  1267. len:=strlen(hp);
  1268. if upper(copy(s,1,i-1))=upper(envname) then
  1269. begin
  1270. GetMem(p2,len-length(envname));
  1271. Move(hp[i],p2^,len-length(envname));
  1272. GetEnvPchar:=p2;
  1273. break;
  1274. end;
  1275. { next string entry}
  1276. hp:=hp+len+1;
  1277. end;
  1278. FreeEnvironmentStrings(p);
  1279. {$define GETENVOK}
  1280. {$endif}
  1281. {$ifdef GETENVOK}
  1282. {$undef GETENVOK}
  1283. {$else}
  1284. GetEnvPchar:=StrPNew(Dos.Getenv(envname));
  1285. {$endif}
  1286. end;
  1287. procedure FreeEnvPChar(p:pchar);
  1288. begin
  1289. {$ifndef linux}
  1290. StrDispose(p);
  1291. {$endif}
  1292. end;
  1293. Procedure Shell(const command:string);
  1294. { This is already defined in the linux.ppu for linux, need for the *
  1295. expansion under linux }
  1296. {$ifdef linux}
  1297. begin
  1298. Linux.Shell(command);
  1299. end;
  1300. {$else}
  1301. var
  1302. comspec : string;
  1303. begin
  1304. comspec:=getenv('COMSPEC');
  1305. Exec(comspec,' /C '+command);
  1306. end;
  1307. {$endif}
  1308. {****************************************************************************
  1309. Init
  1310. ****************************************************************************}
  1311. procedure get_exepath;
  1312. var
  1313. hs1 : namestr;
  1314. hs2 : extstr;
  1315. begin
  1316. {$ifdef delphi}
  1317. exepath:=dmisc.getenv('PPC_EXEC_PATH');
  1318. {$else delphi}
  1319. exepath:=dos.getenv('PPC_EXEC_PATH');
  1320. {$endif delphi}
  1321. if exepath='' then
  1322. fsplit(FixFileName(paramstr(0)),exepath,hs1,hs2);
  1323. {$ifndef VER0_99_15}
  1324. {$ifdef linux}
  1325. if exepath='' then
  1326. fsearch(hs1,dos.getenv('PATH'));
  1327. {$endif}
  1328. {$endif}
  1329. exepath:=FixPath(exepath,false);
  1330. end;
  1331. procedure DoneGlobals;
  1332. begin
  1333. initdefines.done;
  1334. if assigned(DLLImageBase) then
  1335. StringDispose(DLLImageBase);
  1336. RelocSection:=true;
  1337. RelocSectionSetExplicitly:=false;
  1338. DLLsource:=false;
  1339. UseDeffileForExport:=true;
  1340. librarysearchpath.Done;
  1341. unitsearchpath.Done;
  1342. objectsearchpath.Done;
  1343. includesearchpath.Done;
  1344. end;
  1345. procedure InitGlobals;
  1346. begin
  1347. { set global switches }
  1348. do_build:=false;
  1349. do_make:=true;
  1350. {$ifdef tp}
  1351. use_big:=false;
  1352. {$endif tp}
  1353. compile_level:=0;
  1354. { Output }
  1355. OutputFile:='';
  1356. OutputExeDir:='';
  1357. OutputUnitDir:='';
  1358. { Utils directory }
  1359. utilsdirectory:='';
  1360. { Search Paths }
  1361. librarysearchpath.Init;
  1362. unitsearchpath.Init;
  1363. includesearchpath.Init;
  1364. objectsearchpath.Init;
  1365. { Def file }
  1366. usewindowapi:=false;
  1367. description:='Compiled by FPC '+version_string+' - '+target_cpu_string;
  1368. dllversion:='';
  1369. { Init values }
  1370. initmodeswitches:=fpcmodeswitches;
  1371. initlocalswitches:=[cs_check_io];
  1372. initmoduleswitches:=[cs_extsyntax,cs_browser];
  1373. initglobalswitches:=[cs_check_unit_name,cs_link_static];
  1374. {$ifdef i386}
  1375. initoptprocessor:=Class386;
  1376. initspecificoptprocessor:=Class386;
  1377. initpackenum:=4;
  1378. {$IFDEF testvarsets}
  1379. initsetalloc:=0;
  1380. {$ENDIF}
  1381. initpackrecords:=packrecord_2;
  1382. initoutputformat:=target_asm.id;
  1383. initasmmode:=asmmode_i386_att;
  1384. {$else not i386}
  1385. {$ifdef m68k}
  1386. initoptprocessor:=MC68000;
  1387. include(initmoduleswitches,cs_fp_emulation);
  1388. initpackenum:=4;
  1389. {$IFDEF testvarsets}
  1390. initsetalloc:=0;
  1391. {$ENDIF}
  1392. initpackrecords:=packrecord_2;
  1393. initoutputformat:=as_m68k_as;
  1394. initasmmode:=asmmode_m68k_mot;
  1395. {$endif m68k}
  1396. {$endif i386}
  1397. initdefines.init;
  1398. { memory sizes, will be overriden by parameter or default for target
  1399. in options or init_parser }
  1400. stacksize:=0;
  1401. heapsize:=0;
  1402. maxheapsize:=0;
  1403. { compile state }
  1404. in_args:=false;
  1405. { must_be_valid:=true; obsolete PM }
  1406. not_unit_proc:=true;
  1407. apptype:=at_cui;
  1408. end;
  1409. begin
  1410. get_exepath;
  1411. {$ifdef EXTDEBUG}
  1412. {$ifdef FPC}
  1413. EntryMemUsed:=system.HeapSize-MemAvail;
  1414. {$endif FPC}
  1415. {$endif}
  1416. end.
  1417. {
  1418. $Log$
  1419. Revision 1.66 2000-06-18 18:05:54 peter
  1420. * no binary value reading with % if not fpc mode
  1421. * extended illegal char message with the char itself (Delphi like)
  1422. Revision 1.65 2000/06/15 18:10:11 peter
  1423. * first look for ppu in cwd and outputpath and after that for source
  1424. in cwd
  1425. * fixpath() for not linux makes path now lowercase so comparing paths
  1426. with different cases (sometimes a drive letter could be
  1427. uppercased) gives the expected results
  1428. * sources_checked flag if there was already a full search for sources
  1429. which aren't found, so another scan isn't done when checking for the
  1430. sources only when recompile is needed
  1431. Revision 1.64 2000/06/11 07:00:21 peter
  1432. * fixed pchar->string conversion for delphi mode
  1433. Revision 1.63 2000/05/12 08:58:51 pierre
  1434. * adapted to Delphi 3
  1435. Revision 1.62 2000/05/12 05:55:04 pierre
  1436. * * get it to compile with Delphi by Kovacs Attila Zoltan
  1437. Revision 1.61 2000/05/11 09:37:25 pierre
  1438. * do not use upcase for strings, reported by Kovacs Attila Zoltan
  1439. Revision 1.60 2000/05/04 20:46:17 peter
  1440. * ansistrings are now default on for delphi mode, as most ppl expect
  1441. this
  1442. Revision 1.59 2000/05/03 14:36:57 pierre
  1443. * fix for tests/test/testrang.pp bug
  1444. Revision 1.58 2000/04/14 12:27:57 pierre
  1445. * setfiletime to both files in synchronize
  1446. Revision 1.57 2000/03/23 15:35:47 peter
  1447. * $VERSION is now version_string
  1448. + $FULLVERSION is now full_version_string
  1449. Revision 1.56 2000/03/20 16:04:05 pierre
  1450. * probably a fix for bug 615
  1451. Revision 1.55 2000/03/08 15:39:45 daniel
  1452. + Added align_from_size function as suggested by Peter.
  1453. Revision 1.54 2000/02/28 17:23:57 daniel
  1454. * Current work of symtable integration committed. The symtable can be
  1455. activated by defining 'newst', but doesn't compile yet. Changes in type
  1456. checking and oop are completed. What is left is to write a new
  1457. symtablestack and adapt the parser to use it.
  1458. Revision 1.53 2000/02/14 20:58:44 marco
  1459. * Basic structures for new sethandling implemented.
  1460. Revision 1.52 2000/02/10 11:45:48 peter
  1461. * addpath fixed with list of paths when inserting at the beginning
  1462. * if exepath=currentdir then it's not inserted in path list
  1463. * searchpaths in ppc386.cfg are now added at the beginning of the
  1464. list instead of at the end. (commandline is not changed)
  1465. * check paths before inserting in list
  1466. Revision 1.51 2000/02/09 13:22:53 peter
  1467. * log truncated
  1468. Revision 1.50 2000/01/26 14:31:03 marco
  1469. * $VERSION is now also substituted in -F paths (that have subst active)
  1470. Revision 1.49 2000/01/23 21:29:14 florian
  1471. * CMOV support in optimizer (in define USECMOV)
  1472. + start of support of exceptions in constructors
  1473. Revision 1.48 2000/01/23 16:36:37 peter
  1474. * better auto RTL dir detection
  1475. Revision 1.47 2000/01/20 00:23:03 pierre
  1476. * fix for GetShortName, now checks results from Win32
  1477. Revision 1.46 2000/01/07 01:14:27 peter
  1478. * updated copyright to 2000
  1479. Revision 1.45 2000/01/07 00:08:09 peter
  1480. * tp7 fix
  1481. Revision 1.44 2000/01/06 15:48:59 peter
  1482. * wildcard support for directory adding, this allows the use of units/*
  1483. in ppc386.cfg
  1484. Revision 1.43 2000/01/04 15:15:50 florian
  1485. + added compiler switch $maxfpuregisters
  1486. + fixed a small problem in secondvecn
  1487. Revision 1.42 1999/12/22 01:01:48 peter
  1488. - removed freelabel()
  1489. * added undefined label detection in internal assembler, this prevents
  1490. a lot of ld crashes and wrong .o files
  1491. * .o files aren't written anymore if errors have occured
  1492. * inlining of assembler labels is now correct
  1493. Revision 1.41 1999/12/20 23:23:28 pierre
  1494. + $description $version
  1495. Revision 1.40 1999/12/20 21:42:34 pierre
  1496. + dllversion global variable
  1497. * FPC_USE_CPREFIX code removed, not necessary anymore
  1498. as we use .edata direct writing by default now.
  1499. Revision 1.39 1999/12/08 10:40:00 pierre
  1500. + allow use of unit var in exports of DLL for win32
  1501. by using direct export writing by default instead of use of DEFFILE
  1502. that does not allow assembler labels that do not
  1503. start with an underscore.
  1504. Use -WD to force use of Deffile for Win32 DLL
  1505. Revision 1.38 1999/12/06 18:21:03 peter
  1506. * support !ENVVAR for long commandlines
  1507. * win32/go32v2 write short pathnames to link.res so c:\Program Files\ is
  1508. finally supported as installdir.
  1509. Revision 1.37 1999/12/02 17:34:34 peter
  1510. * preprocessor support. But it fails on the caret in type blocks
  1511. Revision 1.36 1999/11/18 15:34:45 pierre
  1512. * Notes/Hints for local syms changed to
  1513. Set_varstate function
  1514. Revision 1.35 1999/11/17 17:04:59 pierre
  1515. * Notes/hints changes
  1516. Revision 1.34 1999/11/15 17:42:41 pierre
  1517. * -g disables reloc section for win32
  1518. Revision 1.33 1999/11/12 11:03:50 peter
  1519. * searchpaths changed to stringqueue object
  1520. Revision 1.32 1999/11/09 23:34:46 pierre
  1521. + resolving_forward boolean used for references
  1522. Revision 1.31 1999/11/09 13:00:38 peter
  1523. * define FPC_DELPHI,FPC_OBJFPC,FPC_TP,FPC_GPC
  1524. * initial support for ansistring default with modes
  1525. }