globals.pas 32 KB

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