globals.pas 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221
  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,cutils,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. m_out,m_default_para];
  57. fpcmodeswitches : tmodeswitches=
  58. [m_fpc,m_all,m_string_pchar,m_nested_comment,m_repeat_forward,
  59. m_cvar_support,m_initfinal,m_add_pointer];
  60. objfpcmodeswitches : tmodeswitches=
  61. [m_objfpc,m_fpc,m_all,m_class,m_objpas,m_result,m_string_pchar,m_nested_comment,
  62. m_repeat_forward,m_cvar_support,m_initfinal,m_add_pointer,m_out,m_default_para];
  63. tpmodeswitches : tmodeswitches=
  64. [m_tp7,m_tp,m_all,m_tp_procvar];
  65. gpcmodeswitches : tmodeswitches=
  66. [m_gpc,m_all];
  67. type
  68. TSearchPathList = object(TStringQueue)
  69. procedure AddPath(s:string;addfirst:boolean);
  70. procedure AddList(list:TSearchPathList;addfirst:boolean);
  71. function FindFile(const f : string;var b : boolean) : string;
  72. end;
  73. var
  74. { specified inputfile }
  75. inputdir : dirstr;
  76. inputfile : namestr;
  77. inputextension : extstr;
  78. { specified outputfile with -o parameter }
  79. outputfile : namestr;
  80. { specified with -FE or -FU }
  81. outputexedir : dirstr;
  82. outputunitdir : dirstr;
  83. { things specified with parameters }
  84. paralinkoptions,
  85. paradynamiclinker : string;
  86. parapreprocess : boolean;
  87. { directory where the utils can be found (options -FD) }
  88. utilsdirectory : dirstr;
  89. { some flags for global compiler switches }
  90. do_build,
  91. do_make : boolean;
  92. not_unit_proc : boolean;
  93. { path for searching units, different paths can be seperated by ; }
  94. exepath : dirstr; { Path to ppc }
  95. librarysearchpath,
  96. unitsearchpath,
  97. objectsearchpath,
  98. includesearchpath : TSearchPathList;
  99. { deffile }
  100. usewindowapi : boolean;
  101. description : string;
  102. dllversion : string;
  103. dllmajor,dllminor : word;
  104. { current position }
  105. token, { current token being parsed }
  106. idtoken : ttoken; { holds the token if the pattern is a known word }
  107. tokenpos, { last postion of the read token }
  108. aktfilepos : tfileposinfo; { current position }
  109. { type of currently parsed block }
  110. { isn't full implemented (FK) }
  111. block_type : tblock_type;
  112. in_args : boolean; { arguments must be checked especially }
  113. parsing_para_level : longint; { parameter level, used to convert
  114. proc calls to proc loads in firstcalln }
  115. { Must_be_valid : boolean; should the variable already have a value
  116. obsolete replace by set_varstate function }
  117. compile_level : word;
  118. make_ref : boolean;
  119. resolving_forward : boolean; { used to add forward reference as second ref }
  120. use_esp_stackframe : boolean; { to test for call with ESP as stack frame }
  121. inlining_procedure : boolean; { are we inlining a procedure }
  122. {$ifdef TP}
  123. use_big : boolean;
  124. {$endif}
  125. { commandline values }
  126. initdefines : tlinkedlist;
  127. initglobalswitches : tglobalswitches;
  128. initmoduleswitches : tmoduleswitches;
  129. initlocalswitches : tlocalswitches;
  130. initmodeswitches : tmodeswitches;
  131. {$IFDEF testvarsets}
  132. Initsetalloc, {0=fixed, 1 =var}
  133. {$ENDIF}
  134. initpackenum : longint;
  135. initpackrecords : tpackrecords;
  136. initoutputformat : tasm;
  137. initoptprocessor,
  138. initspecificoptprocessor : tprocessors;
  139. initasmmode : tasmmode;
  140. { current state values }
  141. aktglobalswitches : tglobalswitches;
  142. aktmoduleswitches : tmoduleswitches;
  143. aktlocalswitches : tlocalswitches;
  144. nextaktlocalswitches : tlocalswitches;
  145. localswitcheschanged : boolean;
  146. aktmodeswitches : tmodeswitches;
  147. {$IFDEF testvarsets}
  148. aktsetalloc,
  149. {$ENDIF}
  150. aktpackenum : longint;
  151. aktmaxfpuregisters: longint;
  152. aktpackrecords : tpackrecords;
  153. aktoutputformat : tasm;
  154. aktoptprocessor,
  155. aktspecificoptprocessor : tprocessors;
  156. aktasmmode : tasmmode;
  157. { Memory sizes }
  158. heapsize,
  159. maxheapsize,
  160. stacksize : longint;
  161. {$Ifdef EXTDEBUG}
  162. total_of_firstpass,
  163. firstpass_several : longint;
  164. {$ifdef FPC}
  165. EntryMemUsed : longint;
  166. {$endif FPC}
  167. { parameter switches }
  168. debugstop,
  169. only_one_pass : boolean;
  170. {$EndIf EXTDEBUG}
  171. { windows application type }
  172. apptype : tapptype;
  173. const
  174. RelocSection : boolean = true;
  175. RelocSectionSetExplicitly : boolean = false;
  176. LinkTypeSetExplicitly : boolean = false;
  177. DLLsource : boolean = false;
  178. DLLImageBase : pstring = nil;
  179. UseDeffileForExport : boolean = true;
  180. ForceDeffileForExport : boolean = false;
  181. { used to set all registers used for each global function
  182. this should dramatically decrease the number of
  183. recompilations needed PM }
  184. simplify_ppu : boolean = false;
  185. { should we allow non static members ? }
  186. allow_only_static : boolean = false;
  187. Inside_asm_statement : boolean = false;
  188. { for error info in pp.pas }
  189. const
  190. parser_current_file : string = '';
  191. procedure abstract;
  192. {$ifdef debug}
  193. { if the pointer don't point to the heap then write an error }
  194. function assigned(p : pointer) : boolean;
  195. {$endif}
  196. function bstoslash(const s : string) : string;
  197. function getdatestr:string;
  198. function gettimestr:string;
  199. function filetimestring( t : longint) : string;
  200. procedure DefaultReplacements(var s:string);
  201. function GetCurrentDir:string;
  202. function path_absolute(const s : string) : boolean;
  203. Function PathExists ( F : String) : Boolean;
  204. Function FileExists ( Const F : String) : Boolean;
  205. Function RemoveFile(const f:string):boolean;
  206. Function RemoveDir(d:string):boolean;
  207. Function GetFileTime ( Var F : File) : Longint;
  208. Function GetNamedFileTime ( Const F : String) : Longint;
  209. Function SplitPath(const s:string):string;
  210. Function SplitFileName(const s:string):string;
  211. Function SplitName(const s:string):string;
  212. Function SplitExtension(Const HStr:String):String;
  213. Function AddExtension(Const HStr,ext:String):String;
  214. Function ForceExtension(Const HStr,ext:String):String;
  215. Function FixPath(s:string;allowdot:boolean):string;
  216. function FixFileName(const s:string):string;
  217. procedure SplitBinCmd(const s:string;var bstr,cstr:string);
  218. procedure SynchronizeFileTime(const fn1,fn2:string);
  219. function FindFile(const f : string;path : string;var b : boolean) : string;
  220. function FindExe(bin:string;var found:boolean):string;
  221. function GetShortName(const n:string):string;
  222. Procedure Shell(const command:string);
  223. function GetEnvPChar(const envname:string):pchar;
  224. procedure FreeEnvPChar(p:pchar);
  225. procedure InitGlobals;
  226. procedure DoneGlobals;
  227. implementation
  228. uses
  229. comphook;
  230. procedure abstract;
  231. begin
  232. do_internalerror(255);
  233. end;
  234. function ngraphsearchvalue(const s1,s2 : string) : double;
  235. const
  236. n = 3;
  237. var
  238. equals,i,j : longint;
  239. hs : string;
  240. begin
  241. equals:=0;
  242. { is the string long enough ? }
  243. if min(length(s1),length(s2))-n+1<1 then
  244. begin
  245. ngraphsearchvalue:=0.0;
  246. exit;
  247. end;
  248. for i:=1 to length(s1)-n+1 do
  249. begin
  250. hs:=copy(s1,i,n);
  251. for j:=1 to length(s2)-n+1 do
  252. if hs=copy(s2,j,n) then
  253. inc(equals);
  254. end;
  255. {$ifdef fpc}
  256. ngraphsearchvalue:=equals/double(max(length(s1),length(s2))-n+1);
  257. {$else}
  258. ngraphsearchvalue:=equals/(max(length(s1),length(s2))-n+1);
  259. {$endif}
  260. end;
  261. function bstoslash(const s : string) : string;
  262. {
  263. return string s with all \ changed into /
  264. }
  265. var
  266. i : longint;
  267. begin
  268. for i:=1to length(s) do
  269. if s[i]='\' then
  270. bstoslash[i]:='/'
  271. else
  272. bstoslash[i]:=s[i];
  273. {$ifndef TP}
  274. {$ifopt H+}
  275. setlength(bstoslash,length(s));
  276. {$else}
  277. bstoslash[0]:=s[0];
  278. {$endif}
  279. {$else}
  280. bstoslash[0]:=s[0];
  281. {$endif}
  282. end;
  283. {$ifdef debug}
  284. function assigned(p : pointer) : boolean;
  285. {$ifndef FPC}
  286. {$ifndef DPMI}
  287. type
  288. ptrrec = record
  289. ofs,seg : word;
  290. end;
  291. var
  292. lp : longint;
  293. {$endif DPMI}
  294. {$endif FPC}
  295. begin
  296. {$ifdef FPC}
  297. { Assigned is used for procvar and
  298. stack stored temp records !! PM }
  299. (* if (p<>nil) {and
  300. ((p<heaporg) or
  301. (p>heapptr))} then
  302. do_internalerror(230); *)
  303. {$else}
  304. {$ifdef DPMI}
  305. assigned:=(p<>nil);
  306. exit;
  307. {$else DPMI}
  308. if p=nil then
  309. lp:=0
  310. else
  311. lp:=longint(ptrrec(p).seg)*16+longint(ptrrec(p).ofs);
  312. if (lp<>0) and
  313. ((lp<longint(seg(heaporg^))*16+longint(ofs(heaporg^))) or
  314. (lp>longint(seg(heapptr^))*16+longint(ofs(heapptr^)))) then
  315. do_internalerror(230);
  316. {$endif DPMI}
  317. {$endif FPC}
  318. assigned:=(p<>nil);
  319. end;
  320. {$endif}
  321. {****************************************************************************
  322. Time Handling
  323. ****************************************************************************}
  324. Function L0(l:longint):string;
  325. {
  326. return the string of value l, if l<10 then insert a zero, so
  327. the string is always at least 2 chars '01','02',etc
  328. }
  329. var
  330. s : string;
  331. begin
  332. Str(l,s);
  333. if l<10 then
  334. s:='0'+s;
  335. L0:=s;
  336. end;
  337. function gettimestr:string;
  338. {
  339. get the current time in a string HH:MM:SS
  340. }
  341. var
  342. hour,min,sec,hsec : word;
  343. begin
  344. {$ifdef delphi}
  345. dmisc.gettime(hour,min,sec,hsec);
  346. {$else delphi}
  347. dos.gettime(hour,min,sec,hsec);
  348. {$endif delphi}
  349. gettimestr:=L0(Hour)+':'+L0(min)+':'+L0(sec);
  350. end;
  351. function getdatestr:string;
  352. {
  353. get the current date in a string YY/MM/DD
  354. }
  355. var
  356. Year,Month,Day,Wday : Word;
  357. begin
  358. {$ifdef delphi}
  359. dmisc.getdate(year,month,day,wday);
  360. {$else}
  361. dos.getdate(year,month,day,wday);
  362. {$endif}
  363. getdatestr:=L0(Year)+'/'+L0(Month)+'/'+L0(Day);
  364. end;
  365. function filetimestring( t : longint) : string;
  366. {
  367. convert dos datetime t to a string YY/MM/DD HH:MM:SS
  368. }
  369. var
  370. {$ifndef linux}
  371. DT : DateTime;
  372. {$endif}
  373. Year,Month,Day,Hour,Min,Sec : Word;
  374. begin
  375. if t=-1 then
  376. begin
  377. FileTimeString:='Not Found';
  378. exit;
  379. end;
  380. {$ifndef linux}
  381. unpacktime(t,DT);
  382. Year:=dT.year;month:=dt.month;day:=dt.day;
  383. Hour:=dt.hour;min:=dt.min;sec:=dt.sec;
  384. {$else}
  385. EpochToLocal (t,year,month,day,hour,min,sec);
  386. {$endif}
  387. filetimestring:=L0(Year)+'/'+L0(Month)+'/'+L0(Day)+' '+L0(Hour)+':'+L0(min)+':'+L0(sec);
  388. end;
  389. {****************************************************************************
  390. Default Macro Handling
  391. ****************************************************************************}
  392. procedure DefaultReplacements(var s:string);
  393. begin
  394. { Replace some macro's }
  395. Replace(s,'$FPCVER',version_string);
  396. Replace(s,'$VERSION',version_string);
  397. Replace(s,'$FULLVERSION',full_version_string);
  398. Replace(s,'$FPCDATE',date_string);
  399. Replace(s,'$FPCTARGET',target_cpu_string);
  400. Replace(s,'$FPCCPU',target_cpu_string);
  401. Replace(s,'$TARGET',target_path);
  402. Replace(s,'$FPCOS',target_path);
  403. end;
  404. {****************************************************************************
  405. File Handling
  406. ****************************************************************************}
  407. function GetCurrentDir:string;
  408. var
  409. CurrentDir : string;
  410. begin
  411. GetDir(0,CurrentDir);
  412. GetCurrentDir:=FixPath(CurrentDir,false);
  413. end;
  414. function path_absolute(const s : string) : boolean;
  415. {
  416. is path s an absolute path?
  417. }
  418. begin
  419. path_absolute:=false;
  420. {$ifdef linux}
  421. if (length(s)>0) and (s[1]='/') then
  422. path_absolute:=true;
  423. {$else linux}
  424. {$ifdef amiga}
  425. if ((length(s)>0) and ((s[1]='\') or (s[1]='/'))) or (Pos(':',s) = length(s)) then
  426. path_absolute:=true;
  427. {$else}
  428. if ((length(s)>0) and ((s[1]='\') or (s[1]='/'))) or
  429. ((length(s)>2) and (s[2]=':') and ((s[3]='\') or (s[3]='/'))) then
  430. path_absolute:=true;
  431. {$endif amiga}
  432. {$endif linux}
  433. end;
  434. {$ifndef FPC}
  435. Procedure FindClose(var Info : SearchRec);
  436. Begin
  437. End;
  438. {$endif not FPC}
  439. Function FileExists ( Const F : String) : Boolean;
  440. {$ifndef delphi}
  441. Var
  442. Info : SearchRec;
  443. {$endif}
  444. begin
  445. {$ifdef delphi}
  446. FileExists:=sysutils.FileExists(f);
  447. {$else}
  448. findfirst(F,readonly+archive+hidden,info);
  449. FileExists:=(doserror=0);
  450. findclose(Info);
  451. {$endif delphi}
  452. end;
  453. Function PathExists ( F : String) : Boolean;
  454. Var
  455. Info : SearchRec;
  456. begin
  457. if F[Length(f)] in ['/','\'] then
  458. Delete(f,length(f),1);
  459. findfirst(F,readonly+archive+hidden+directory,info);
  460. PathExists:=(doserror=0) and ((info.attr and directory)=directory);
  461. findclose(Info);
  462. end;
  463. Function RemoveFile(const f:string):boolean;
  464. var
  465. g : file;
  466. begin
  467. assign(g,f);
  468. {$I-}
  469. erase(g);
  470. {$I+}
  471. RemoveFile:=(ioresult=0);
  472. end;
  473. Function RemoveDir(d:string):boolean;
  474. begin
  475. if d[length(d)]=DirSep then
  476. Delete(d,length(d),1);
  477. {$I-}
  478. rmdir(d);
  479. {$I+}
  480. RemoveDir:=(ioresult=0);
  481. end;
  482. Function SplitPath(const s:string):string;
  483. var
  484. i : longint;
  485. begin
  486. i:=Length(s);
  487. while (i>0) and not(s[i] in ['/','\']) do
  488. dec(i);
  489. SplitPath:=Copy(s,1,i);
  490. end;
  491. Function SplitFileName(const s:string):string;
  492. var
  493. p : dirstr;
  494. n : namestr;
  495. e : extstr;
  496. begin
  497. FSplit(s,p,n,e);
  498. SplitFileName:=n+e;
  499. end;
  500. Function SplitName(const s:string):string;
  501. var
  502. i,j : longint;
  503. begin
  504. i:=Length(s);
  505. j:=Length(s);
  506. while (i>0) and not(s[i] in ['/','\']) do
  507. dec(i);
  508. while (j>0) and (s[j]<>'.') do
  509. dec(j);
  510. if j<=i then
  511. j:=255;
  512. SplitName:=Copy(s,i+1,j-(i+1));
  513. end;
  514. Function SplitExtension(Const HStr:String):String;
  515. var
  516. j : longint;
  517. begin
  518. j:=length(Hstr);
  519. while (j>0) and (Hstr[j]<>'.') do
  520. begin
  521. if hstr[j]=DirSep then
  522. j:=0
  523. else
  524. dec(j);
  525. end;
  526. if j=0 then
  527. j:=254;
  528. SplitExtension:=Copy(Hstr,j,255);
  529. end;
  530. Function AddExtension(Const HStr,ext:String):String;
  531. begin
  532. if (Ext<>'') and (SplitExtension(HStr)='') then
  533. AddExtension:=Hstr+Ext
  534. else
  535. AddExtension:=Hstr;
  536. end;
  537. Function ForceExtension(Const HStr,ext:String):String;
  538. var
  539. j : longint;
  540. begin
  541. j:=length(Hstr);
  542. while (j>0) and (Hstr[j]<>'.') do
  543. dec(j);
  544. if j=0 then
  545. j:=255;
  546. ForceExtension:=Copy(Hstr,1,j-1)+Ext;
  547. end;
  548. Function FixPath(s:string;allowdot:boolean):string;
  549. var
  550. i : longint;
  551. begin
  552. { Fix separator }
  553. for i:=1 to length(s) do
  554. if s[i] in ['/','\'] then
  555. s[i]:=DirSep;
  556. { Fix ending / }
  557. if (length(s)>0) and (s[length(s)]<>DirSep) and
  558. (s[length(s)]<>':') then
  559. s:=s+DirSep;
  560. { Remove ./ }
  561. if (not allowdot) and (s='.'+DirSep) then
  562. s:='';
  563. { return }
  564. {$ifdef linux}
  565. FixPath:=s;
  566. {$else}
  567. FixPath:=Lower(s);
  568. {$endif}
  569. end;
  570. function FixFileName(const s:string):string;
  571. var
  572. i : longint;
  573. {$ifdef Linux}
  574. NoPath : boolean;
  575. {$endif Linux}
  576. begin
  577. {$ifdef Linux}
  578. NoPath:=true;
  579. {$endif Linux}
  580. for i:=length(s) downto 1 do
  581. begin
  582. case s[i] of
  583. {$ifdef Linux}
  584. '/','\' : begin
  585. FixFileName[i]:='/';
  586. NoPath:=false; {Skip lowercasing path: 'X11'<>'x11' }
  587. end;
  588. 'A'..'Z' : if NoPath then
  589. FixFileName[i]:=char(byte(s[i])+32)
  590. else
  591. FixFileName[i]:=s[i];
  592. {$else}
  593. '/' : FixFileName[i]:='\';
  594. 'A'..'Z' : FixFileName[i]:=char(byte(s[i])+32);
  595. {$endif}
  596. else
  597. FixFileName[i]:=s[i];
  598. end;
  599. end;
  600. {$ifndef TP}
  601. {$ifopt H+}
  602. SetLength(FixFileName,length(s));
  603. {$else}
  604. FixFileName[0]:=s[0];
  605. {$endif}
  606. {$else}
  607. FixFileName[0]:=s[0];
  608. {$endif}
  609. end;
  610. procedure SplitBinCmd(const s:string;var bstr,cstr:string);
  611. var
  612. i : longint;
  613. begin
  614. i:=pos(' ',s);
  615. if i>0 then
  616. begin
  617. bstr:=Copy(s,1,i-1);
  618. cstr:=Copy(s,i+1,length(s)-i);
  619. end
  620. else
  621. begin
  622. bstr:='';
  623. cstr:='';
  624. end;
  625. end;
  626. procedure TSearchPathList.AddPath(s:string;addfirst:boolean);
  627. var
  628. j : longint;
  629. hs,hsd,
  630. CurrentDir,
  631. CurrPath : string;
  632. dir : searchrec;
  633. {$IFDEF NEWST}
  634. hp : PStringItem;
  635. {$ELSE}
  636. hp : PStringQueueItem;
  637. {$ENDIF}
  638. procedure addcurrpath;
  639. begin
  640. if addfirst then
  641. begin
  642. Delete(currPath);
  643. Insert(currPath);
  644. end
  645. else
  646. begin
  647. { Check if already in path, then we don't add it }
  648. hp:=Find(currPath);
  649. if not assigned(hp) then
  650. Concat(currPath);
  651. end;
  652. end;
  653. begin
  654. if s='' then
  655. exit;
  656. { Support default macro's }
  657. DefaultReplacements(s);
  658. { get current dir }
  659. CurrentDir:=GetCurrentDir;
  660. repeat
  661. { get currpath }
  662. if addfirst then
  663. begin
  664. j:=length(s);
  665. while (j>0) and (s[j]<>';') do
  666. dec(j);
  667. CurrPath:=FixPath(Copy(s,j+1,length(s)-j),false);
  668. if j=0 then
  669. s:=''
  670. else
  671. System.Delete(s,j,length(s)-j+1);
  672. end
  673. else
  674. begin
  675. j:=Pos(';',s);
  676. if j=0 then
  677. j:=255;
  678. CurrPath:=FixPath(Copy(s,1,j-1),false);
  679. System.Delete(s,1,j);
  680. end;
  681. { fix pathname }
  682. if CurrPath='' then
  683. CurrPath:='.'+DirSep
  684. else
  685. begin
  686. CurrPath:=FixPath(FExpand(CurrPath),false);
  687. if (CurrentDir<>'') and (Copy(CurrPath,1,length(CurrentDir))=CurrentDir) then
  688. CurrPath:='.'+DirSep+Copy(CurrPath,length(CurrentDir)+1,255);
  689. end;
  690. { wildcard adding ? }
  691. if pos('*',currpath)>0 then
  692. begin
  693. if currpath[length(currpath)]=dirsep then
  694. hs:=Copy(currpath,1,length(CurrPath)-1)
  695. else
  696. hs:=currpath;
  697. hsd:=SplitPath(hs);
  698. findfirst(hs,directory,dir);
  699. while doserror=0 do
  700. begin
  701. if (dir.name<>'.') and
  702. (dir.name<>'..') and
  703. ((dir.attr and directory)<>0) then
  704. begin
  705. currpath:=hsd+dir.name+dirsep;
  706. hp:=Find(currPath);
  707. if not assigned(hp) then
  708. AddCurrPath;
  709. end;
  710. findnext(dir);
  711. end;
  712. FindClose(dir);
  713. end
  714. else
  715. begin
  716. if PathExists(currpath) then
  717. addcurrpath;
  718. end;
  719. until (s='');
  720. end;
  721. procedure TSearchPathList.AddList(list:TSearchPathList;addfirst:boolean);
  722. var
  723. s : string;
  724. hl : TSearchPathList;
  725. {$IFDEF NEWST}
  726. hp,hp2 : PStringItem;
  727. {$ELSE}
  728. hp,hp2 : PStringQueueItem;
  729. {$ENDIF}
  730. begin
  731. if list.empty then
  732. exit;
  733. { create temp and reverse the list }
  734. if addfirst then
  735. begin
  736. hl.Init;
  737. hp:=list.first;
  738. while assigned(hp) do
  739. begin
  740. hl.insert(hp^.data^);
  741. hp:=hp^.next;
  742. end;
  743. while not hl.empty do
  744. begin
  745. s:=hl.Get;
  746. Delete(s);
  747. Insert(s);
  748. end;
  749. hl.done;
  750. end
  751. else
  752. begin
  753. hp:=list.first;
  754. while assigned(hp) do
  755. begin
  756. hp2:=Find(hp^.data^);
  757. { Check if already in path, then we don't add it }
  758. if not assigned(hp2) then
  759. Concat(hp^.data^);
  760. hp:=hp^.next;
  761. end;
  762. end;
  763. end;
  764. function TSearchPathList.FindFile(const f : string;var b : boolean) : string;
  765. Var
  766. {$IFDEF NEWST}
  767. p : PStringItem;
  768. {$ELSE}
  769. p : PStringQueueItem;
  770. {$ENDIF}
  771. begin
  772. FindFile:='';
  773. b:=false;
  774. p:=first;
  775. while assigned(p) do
  776. begin
  777. If FileExists(p^.data^+f) then
  778. begin
  779. FindFile:=p^.data^;
  780. b:=true;
  781. exit;
  782. end;
  783. p:=p^.next;
  784. end;
  785. end;
  786. Function GetFileTime ( Var F : File) : Longint;
  787. Var
  788. {$ifdef linux}
  789. Info : Stat;
  790. {$endif}
  791. L : longint;
  792. begin
  793. {$ifdef linux}
  794. FStat (F,Info);
  795. L:=Info.Mtime;
  796. {$else}
  797. GetFTime(f,l);
  798. {$endif}
  799. GetFileTime:=L;
  800. end;
  801. Function GetNamedFileTime (Const F : String) : Longint;
  802. begin
  803. GetNamedFileTime:=do_getnamedfiletime(F);
  804. end;
  805. {Touch Assembler and object time to ppu time is there is a ppufilename}
  806. procedure SynchronizeFileTime(const fn1,fn2:string);
  807. var
  808. f : file;
  809. l : longint;
  810. begin
  811. Assign(f,fn1);
  812. {$I-}
  813. reset(f,1);
  814. {$I+}
  815. if ioresult=0 then
  816. begin
  817. getftime(f,l);
  818. { just to be sure in case there are rounding errors }
  819. setftime(f,l);
  820. close(f);
  821. assign(f,fn2);
  822. {$I-}
  823. reset(f,1);
  824. {$I+}
  825. if ioresult=0 then
  826. begin
  827. setftime(f,l);
  828. close(f);
  829. end;
  830. end;
  831. end;
  832. function FindFile(const f : string;path : string;var b : boolean) : string;
  833. Var
  834. singlepathstring : string;
  835. i : longint;
  836. begin
  837. {$ifdef linux}
  838. for i:=1 to length(path) do
  839. if path[i]=':' then
  840. path[i]:=';';
  841. {$endif}
  842. b:=false;
  843. FindFile:='';
  844. repeat
  845. i:=pos(';',path);
  846. if i=0 then
  847. i:=256;
  848. singlepathstring:=FixPath(copy(path,1,i-1),false);
  849. delete(path,1,i);
  850. If FileExists (singlepathstring+f) then
  851. begin
  852. FindFile:=singlepathstring;
  853. b:=true;
  854. exit;
  855. end;
  856. until path='';
  857. end;
  858. function FindExe(bin:string;var found:boolean):string;
  859. begin
  860. bin:=FixFileName(bin)+source_os.exeext;
  861. {$ifdef delphi}
  862. FindExe:=FindFile(bin,'.;'+exepath+';'+dmisc.getenv('PATH'),found)+bin;
  863. {$else delphi}
  864. FindExe:=FindFile(bin,'.;'+exepath+';'+dos.getenv('PATH'),found)+bin;
  865. {$endif delphi}
  866. end;
  867. function GetShortName(const n:string):string;
  868. {$ifdef win32}
  869. var
  870. hs,hs2 : string;
  871. i : longint;
  872. {$endif}
  873. {$ifdef go32v2}
  874. var
  875. hs : string;
  876. {$endif}
  877. begin
  878. GetShortName:=n;
  879. {$ifdef win32}
  880. hs:=n+#0;
  881. i:=Windows.GetShortPathName(@hs[1],@hs2[1],high(hs2));
  882. if (i>0) and (i<=high(hs2)) then
  883. begin
  884. hs2[0]:=chr(strlen(@hs2[1]));
  885. GetShortName:=hs2;
  886. end;
  887. {$endif}
  888. {$ifdef go32v2}
  889. hs:=n;
  890. if Dos.GetShortName(hs) then
  891. GetShortName:=hs;
  892. {$endif}
  893. end;
  894. {****************************************************************************
  895. OS Dependent things
  896. ****************************************************************************}
  897. function GetEnvPChar(const envname:string):pchar;
  898. {$ifdef win32}
  899. var
  900. s : string;
  901. i,len : longint;
  902. hp,p,p2 : pchar;
  903. {$endif}
  904. begin
  905. {$ifdef linux}
  906. GetEnvPchar:=Linux.Getenv(envname);
  907. {$define GETENVOK}
  908. {$endif}
  909. {$ifdef win32}
  910. GetEnvPchar:=nil;
  911. p:=GetEnvironmentStrings;
  912. hp:=p;
  913. while hp^<>#0 do
  914. begin
  915. s:=strpas(hp);
  916. i:=pos('=',s);
  917. len:=strlen(hp);
  918. if upper(copy(s,1,i-1))=upper(envname) then
  919. begin
  920. GetMem(p2,len-length(envname));
  921. Move(hp[i],p2^,len-length(envname));
  922. GetEnvPchar:=p2;
  923. break;
  924. end;
  925. { next string entry}
  926. hp:=hp+len+1;
  927. end;
  928. FreeEnvironmentStrings(p);
  929. {$define GETENVOK}
  930. {$endif}
  931. {$ifdef GETENVOK}
  932. {$undef GETENVOK}
  933. {$else}
  934. GetEnvPchar:=StrPNew(Dos.Getenv(envname));
  935. {$endif}
  936. end;
  937. procedure FreeEnvPChar(p:pchar);
  938. begin
  939. {$ifndef linux}
  940. StrDispose(p);
  941. {$endif}
  942. end;
  943. Procedure Shell(const command:string);
  944. { This is already defined in the linux.ppu for linux, need for the *
  945. expansion under linux }
  946. {$ifdef linux}
  947. begin
  948. Linux.Shell(command);
  949. end;
  950. {$else}
  951. var
  952. comspec : string;
  953. begin
  954. comspec:=getenv('COMSPEC');
  955. Exec(comspec,' /C '+command);
  956. end;
  957. {$endif}
  958. {****************************************************************************
  959. Init
  960. ****************************************************************************}
  961. procedure get_exepath;
  962. var
  963. hs1 : namestr;
  964. hs2 : extstr;
  965. begin
  966. {$ifdef delphi}
  967. exepath:=dmisc.getenv('PPC_EXEC_PATH');
  968. {$else delphi}
  969. exepath:=dos.getenv('PPC_EXEC_PATH');
  970. {$endif delphi}
  971. if exepath='' then
  972. fsplit(FixFileName(paramstr(0)),exepath,hs1,hs2);
  973. {$ifndef VER0_99_15}
  974. {$ifdef linux}
  975. if exepath='' then
  976. fsearch(hs1,dos.getenv('PATH'));
  977. {$endif}
  978. {$endif}
  979. exepath:=FixPath(exepath,false);
  980. end;
  981. procedure DoneGlobals;
  982. begin
  983. initdefines.done;
  984. if assigned(DLLImageBase) then
  985. StringDispose(DLLImageBase);
  986. RelocSection:=true;
  987. RelocSectionSetExplicitly:=false;
  988. DLLsource:=false;
  989. UseDeffileForExport:=true;
  990. librarysearchpath.Done;
  991. unitsearchpath.Done;
  992. objectsearchpath.Done;
  993. includesearchpath.Done;
  994. end;
  995. procedure InitGlobals;
  996. begin
  997. { set global switches }
  998. do_build:=false;
  999. do_make:=true;
  1000. {$ifdef tp}
  1001. use_big:=false;
  1002. {$endif tp}
  1003. compile_level:=0;
  1004. { Output }
  1005. OutputFile:='';
  1006. OutputExeDir:='';
  1007. OutputUnitDir:='';
  1008. { Utils directory }
  1009. utilsdirectory:='';
  1010. { Search Paths }
  1011. librarysearchpath.Init;
  1012. unitsearchpath.Init;
  1013. includesearchpath.Init;
  1014. objectsearchpath.Init;
  1015. { Def file }
  1016. usewindowapi:=false;
  1017. description:='Compiled by FPC '+version_string+' - '+target_cpu_string;
  1018. dllversion:='';
  1019. { Init values }
  1020. initmodeswitches:=fpcmodeswitches;
  1021. initlocalswitches:=[cs_check_io];
  1022. initmoduleswitches:=[cs_extsyntax,cs_browser];
  1023. initglobalswitches:=[cs_check_unit_name,cs_link_static];
  1024. {$ifdef i386}
  1025. initoptprocessor:=Class386;
  1026. initspecificoptprocessor:=Class386;
  1027. initpackenum:=4;
  1028. {$IFDEF testvarsets}
  1029. initsetalloc:=0;
  1030. {$ENDIF}
  1031. initpackrecords:=packrecord_2;
  1032. initoutputformat:=target_asm.id;
  1033. initasmmode:=asmmode_i386_att;
  1034. {$else not i386}
  1035. {$ifdef m68k}
  1036. initoptprocessor:=MC68000;
  1037. include(initmoduleswitches,cs_fp_emulation);
  1038. initpackenum:=4;
  1039. {$IFDEF testvarsets}
  1040. initsetalloc:=0;
  1041. {$ENDIF}
  1042. initpackrecords:=packrecord_2;
  1043. initoutputformat:=as_m68k_as;
  1044. initasmmode:=asmmode_m68k_mot;
  1045. {$endif m68k}
  1046. {$endif i386}
  1047. initdefines.init;
  1048. { memory sizes, will be overriden by parameter or default for target
  1049. in options or init_parser }
  1050. stacksize:=0;
  1051. heapsize:=0;
  1052. maxheapsize:=0;
  1053. { compile state }
  1054. in_args:=false;
  1055. { must_be_valid:=true; obsolete PM }
  1056. not_unit_proc:=true;
  1057. apptype:=at_cui;
  1058. end;
  1059. begin
  1060. get_exepath;
  1061. {$ifdef EXTDEBUG}
  1062. {$ifdef FPC}
  1063. EntryMemUsed:=system.HeapSize-MemAvail;
  1064. {$endif FPC}
  1065. {$endif}
  1066. end.
  1067. {
  1068. $Log$
  1069. Revision 1.7 2000-08-27 16:11:51 peter
  1070. * moved some util functions from globals,cobjects to cutils
  1071. * splitted files into finput,fmodule
  1072. Revision 1.6 2000/08/12 19:14:58 peter
  1073. * ELF writer works now also with -g
  1074. * ELF writer is default again for linux
  1075. Revision 1.5 2000/08/12 15:30:44 peter
  1076. * IDE patch for stream reading (merged)
  1077. Revision 1.4 2000/08/02 19:49:59 peter
  1078. * first things for default parameters
  1079. Revision 1.3 2000/07/13 12:08:25 michael
  1080. + patched to 1.1.0 with former 1.09patch from peter
  1081. Revision 1.2 2000/07/13 11:32:41 michael
  1082. + removed logs
  1083. }