globals.pas 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
  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. unit globals;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. {$ifdef win32}
  23. windows,
  24. {$endif}
  25. {$ifdef unix}
  26. {$ifdef ver1_0}
  27. linux,
  28. {$else}
  29. unix,
  30. {$endif}
  31. {$endif}
  32. {$ifdef os2}
  33. doscalls,
  34. {$endif}
  35. {$ifdef Delphi}
  36. SysUtils,
  37. dmisc,
  38. {$else}
  39. strings,
  40. dos,
  41. {$endif}
  42. cutils,cclasses,
  43. globtype,version,systems;
  44. const
  45. {$ifdef unix}
  46. DirSep = '/';
  47. {$else}
  48. {$ifdef amiga}
  49. DirSep = '/';
  50. {$else}
  51. DirSep = '\';
  52. {$endif}
  53. {$endif}
  54. {$ifdef Splitheap}
  55. testsplit : boolean = false;
  56. {$endif Splitheap}
  57. delphimodeswitches : tmodeswitches=
  58. [m_delphi,m_tp,m_all,m_class,m_objpas,m_result,m_string_pchar,
  59. m_pointer_2_procedure,m_autoderef,m_tp_procvar,m_initfinal,m_default_ansistring,
  60. m_out,m_default_para,m_hintdirective];
  61. fpcmodeswitches : tmodeswitches=
  62. [m_fpc,m_all,m_string_pchar,m_nested_comment,m_repeat_forward,
  63. m_cvar_support,m_initfinal,m_add_pointer];
  64. objfpcmodeswitches : tmodeswitches=
  65. [m_objfpc,m_fpc,m_all,m_class,m_objpas,m_result,m_string_pchar,m_nested_comment,
  66. m_repeat_forward,m_cvar_support,m_initfinal,m_add_pointer,m_out,m_default_para];
  67. tpmodeswitches : tmodeswitches=
  68. [m_tp7,m_tp,m_all,m_tp_procvar];
  69. gpcmodeswitches : tmodeswitches=
  70. [m_gpc,m_all];
  71. type
  72. pfileposinfo = ^tfileposinfo;
  73. tfileposinfo = record
  74. line : longint;
  75. column : word;
  76. fileindex : word;
  77. end;
  78. TSearchPathList = class(TStringList)
  79. procedure AddPath(s:string;addfirst:boolean);
  80. procedure AddList(list:TSearchPathList;addfirst:boolean);
  81. function FindFile(const f : string;var foundfile:string):boolean;
  82. end;
  83. var
  84. { specified inputfile }
  85. inputdir : dirstr;
  86. inputfile : namestr;
  87. inputextension : extstr;
  88. { specified outputfile with -o parameter }
  89. outputfile : namestr;
  90. { specified with -FE or -FU }
  91. outputexedir : dirstr;
  92. outputunitdir : dirstr;
  93. { things specified with parameters }
  94. paralinkoptions,
  95. paradynamiclinker : string;
  96. parapreprocess : boolean;
  97. { directory where the utils can be found (options -FD) }
  98. utilsdirectory : dirstr;
  99. { some flags for global compiler switches }
  100. do_build,
  101. do_release,
  102. do_make : boolean;
  103. not_unit_proc : boolean;
  104. { path for searching units, different paths can be seperated by ; }
  105. exepath : dirstr; { Path to ppc }
  106. librarysearchpath,
  107. unitsearchpath,
  108. objectsearchpath,
  109. includesearchpath : TSearchPathList;
  110. { deffile }
  111. usewindowapi : boolean;
  112. description : string;
  113. dllversion : string;
  114. dllmajor,dllminor,dllrevision : word; { revision only for netware }
  115. akttokenpos, { position of the last token }
  116. aktfilepos : tfileposinfo; { current position }
  117. { ad 18.05.2001: Screen and Threadname for Netware }
  118. nwscreenname : string;
  119. nwthreadname : string;
  120. nwcopyright : string;
  121. { type of currently parsed block }
  122. { isn't full implemented (FK) }
  123. block_type : tblock_type;
  124. in_args : boolean; { arguments must be checked especially }
  125. parsing_para_level : integer; { parameter level, used to convert
  126. proc calls to proc loads in firstcalln }
  127. compile_level : word;
  128. make_ref : boolean;
  129. resolving_forward : boolean; { used to add forward reference as second ref }
  130. use_esp_stackframe : boolean; { to test for call with ESP as stack frame }
  131. inlining_procedure : boolean; { are we inlining a procedure }
  132. statement_level : integer;
  133. aktexceptblock : integer; { each except block gets a number check gotos }
  134. { commandline values }
  135. initdefines : tstringlist;
  136. initglobalswitches : tglobalswitches;
  137. initmoduleswitches : tmoduleswitches;
  138. initlocalswitches : tlocalswitches;
  139. initmodeswitches : tmodeswitches;
  140. {$IFDEF testvarsets}
  141. Initsetalloc, {0=fixed, 1 =var}
  142. {$ENDIF}
  143. initpackenum : longint;
  144. initalignment : talignmentinfo;
  145. initoptprocessor,
  146. initspecificoptprocessor : tprocessors;
  147. initasmmode : tasmmode;
  148. initinterfacetype : tinterfacetypes;
  149. initoutputformat : tasm;
  150. { current state values }
  151. aktglobalswitches : tglobalswitches;
  152. aktmoduleswitches : tmoduleswitches;
  153. aktlocalswitches : tlocalswitches;
  154. nextaktlocalswitches : tlocalswitches;
  155. localswitcheschanged : boolean;
  156. aktmodeswitches : tmodeswitches;
  157. {$IFDEF testvarsets}
  158. aktsetalloc,
  159. {$ENDIF}
  160. aktpackenum : longint;
  161. aktmaxfpuregisters : longint;
  162. aktalignment : talignmentinfo;
  163. aktoptprocessor,
  164. aktspecificoptprocessor : tprocessors;
  165. aktasmmode : tasmmode;
  166. aktinterfacetype : tinterfacetypes;
  167. aktoutputformat : tasm;
  168. { Memory sizes }
  169. heapsize,
  170. maxheapsize,
  171. stacksize : longint;
  172. {$Ifdef EXTDEBUG}
  173. total_of_firstpass,
  174. firstpass_several : longint;
  175. {$ifdef FPC}
  176. EntryMemUsed : longint;
  177. {$endif FPC}
  178. { parameter switches }
  179. debugstop : boolean;
  180. {$EndIf EXTDEBUG}
  181. { windows / OS/2 application type }
  182. apptype : tapptype;
  183. const
  184. RelocSection : boolean = true;
  185. RelocSectionSetExplicitly : boolean = false;
  186. LinkTypeSetExplicitly : boolean = false;
  187. IsExe : boolean = false;
  188. DLLsource : boolean = false;
  189. DLLImageBase : pstring = nil;
  190. UseDeffileForExport : boolean = true;
  191. ForceDeffileForExport : boolean = false;
  192. { used to set all registers used for each global function
  193. this should dramatically decrease the number of
  194. recompilations needed PM }
  195. simplify_ppu : boolean = true;
  196. { should we allow non static members ? }
  197. allow_only_static : boolean = false;
  198. Inside_asm_statement : boolean = false;
  199. global_unit_count : word = 0;
  200. { for error info in pp.pas }
  201. parser_current_file : string = '';
  202. procedure abstract;
  203. function bstoslash(const s : string) : string;
  204. function getdatestr:string;
  205. function gettimestr:string;
  206. function filetimestring( t : longint) : string;
  207. procedure DefaultReplacements(var s:string);
  208. function GetCurrentDir:string;
  209. function path_absolute(const s : string) : boolean;
  210. Function PathExists ( F : String) : Boolean;
  211. Function FileExists ( Const F : String) : Boolean;
  212. Function RemoveFile(const f:string):boolean;
  213. Function RemoveDir(d:string):boolean;
  214. Function GetFileTime ( Var F : File) : Longint;
  215. Function GetNamedFileTime ( Const F : String) : Longint;
  216. Function SplitPath(const s:string):string;
  217. Function SplitFileName(const s:string):string;
  218. Function SplitName(const s:string):string;
  219. Function SplitExtension(Const HStr:String):String;
  220. Function AddExtension(Const HStr,ext:String):String;
  221. Function ForceExtension(Const HStr,ext:String):String;
  222. Function FixPath(s:string;allowdot:boolean):string;
  223. function FixFileName(const s:string):string;
  224. procedure SplitBinCmd(const s:string;var bstr,cstr:string);
  225. function FindFile(const f : string;path : string;var foundfile:string):boolean;
  226. function FindExe(const bin:string;var foundfile:string):boolean;
  227. function GetShortName(const n:string):string;
  228. Procedure Shell(const command:string);
  229. function GetEnvPChar(const envname:string):pchar;
  230. procedure FreeEnvPChar(p:pchar);
  231. Function SetCompileMode(const s:string; changeInit: boolean):boolean;
  232. procedure InitGlobals;
  233. procedure DoneGlobals;
  234. function string2guid(const s: string; var GUID: TGUID): boolean;
  235. function guid2string(const GUID: TGUID): string;
  236. function UpdateAlignmentStr(s:string;var a:talignmentinfo):boolean;
  237. implementation
  238. uses
  239. comphook;
  240. procedure abstract;
  241. begin
  242. do_internalerror(255);
  243. end;
  244. function bstoslash(const s : string) : string;
  245. {
  246. return string s with all \ changed into /
  247. }
  248. var
  249. i : longint;
  250. begin
  251. for i:=1to length(s) do
  252. if s[i]='\' then
  253. bstoslash[i]:='/'
  254. else
  255. bstoslash[i]:=s[i];
  256. bstoslash[0]:=s[0];
  257. end;
  258. {****************************************************************************
  259. Time Handling
  260. ****************************************************************************}
  261. Function L0(l:longint):string;
  262. {
  263. return the string of value l, if l<10 then insert a zero, so
  264. the string is always at least 2 chars '01','02',etc
  265. }
  266. var
  267. s : string;
  268. begin
  269. Str(l,s);
  270. if l<10 then
  271. s:='0'+s;
  272. L0:=s;
  273. end;
  274. function gettimestr:string;
  275. {
  276. get the current time in a string HH:MM:SS
  277. }
  278. var
  279. hour,min,sec,hsec : word;
  280. begin
  281. {$ifdef delphi}
  282. dmisc.gettime(hour,min,sec,hsec);
  283. {$else delphi}
  284. dos.gettime(hour,min,sec,hsec);
  285. {$endif delphi}
  286. gettimestr:=L0(Hour)+':'+L0(min)+':'+L0(sec);
  287. end;
  288. function getdatestr:string;
  289. {
  290. get the current date in a string YY/MM/DD
  291. }
  292. var
  293. Year,Month,Day,Wday : Word;
  294. begin
  295. {$ifdef delphi}
  296. dmisc.getdate(year,month,day,wday);
  297. {$else}
  298. dos.getdate(year,month,day,wday);
  299. {$endif}
  300. getdatestr:=L0(Year)+'/'+L0(Month)+'/'+L0(Day);
  301. end;
  302. function filetimestring( t : longint) : string;
  303. {
  304. convert dos datetime t to a string YY/MM/DD HH:MM:SS
  305. }
  306. var
  307. DT : DateTime;
  308. begin
  309. if t=-1 then
  310. begin
  311. FileTimeString:='Not Found';
  312. exit;
  313. end;
  314. unpacktime(t,DT);
  315. filetimestring:=L0(dt.Year)+'/'+L0(dt.Month)+'/'+L0(dt.Day)+' '+L0(dt.Hour)+':'+L0(dt.min)+':'+L0(dt.sec);
  316. end;
  317. {****************************************************************************
  318. Default Macro Handling
  319. ****************************************************************************}
  320. procedure DefaultReplacements(var s:string);
  321. begin
  322. { Replace some macro's }
  323. Replace(s,'$FPCVER',version_string);
  324. Replace(s,'$VERSION',version_string);
  325. Replace(s,'$FULLVERSION',full_version_string);
  326. Replace(s,'$FPCDATE',date_string);
  327. Replace(s,'$FPCTARGET',target_cpu_string);
  328. Replace(s,'$FPCCPU',target_cpu_string);
  329. Replace(s,'$TARGET',target_path);
  330. Replace(s,'$FPCOS',target_path);
  331. end;
  332. {****************************************************************************
  333. File Handling
  334. ****************************************************************************}
  335. function GetCurrentDir:string;
  336. var
  337. CurrentDir : string;
  338. begin
  339. GetDir(0,CurrentDir);
  340. GetCurrentDir:=FixPath(CurrentDir,false);
  341. end;
  342. function path_absolute(const s : string) : boolean;
  343. {
  344. is path s an absolute path?
  345. }
  346. begin
  347. path_absolute:=false;
  348. {$ifdef unix}
  349. if (length(s)>0) and (s[1]='/') then
  350. path_absolute:=true;
  351. {$else unix}
  352. {$ifdef amiga}
  353. if ((length(s)>0) and ((s[1]='\') or (s[1]='/'))) or (Pos(':',s) = length(s)) then
  354. path_absolute:=true;
  355. {$else}
  356. if ((length(s)>0) and ((s[1]='\') or (s[1]='/'))) or
  357. ((length(s)>2) and (s[2]=':') and ((s[3]='\') or (s[3]='/'))) then
  358. path_absolute:=true;
  359. {$endif amiga}
  360. {$endif unix}
  361. end;
  362. {$ifndef FPC}
  363. Procedure FindClose(var Info : SearchRec);
  364. Begin
  365. End;
  366. {$endif not FPC}
  367. Function FileExists ( Const F : String) : Boolean;
  368. {$ifndef delphi}
  369. Var
  370. Info : SearchRec;
  371. {$endif}
  372. begin
  373. {$ifdef delphi}
  374. FileExists:=sysutils.FileExists(f);
  375. {$else}
  376. findfirst(F,readonly+archive+hidden,info);
  377. FileExists:=(doserror=0);
  378. findclose(Info);
  379. {$endif delphi}
  380. end;
  381. Function PathExists ( F : String) : Boolean;
  382. Var
  383. Info : SearchRec;
  384. begin
  385. if F[Length(f)] in ['/','\'] then
  386. Delete(f,length(f),1);
  387. findfirst(F,readonly+archive+hidden+directory,info);
  388. PathExists:=(doserror=0) and ((info.attr and directory)=directory);
  389. findclose(Info);
  390. end;
  391. Function RemoveFile(const f:string):boolean;
  392. var
  393. g : file;
  394. begin
  395. assign(g,f);
  396. {$I-}
  397. erase(g);
  398. {$I+}
  399. RemoveFile:=(ioresult=0);
  400. end;
  401. Function RemoveDir(d:string):boolean;
  402. begin
  403. if d[length(d)]=DirSep then
  404. Delete(d,length(d),1);
  405. {$I-}
  406. rmdir(d);
  407. {$I+}
  408. RemoveDir:=(ioresult=0);
  409. end;
  410. Function SplitPath(const s:string):string;
  411. var
  412. i : longint;
  413. begin
  414. i:=Length(s);
  415. while (i>0) and not(s[i] in ['/','\']) do
  416. dec(i);
  417. SplitPath:=Copy(s,1,i);
  418. end;
  419. Function SplitFileName(const s:string):string;
  420. var
  421. p : dirstr;
  422. n : namestr;
  423. e : extstr;
  424. begin
  425. FSplit(s,p,n,e);
  426. SplitFileName:=n+e;
  427. end;
  428. Function SplitName(const s:string):string;
  429. var
  430. i,j : longint;
  431. begin
  432. i:=Length(s);
  433. j:=Length(s);
  434. while (i>0) and not(s[i] in ['/','\']) do
  435. dec(i);
  436. while (j>0) and (s[j]<>'.') do
  437. dec(j);
  438. if j<=i then
  439. j:=255;
  440. SplitName:=Copy(s,i+1,j-(i+1));
  441. end;
  442. Function SplitExtension(Const HStr:String):String;
  443. var
  444. j : longint;
  445. begin
  446. j:=length(Hstr);
  447. while (j>0) and (Hstr[j]<>'.') do
  448. begin
  449. if hstr[j]=DirSep then
  450. j:=0
  451. else
  452. dec(j);
  453. end;
  454. if j=0 then
  455. j:=254;
  456. SplitExtension:=Copy(Hstr,j,255);
  457. end;
  458. Function AddExtension(Const HStr,ext:String):String;
  459. begin
  460. if (Ext<>'') and (SplitExtension(HStr)='') then
  461. AddExtension:=Hstr+Ext
  462. else
  463. AddExtension:=Hstr;
  464. end;
  465. Function ForceExtension(Const HStr,ext:String):String;
  466. var
  467. j : longint;
  468. begin
  469. j:=length(Hstr);
  470. while (j>0) and (Hstr[j]<>'.') do
  471. dec(j);
  472. if j=0 then
  473. j:=255;
  474. ForceExtension:=Copy(Hstr,1,j-1)+Ext;
  475. end;
  476. Function FixPath(s:string;allowdot:boolean):string;
  477. var
  478. i : longint;
  479. begin
  480. { Fix separator }
  481. for i:=1 to length(s) do
  482. if s[i] in ['/','\'] then
  483. s[i]:=DirSep;
  484. { Fix ending / }
  485. if (length(s)>0) and (s[length(s)]<>DirSep) and
  486. (s[length(s)]<>':') then
  487. s:=s+DirSep;
  488. { Remove ./ }
  489. if (not allowdot) and (s='.'+DirSep) then
  490. s:='';
  491. { return }
  492. {$ifdef unix}
  493. FixPath:=s;
  494. {$else}
  495. FixPath:=Lower(s);
  496. {$endif}
  497. end;
  498. function FixFileName(const s:string):string;
  499. var
  500. i : longint;
  501. begin
  502. for i:=length(s) downto 1 do
  503. begin
  504. case s[i] of
  505. {$ifdef Unix}
  506. '/','\' :
  507. FixFileName[i]:='/';
  508. {$else Unix}
  509. '/' :
  510. FixFileName[i]:='\';
  511. 'A'..'Z' :
  512. FixFileName[i]:=char(byte(s[i])+32);
  513. {$endif Unix}
  514. else
  515. FixFileName[i]:=s[i];
  516. end;
  517. end;
  518. FixFileName[0]:=s[0];
  519. end;
  520. procedure SplitBinCmd(const s:string;var bstr,cstr:string);
  521. var
  522. i : longint;
  523. begin
  524. i:=pos(' ',s);
  525. if i>0 then
  526. begin
  527. bstr:=Copy(s,1,i-1);
  528. cstr:=Copy(s,i+1,length(s)-i);
  529. end
  530. else
  531. begin
  532. bstr:='';
  533. cstr:='';
  534. end;
  535. end;
  536. procedure TSearchPathList.AddPath(s:string;addfirst:boolean);
  537. var
  538. j : longint;
  539. hs,hsd,
  540. CurrentDir,
  541. CurrPath : string;
  542. dir : searchrec;
  543. hp : TStringListItem;
  544. procedure addcurrpath;
  545. begin
  546. if addfirst then
  547. begin
  548. Remove(currPath);
  549. Insert(currPath);
  550. end
  551. else
  552. begin
  553. { Check if already in path, then we don't add it }
  554. hp:=Find(currPath);
  555. if not assigned(hp) then
  556. Concat(currPath);
  557. end;
  558. end;
  559. begin
  560. if s='' then
  561. exit;
  562. { Support default macro's }
  563. DefaultReplacements(s);
  564. { get current dir }
  565. CurrentDir:=GetCurrentDir;
  566. repeat
  567. { get currpath }
  568. if addfirst then
  569. begin
  570. j:=length(s);
  571. while (j>0) and (s[j]<>';') do
  572. dec(j);
  573. CurrPath:=FixPath(Copy(s,j+1,length(s)-j),false);
  574. if j=0 then
  575. s:=''
  576. else
  577. System.Delete(s,j,length(s)-j+1);
  578. end
  579. else
  580. begin
  581. j:=Pos(';',s);
  582. if j=0 then
  583. j:=255;
  584. CurrPath:=FixPath(Copy(s,1,j-1),false);
  585. System.Delete(s,1,j);
  586. end;
  587. { fix pathname }
  588. if CurrPath='' then
  589. CurrPath:='.'+DirSep
  590. else
  591. begin
  592. CurrPath:=FixPath(FExpand(CurrPath),false);
  593. if (CurrentDir<>'') and (Copy(CurrPath,1,length(CurrentDir))=CurrentDir) then
  594. CurrPath:='.'+DirSep+Copy(CurrPath,length(CurrentDir)+1,255);
  595. end;
  596. { wildcard adding ? }
  597. if pos('*',currpath)>0 then
  598. begin
  599. if currpath[length(currpath)]=dirsep then
  600. hs:=Copy(currpath,1,length(CurrPath)-1)
  601. else
  602. hs:=currpath;
  603. hsd:=SplitPath(hs);
  604. findfirst(hs,directory,dir);
  605. while doserror=0 do
  606. begin
  607. if (dir.name<>'.') and
  608. (dir.name<>'..') and
  609. ((dir.attr and directory)<>0) then
  610. begin
  611. currpath:=hsd+dir.name+dirsep;
  612. hp:=Find(currPath);
  613. if not assigned(hp) then
  614. AddCurrPath;
  615. end;
  616. findnext(dir);
  617. end;
  618. FindClose(dir);
  619. end
  620. else
  621. begin
  622. if PathExists(currpath) then
  623. addcurrpath;
  624. end;
  625. until (s='');
  626. end;
  627. procedure TSearchPathList.AddList(list:TSearchPathList;addfirst:boolean);
  628. var
  629. s : string;
  630. hl : TSearchPathList;
  631. hp,hp2 : TStringListItem;
  632. begin
  633. if list.empty then
  634. exit;
  635. { create temp and reverse the list }
  636. if addfirst then
  637. begin
  638. hl:=TSearchPathList.Create;
  639. hp:=TStringListItem(list.first);
  640. while assigned(hp) do
  641. begin
  642. hl.insert(hp.Str);
  643. hp:=TStringListItem(hp.next);
  644. end;
  645. while not hl.empty do
  646. begin
  647. s:=hl.GetFirst;
  648. Remove(s);
  649. Insert(s);
  650. end;
  651. hl.Free;
  652. end
  653. else
  654. begin
  655. hp:=TStringListItem(list.first);
  656. while assigned(hp) do
  657. begin
  658. hp2:=Find(hp.Str);
  659. { Check if already in path, then we don't add it }
  660. if not assigned(hp2) then
  661. Concat(hp.Str);
  662. hp:=TStringListItem(hp.next);
  663. end;
  664. end;
  665. end;
  666. function TSearchPathList.FindFile(const f : string;var foundfile:string):boolean;
  667. Var
  668. p : TStringListItem;
  669. begin
  670. FindFile:=false;
  671. p:=TStringListItem(first);
  672. while assigned(p) do
  673. begin
  674. {
  675. Search order for case sensitive systems:
  676. 1. lowercase
  677. 2. NormalCase
  678. 3. UPPERCASE
  679. None case sensitive only lowercase
  680. }
  681. FoundFile:=p.Str+Lower(f);
  682. If FileExists(FoundFile) then
  683. begin
  684. FindFile:=true;
  685. exit;
  686. end;
  687. {$ifdef UNIX}
  688. FoundFile:=p.Str+f;
  689. If FileExists(FoundFile) then
  690. begin
  691. FindFile:=true;
  692. exit;
  693. end;
  694. FoundFile:=p.Str+Upper(f);
  695. If FileExists(FoundFile) then
  696. begin
  697. FindFile:=true;
  698. exit;
  699. end;
  700. {$endif UNIX}
  701. p:=TStringListItem(p.next);
  702. end;
  703. { Return original filename if not found }
  704. FoundFile:=f;
  705. end;
  706. Function GetFileTime ( Var F : File) : Longint;
  707. Var
  708. {$ifdef unix}
  709. Info : Stat;
  710. {$endif}
  711. L : longint;
  712. begin
  713. {$ifdef unix}
  714. FStat (F,Info);
  715. L:=Info.Mtime;
  716. {$else}
  717. GetFTime(f,l);
  718. {$endif}
  719. GetFileTime:=L;
  720. end;
  721. Function GetNamedFileTime (Const F : String) : Longint;
  722. begin
  723. GetNamedFileTime:=do_getnamedfiletime(F);
  724. end;
  725. function FindFile(const f : string;path : string;var foundfile:string):boolean;
  726. Var
  727. singlepathstring : string;
  728. i : longint;
  729. begin
  730. {$ifdef Unix}
  731. for i:=1 to length(path) do
  732. if path[i]=':' then
  733. path[i]:=';';
  734. {$endif Unix}
  735. FindFile:=false;
  736. repeat
  737. i:=pos(';',path);
  738. if i=0 then
  739. i:=256;
  740. singlepathstring:=FixPath(copy(path,1,i-1),false);
  741. delete(path,1,i);
  742. {
  743. Search order for case sensitive systems:
  744. 1. lowercase
  745. 2. NormalCase
  746. 3. UPPERCASE
  747. None case sensitive only lowercase
  748. }
  749. FoundFile:=singlepathstring+Lower(f);
  750. If FileExists(FoundFile) then
  751. begin
  752. FindFile:=true;
  753. exit;
  754. end;
  755. {$ifdef UNIX}
  756. FoundFile:=singlepathstring+f;
  757. If FileExists(FoundFile) then
  758. begin
  759. FindFile:=true;
  760. exit;
  761. end;
  762. FoundFile:=singlepathstring+Upper(f);
  763. If FileExists(FoundFile) then
  764. begin
  765. FindFile:=true;
  766. exit;
  767. end;
  768. {$endif UNIX}
  769. until path='';
  770. FoundFile:=f;
  771. end;
  772. function FindExe(const bin:string;var foundfile:string):boolean;
  773. begin
  774. {$ifdef delphi}
  775. FindExe:=FindFile(FixFileName(AddExtension(bin,source_info.exeext)),'.;'+exepath+';'+dmisc.getenv('PATH'),foundfile);
  776. {$else delphi}
  777. FindExe:=FindFile(FixFileName(AddExtension(bin,source_info.exeext)),'.;'+exepath+';'+dos.getenv('PATH'),foundfile);
  778. {$endif delphi}
  779. end;
  780. function GetShortName(const n:string):string;
  781. {$ifdef win32}
  782. var
  783. hs,hs2 : string;
  784. i : longint;
  785. {$endif}
  786. {$ifdef go32v2}
  787. var
  788. hs : string;
  789. {$endif}
  790. begin
  791. GetShortName:=n;
  792. {$ifdef win32}
  793. hs:=n+#0;
  794. i:=Windows.GetShortPathName(@hs[1],@hs2[1],high(hs2));
  795. if (i>0) and (i<=high(hs2)) then
  796. begin
  797. hs2[0]:=chr(strlen(@hs2[1]));
  798. GetShortName:=hs2;
  799. end;
  800. {$endif}
  801. {$ifdef go32v2}
  802. hs:=n;
  803. if Dos.GetShortName(hs) then
  804. GetShortName:=hs;
  805. {$endif}
  806. end;
  807. {****************************************************************************
  808. OS Dependent things
  809. ****************************************************************************}
  810. function GetEnvPChar(const envname:string):pchar;
  811. {$ifdef win32}
  812. var
  813. s : string;
  814. i,len : longint;
  815. hp,p,p2 : pchar;
  816. {$endif}
  817. {$ifdef os2}
  818. var
  819. P1, P2: PChar;
  820. {$endif}
  821. begin
  822. {$ifdef unix}
  823. GetEnvPchar:={$ifdef ver1_0}Linux{$else}Unix{$endif}.Getenv(envname);
  824. {$define GETENVOK}
  825. {$endif}
  826. {$ifdef win32}
  827. GetEnvPchar:=nil;
  828. p:=GetEnvironmentStrings;
  829. hp:=p;
  830. while hp^<>#0 do
  831. begin
  832. s:=strpas(hp);
  833. i:=pos('=',s);
  834. len:=strlen(hp);
  835. if upper(copy(s,1,i-1))=upper(envname) then
  836. begin
  837. GetMem(p2,len-length(envname));
  838. Move(hp[i],p2^,len-length(envname));
  839. GetEnvPchar:=p2;
  840. break;
  841. end;
  842. { next string entry}
  843. hp:=hp+len+1;
  844. end;
  845. FreeEnvironmentStrings(p);
  846. {$define GETENVOK}
  847. {$endif}
  848. {$ifdef os2}
  849. P1 := StrPNew (EnvName);
  850. if Assigned (P1) then
  851. begin
  852. if DosCalls.DosScanEnv (P1, P2) = 0 then
  853. GetEnvPChar := P2
  854. else
  855. GetEnvPChar := nil;
  856. StrDispose (P1);
  857. end else GetEnvPChar := nil;
  858. {$define GETENVOK}
  859. {$endif}
  860. {$ifdef GETENVOK}
  861. {$undef GETENVOK}
  862. {$else}
  863. GetEnvPchar:=StrPNew({$ifdef delphi}DMisc{$else}Dos{$endif}.Getenv(envname));
  864. {$endif}
  865. end;
  866. procedure FreeEnvPChar(p:pchar);
  867. begin
  868. {$ifndef unix}
  869. {$ifndef os2}
  870. StrDispose(p);
  871. {$endif}
  872. {$endif}
  873. end;
  874. Procedure Shell(const command:string);
  875. { This is already defined in the linux.ppu for linux, need for the *
  876. expansion under linux }
  877. {$ifdef unix}
  878. begin
  879. {$ifdef ver1_0}Linux{$else}Unix{$endif}.Shell(command);
  880. end;
  881. {$else}
  882. var
  883. comspec : string;
  884. begin
  885. comspec:=getenv('COMSPEC');
  886. Exec(comspec,' /C '+command);
  887. end;
  888. {$endif}
  889. Function SetCompileMode(const s:string; changeInit: boolean):boolean;
  890. var
  891. b : boolean;
  892. begin
  893. b:=true;
  894. if s='DEFAULT' then
  895. aktmodeswitches:=initmodeswitches
  896. else
  897. if s='DELPHI' then
  898. aktmodeswitches:=delphimodeswitches
  899. else
  900. if s='TP' then
  901. aktmodeswitches:=tpmodeswitches
  902. else
  903. if s='FPC' then
  904. aktmodeswitches:=fpcmodeswitches
  905. else
  906. if s='OBJFPC' then
  907. aktmodeswitches:=objfpcmodeswitches
  908. else
  909. if s='GPC' then
  910. aktmodeswitches:=gpcmodeswitches
  911. else
  912. b:=false;
  913. if b and changeInit then
  914. initmodeswitches := aktmodeswitches;
  915. if b then
  916. begin
  917. { turn ansistrings on by default ? }
  918. if (m_delphi in aktmodeswitches) then
  919. begin
  920. include(aktlocalswitches,cs_ansistrings);
  921. if changeinit then
  922. include(initlocalswitches,cs_ansistrings);
  923. end
  924. else
  925. begin
  926. exclude(aktlocalswitches,cs_ansistrings);
  927. if changeinit then
  928. exclude(initlocalswitches,cs_ansistrings);
  929. end;
  930. { enum packing }
  931. if (m_tp7 in aktmodeswitches) then
  932. aktpackenum:=1
  933. else
  934. aktpackenum:=4;
  935. if changeinit then
  936. initpackenum:=aktpackenum;
  937. end;
  938. SetCompileMode:=b;
  939. end;
  940. { '('D1:'00000000-'D2:'0000-'D3:'0000-'D4:'0000-000000000000)' }
  941. function string2guid(const s: string; var GUID: TGUID): boolean;
  942. function ishexstr(const hs: string): boolean;
  943. var
  944. i: integer;
  945. begin
  946. ishexstr:=false;
  947. for i:=1 to Length(hs) do begin
  948. if not (hs[i] in ['0'..'9','A'..'F','a'..'f']) then
  949. exit;
  950. end;
  951. ishexstr:=true;
  952. end;
  953. function hexstr2longint(const hexs: string): longint;
  954. var
  955. i: integer;
  956. rl: longint;
  957. begin
  958. rl:=0;
  959. for i:=1 to length(hexs) do begin
  960. rl:=rl shl 4;
  961. case hexs[i] of
  962. '0'..'9' : inc(rl,ord(hexs[i])-ord('0'));
  963. 'A'..'F' : inc(rl,ord(hexs[i])-ord('A')+10);
  964. 'a'..'f' : inc(rl,ord(hexs[i])-ord('a')+10);
  965. end
  966. end;
  967. hexstr2longint:=rl;
  968. end;
  969. var
  970. i: integer;
  971. begin
  972. if (Length(s)=38) and (s[1]='{') and (s[38]='}') and
  973. (s[10]='-') and (s[15]='-') and (s[20]='-') and (s[25]='-') and
  974. ishexstr(copy(s,2,8)) and ishexstr(copy(s,11,4)) and
  975. ishexstr(copy(s,16,4)) and ishexstr(copy(s,21,4)) and
  976. ishexstr(copy(s,26,12)) then begin
  977. GUID.D1:=dword(hexstr2longint(copy(s,2,8)));
  978. GUID.D2:=hexstr2longint(copy(s,11,4));
  979. GUID.D3:=hexstr2longint(copy(s,16,4));
  980. for i:=0 to 1 do
  981. GUID.D4[i]:=hexstr2longint(copy(s,21+i*2,2));
  982. for i:=2 to 7 do
  983. GUID.D4[i]:=hexstr2longint(copy(s,22+i*2,2));
  984. string2guid:=true;
  985. end
  986. else
  987. string2guid:=false;
  988. end;
  989. function guid2string(const GUID: TGUID): string;
  990. function long2hex(l, len: longint): string;
  991. const
  992. hextbl: array[0..15] of char = '0123456789ABCDEF';
  993. var
  994. rs: string;
  995. i: integer;
  996. begin
  997. rs[0]:=chr(len);
  998. for i:=len downto 1 do begin
  999. rs[i]:=hextbl[l and $F];
  1000. l:=l shr 4;
  1001. end;
  1002. long2hex:=rs;
  1003. end;
  1004. begin
  1005. guid2string:=
  1006. '{'+long2hex(GUID.D1,8)+
  1007. '-'+long2hex(GUID.D2,4)+
  1008. '-'+long2hex(GUID.D3,4)+
  1009. '-'+long2hex(GUID.D4[0],2)+long2hex(GUID.D4[1],2)+
  1010. '-'+long2hex(GUID.D4[2],2)+long2hex(GUID.D4[3],2)+
  1011. long2hex(GUID.D4[4],2)+long2hex(GUID.D4[5],2)+
  1012. long2hex(GUID.D4[6],2)+long2hex(GUID.D4[7],2)+
  1013. '}';
  1014. end;
  1015. function UpdateAlignmentStr(s:string;var a:talignmentinfo):boolean;
  1016. var
  1017. tok : string;
  1018. vstr : string;
  1019. l : longint;
  1020. code : integer;
  1021. b : talignmentinfo;
  1022. begin
  1023. UpdateAlignmentStr:=true;
  1024. uppervar(s);
  1025. fillchar(b,sizeof(b),0);
  1026. repeat
  1027. tok:=GetToken(s,'=');
  1028. if tok='' then
  1029. break;
  1030. vstr:=GetToken(s,',');
  1031. val(vstr,l,code);
  1032. if tok='PROC' then
  1033. b.procalign:=l
  1034. else if tok='JUMP' then
  1035. b.jumpalign:=l
  1036. else if tok='LOOP' then
  1037. b.loopalign:=l
  1038. else if tok='CONSTMIN' then
  1039. b.constalignmin:=l
  1040. else if tok='CONSTMAX' then
  1041. b.constalignmax:=l
  1042. else if tok='VARMIN' then
  1043. b.varalignmin:=l
  1044. else if tok='VARMAX' then
  1045. b.varalignmax:=l
  1046. else if tok='LOCALMIN' then
  1047. b.localalignmin:=l
  1048. else if tok='LOCALMAX' then
  1049. b.localalignmax:=l
  1050. else if tok='RECORDMIN' then
  1051. b.recordalignmin:=l
  1052. else if tok='RECORDMAX' then
  1053. b.recordalignmax:=l
  1054. else if tok='PARAALIGN' then
  1055. b.paraalign:=l
  1056. else { Error }
  1057. UpdateAlignmentStr:=false;
  1058. until false;
  1059. UpdateAlignment(a,b);
  1060. end;
  1061. {****************************************************************************
  1062. Init
  1063. ****************************************************************************}
  1064. {$ifdef unix}
  1065. {$define need_path_search}
  1066. {$endif unix}
  1067. {$ifdef os2}
  1068. {$define need_path_search}
  1069. {$endif os2}
  1070. procedure get_exepath;
  1071. var
  1072. hs1 : namestr;
  1073. hs2 : extstr;
  1074. begin
  1075. {$ifdef delphi}
  1076. exepath:=dmisc.getenv('PPC_EXEC_PATH');
  1077. {$else delphi}
  1078. exepath:=dos.getenv('PPC_EXEC_PATH');
  1079. {$endif delphi}
  1080. if exepath='' then
  1081. fsplit(FixFileName(system.paramstr(0)),exepath,hs1,hs2);
  1082. {$ifdef need_path_search}
  1083. if exepath='' then
  1084. begin
  1085. if pos(source_info.exeext,hs1) <>
  1086. (length(hs1) - length(source_info.exeext)+1) then
  1087. hs1 := hs1 + source_info.exeext;
  1088. {$ifdef delphi}
  1089. findfile(hs1,dmisc.getenv('PATH'),exepath);
  1090. {$else delphi}
  1091. findfile(hs1,dos.getenv('PATH'),exepath);
  1092. {$endif delphi}
  1093. exepath:=SplitPath(exepath);
  1094. end;
  1095. {$endif need_path_search}
  1096. exepath:=FixPath(exepath,false);
  1097. end;
  1098. procedure DoneGlobals;
  1099. begin
  1100. initdefines.free;
  1101. if assigned(DLLImageBase) then
  1102. StringDispose(DLLImageBase);
  1103. RelocSection:=true;
  1104. RelocSectionSetExplicitly:=false;
  1105. UseDeffileForExport:=true;
  1106. librarysearchpath.Free;
  1107. unitsearchpath.Free;
  1108. objectsearchpath.Free;
  1109. includesearchpath.Free;
  1110. end;
  1111. procedure InitGlobals;
  1112. begin
  1113. { set global switches }
  1114. do_build:=false;
  1115. do_release:=false;
  1116. do_make:=true;
  1117. compile_level:=0;
  1118. { these two should not be cleared in
  1119. DoneGlobals as the IDE might need their value }
  1120. IsExe:=false;
  1121. DLLsource:=false;
  1122. { Output }
  1123. OutputFile:='';
  1124. OutputExeDir:='';
  1125. OutputUnitDir:='';
  1126. { Utils directory }
  1127. utilsdirectory:='';
  1128. { Search Paths }
  1129. librarysearchpath:=TSearchPathList.Create;
  1130. unitsearchpath:=TSearchPathList.Create;
  1131. includesearchpath:=TSearchPathList.Create;
  1132. objectsearchpath:=TSearchPathList.Create;
  1133. { Def file }
  1134. usewindowapi:=false;
  1135. description:='Compiled by FPC '+version_string+' - '+target_cpu_string;
  1136. dllversion:='';
  1137. nwscreenname := '';
  1138. nwthreadname := '';
  1139. nwcopyright := '';
  1140. { Init values }
  1141. initmodeswitches:=fpcmodeswitches;
  1142. initlocalswitches:=[cs_check_io];
  1143. initmoduleswitches:=[cs_extsyntax,cs_browser];
  1144. initglobalswitches:=[cs_check_unit_name,cs_link_static];
  1145. initoutputformat:=as_none;
  1146. fillchar(initalignment,sizeof(talignmentinfo),0);
  1147. {$ifdef i386}
  1148. initoptprocessor:=Class386;
  1149. initspecificoptprocessor:=Class386;
  1150. initpackenum:=4;
  1151. {$IFDEF testvarsets}
  1152. initsetalloc:=0;
  1153. {$ENDIF}
  1154. initasmmode:=asmmode_i386_att;
  1155. {$else not i386}
  1156. {$ifdef m68k}
  1157. initoptprocessor:=MC68000;
  1158. include(initmoduleswitches,cs_fp_emulation);
  1159. initpackenum:=4;
  1160. {$IFDEF testvarsets}
  1161. initsetalloc:=0;
  1162. {$ENDIF}
  1163. initoutputformat:=as_m68k_as;
  1164. initasmmode:=asmmode_m68k_mot;
  1165. {$endif m68k}
  1166. {$endif i386}
  1167. initinterfacetype:=it_interfacecom;
  1168. initdefines:=TStringList.Create;
  1169. { memory sizes, will be overriden by parameter or default for target
  1170. in options or init_parser }
  1171. stacksize:=0;
  1172. heapsize:=0;
  1173. maxheapsize:=0;
  1174. { compile state }
  1175. in_args:=false;
  1176. { must_be_valid:=true; obsolete PM }
  1177. not_unit_proc:=true;
  1178. apptype:=app_cui;
  1179. end;
  1180. begin
  1181. get_exepath;
  1182. {$ifdef EXTDEBUG}
  1183. {$ifdef FPC}
  1184. EntryMemUsed:=system.HeapSize-MemAvail;
  1185. {$endif FPC}
  1186. {$endif}
  1187. end.
  1188. {
  1189. $Log$
  1190. Revision 1.39 2001-07-01 20:16:15 peter
  1191. * alignmentinfo record added
  1192. * -Oa argument supports more alignment settings that can be specified
  1193. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  1194. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  1195. required alignment and the maximum usefull alignment. The final
  1196. alignment will be choosen per variable size dependent on these
  1197. settings
  1198. Revision 1.38 2001/06/18 20:36:24 peter
  1199. * -Ur switch (merged)
  1200. * masm fixes (merged)
  1201. * quoted filenames for go32v2 and win32
  1202. Revision 1.37 2001/06/03 21:57:35 peter
  1203. + hint directive parsing support
  1204. Revision 1.36 2001/06/03 20:21:08 peter
  1205. * Kylix fixes, mostly case names of units
  1206. Revision 1.35 2001/05/30 21:35:48 peter
  1207. * netware patches for copyright, screenname, threadname directives
  1208. Revision 1.34 2001/05/12 12:11:31 peter
  1209. * simplify_ppu is now the default, a recompile of the compiler now
  1210. only compiles pp.pas
  1211. Revision 1.33 2001/05/06 14:49:17 peter
  1212. * ppu object to class rewrite
  1213. * move ppu read and write stuff to fppu
  1214. Revision 1.32 2001/04/18 22:01:53 peter
  1215. * registration of targets and assemblers
  1216. Revision 1.31 2001/04/15 09:48:29 peter
  1217. * fixed crash in labelnode
  1218. * easier detection of goto and label in try blocks
  1219. Revision 1.30 2001/04/13 01:22:07 peter
  1220. * symtable change to classes
  1221. * range check generation and errors fixed, make cycle DEBUG=1 works
  1222. * memory leaks fixed
  1223. Revision 1.29 2001/04/04 21:30:42 florian
  1224. * applied several fixes to get the DD8 Delphi Unit compiled
  1225. e.g. "forward"-interfaces are working now
  1226. Revision 1.28 2001/02/20 21:41:16 peter
  1227. * new fixfilename, findfile for unix. Look first for lowercase, then
  1228. NormalCase and last for UPPERCASE names.
  1229. Revision 1.27 2001/02/09 23:05:45 peter
  1230. * default packenum=1 for tp7 mode
  1231. Revision 1.26 2001/02/05 20:47:00 peter
  1232. * support linux unit for ver1_0 compilers
  1233. Revision 1.25 2001/01/21 20:32:45 marco
  1234. * Renamefest. Compiler part. Not that hard.
  1235. Revision 1.24 2001/01/20 18:32:52 hajny
  1236. + APPTYPE support under OS/2, app_fs, GetEnvPChar for OS/2
  1237. Revision 1.23 2001/01/13 00:03:41 peter
  1238. * fixed findexe to also support already extension in name
  1239. Revision 1.22 2000/12/26 15:57:25 peter
  1240. * use system.paramstr()
  1241. Revision 1.21 2000/12/25 00:07:26 peter
  1242. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  1243. tlinkedlist objects)
  1244. Revision 1.20 2000/11/13 15:26:12 marco
  1245. * Renamefest
  1246. Revision 1.19 2000/11/12 22:20:37 peter
  1247. * create generic toutputsection for binary writers
  1248. Revision 1.18 2000/11/04 14:25:19 florian
  1249. + merged Attila's changes for interfaces, not tested yet
  1250. Revision 1.17 2000/10/31 22:02:46 peter
  1251. * symtable splitted, no real code changes
  1252. Revision 1.16 2000/10/04 14:51:08 pierre
  1253. * IsExe restored
  1254. Revision 1.15 2000/09/27 21:20:56 peter
  1255. * also set initlocalswitches in setcompilemode (merged)
  1256. Revision 1.14 2000/09/26 10:50:41 jonas
  1257. * initmodeswitches is changed is you change the compiler mode from the
  1258. command line (the -S<x> switches didn't work anymore for changing the
  1259. compiler mode) (merged from fixes branch)
  1260. Revision 1.13 2000/09/24 21:33:46 peter
  1261. * message updates merges
  1262. Revision 1.12 2000/09/24 21:19:50 peter
  1263. * delphi compile fixes
  1264. Revision 1.11 2000/09/24 15:12:40 peter
  1265. * fixed typo
  1266. Revision 1.10 2000/09/24 15:06:16 peter
  1267. * use defines.inc
  1268. Revision 1.9 2000/09/24 10:33:07 peter
  1269. * searching of exe in path also for OS/2
  1270. * fixed searching of exe in path.
  1271. Revision 1.8 2000/09/11 17:00:22 florian
  1272. + first implementation of Netware Module support, thanks to
  1273. Armin Diehl ([email protected]) for providing the patches
  1274. Revision 1.7 2000/08/27 16:11:51 peter
  1275. * moved some util functions from globals,cobjects to cutils
  1276. * splitted files into finput,fmodule
  1277. Revision 1.6 2000/08/12 19:14:58 peter
  1278. * ELF writer works now also with -g
  1279. * ELF writer is default again for linux
  1280. Revision 1.5 2000/08/12 15:30:44 peter
  1281. * IDE patch for stream reading (merged)
  1282. Revision 1.4 2000/08/02 19:49:59 peter
  1283. * first things for default parameters
  1284. Revision 1.3 2000/07/13 12:08:25 michael
  1285. + patched to 1.1.0 with former 1.09patch from peter
  1286. Revision 1.2 2000/07/13 11:32:41 michael
  1287. + removed logs
  1288. }