options.pas 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl and Peter Vreman
  4. Reads command line options and config files
  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 options;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. globtype,globals,verbose,systems;
  23. type
  24. TOption=class
  25. FirstPass,
  26. NoPressEnter,
  27. DoWriteLogo : boolean;
  28. FileLevel : longint;
  29. QuickInfo : string;
  30. ParaIncludePath,
  31. ParaUnitPath,
  32. ParaObjectPath,
  33. ParaLibraryPath : TSearchPathList;
  34. ParaAlignment : TAlignmentInfo;
  35. Constructor Create;
  36. Destructor Destroy;override;
  37. procedure WriteLogo;
  38. procedure WriteInfo;
  39. procedure WriteHelpPages;
  40. procedure WriteQuickInfo;
  41. procedure IllegalPara(const opt:string);
  42. function Unsetbool(var Opts:string; Pos: Longint):boolean;
  43. procedure interpret_proc_specific_options(const opt:string);virtual;
  44. procedure interpret_option(const opt :string;ispara:boolean);
  45. procedure Interpret_envvar(const envname : string);
  46. procedure Interpret_file(const filename : string);
  47. procedure Read_Parameters;
  48. procedure parsecmd(cmd:string);
  49. procedure TargetDefines(def:boolean);
  50. end;
  51. TOptionClass=class of toption;
  52. var
  53. coption : TOptionClass;
  54. procedure read_arguments(cmd:string);
  55. implementation
  56. uses
  57. {$ifdef Delphi}
  58. dmisc,
  59. {$else Delphi}
  60. dos,
  61. {$endif Delphi}
  62. version,
  63. cutils,cmsgs
  64. {$ifdef BrowserLog}
  65. ,browlog
  66. {$endif BrowserLog}
  67. ;
  68. const
  69. page_size = 24;
  70. var
  71. option : toption;
  72. read_configfile, { read config file, set when a cfgfile is found }
  73. disable_configfile,
  74. target_is_set : boolean; { do not allow contradictory target settings }
  75. asm_is_set : boolean; { -T also change initoutputformat if not set idrectly }
  76. fpcdir,
  77. ppccfg,
  78. ppcaltcfg,
  79. param_file : string; { file to compile specified on the commandline }
  80. {****************************************************************************
  81. Defines
  82. ****************************************************************************}
  83. procedure def_symbol(const s : string);
  84. begin
  85. if s='' then
  86. exit;
  87. initdefines.insert(upper(s));
  88. end;
  89. procedure undef_symbol(const s : string);
  90. begin
  91. if s='' then
  92. exit;
  93. InitDefines.Remove(s);
  94. end;
  95. function check_symbol(const s:string):boolean;
  96. begin
  97. check_symbol:=(initdefines.find(s)<>nil);
  98. end;
  99. procedure set_default_link_type;
  100. begin
  101. if (target_info.target in [target_i386_win32,target_i386_wdosx]) then
  102. begin
  103. def_symbol('FPC_LINK_SMART');
  104. undef_symbol('FPC_LINK_STATIC');
  105. undef_symbol('FPC_LINK_DYNAMIC');
  106. initglobalswitches:=initglobalswitches+[cs_link_smart];
  107. initglobalswitches:=initglobalswitches-[cs_link_shared,cs_link_static];
  108. end
  109. else
  110. begin
  111. undef_symbol('FPC_LINK_SMART');
  112. def_symbol('FPC_LINK_STATIC');
  113. undef_symbol('FPC_LINK_DYNAMIC');
  114. initglobalswitches:=initglobalswitches+[cs_link_static];
  115. initglobalswitches:=initglobalswitches-[cs_link_shared,cs_link_smart];
  116. end;
  117. end;
  118. {****************************************************************************
  119. Toption
  120. ****************************************************************************}
  121. procedure StopOptions;
  122. begin
  123. if assigned(Option) then
  124. begin
  125. Option.free;
  126. Option:=nil;
  127. end;
  128. DoneVerbose;
  129. Stop;
  130. end;
  131. procedure Toption.WriteLogo;
  132. var
  133. p : pchar;
  134. begin
  135. p:=MessagePchar(option_logo);
  136. while assigned(p) do
  137. Comment(V_Normal,GetMsgLine(p));
  138. end;
  139. procedure Toption.WriteInfo;
  140. var
  141. p : pchar;
  142. hs,hs1,s : string;
  143. target : ttarget;
  144. begin
  145. p:=MessagePchar(option_info);
  146. while assigned(p) do
  147. begin
  148. s:=GetMsgLine(p);
  149. { list OS Targets }
  150. if pos('$OSTARGETS',s)>0 then
  151. begin
  152. for target:=low(ttarget) to high(ttarget) do
  153. if assigned(targetinfos[target]) then
  154. begin
  155. hs:=s;
  156. hs1:=targetinfos[target]^.name;
  157. if tf_under_development in targetinfos[target]^.flags then
  158. hs1:=hs1+' (under development)';
  159. Replace(hs,'$OSTARGETS',hs1);
  160. Comment(V_Normal,hs);
  161. end;
  162. end
  163. else
  164. Comment(V_Normal,s);
  165. end;
  166. StopOptions;
  167. end;
  168. procedure Toption.WriteHelpPages;
  169. function PadEnd(s:string;i:longint):string;
  170. begin
  171. while (length(s)<i) do
  172. s:=s+' ';
  173. PadEnd:=s;
  174. end;
  175. var
  176. lastident,
  177. j,outline,
  178. ident,
  179. lines : longint;
  180. show : boolean;
  181. opt : string[32];
  182. input,
  183. s : string;
  184. p : pchar;
  185. begin
  186. WriteLogo;
  187. Lines:=4;
  188. Message1(option_usage,system.paramstr(0));
  189. lastident:=0;
  190. p:=MessagePChar(option_help_pages);
  191. while assigned(p) do
  192. begin
  193. { get a line and reset }
  194. s:=GetMsgLine(p);
  195. ident:=0;
  196. show:=false;
  197. { parse options }
  198. case s[1] of
  199. {$ifdef UNITALIASES}
  200. 'a',
  201. {$endif}
  202. {$ifdef EXTDEBUG}
  203. 'e',
  204. {$endif EXTDEBUG}
  205. {$ifdef i386}
  206. '3',
  207. {$endif}
  208. {$ifdef m68k}
  209. '6',
  210. {$endif}
  211. '*' : show:=true;
  212. end;
  213. if show then
  214. begin
  215. case s[2] of
  216. {$ifdef GDB}
  217. 'g',
  218. {$endif}
  219. {$ifdef Unix}
  220. 'L',
  221. {$endif}
  222. {$ifdef os2}
  223. 'O',
  224. {$endif}
  225. '*' : show:=true;
  226. else
  227. show:=false;
  228. end;
  229. end;
  230. { now we may show the message or not }
  231. if show then
  232. begin
  233. case s[3] of
  234. '0' : begin
  235. ident:=0;
  236. outline:=0;
  237. end;
  238. '1' : begin
  239. ident:=2;
  240. outline:=7;
  241. end;
  242. '2' : begin
  243. ident:=6;
  244. outline:=11;
  245. end;
  246. '3' : begin
  247. ident:=9;
  248. outline:=6;
  249. end;
  250. end;
  251. j:=pos('_',s);
  252. opt:=Copy(s,4,j-4);
  253. if opt='*' then
  254. opt:=''
  255. else
  256. if opt=' ' then
  257. opt:=PadEnd(opt,outline)
  258. else
  259. opt:=PadEnd('-'+opt,outline);
  260. if (ident=0) and (lastident<>0) then
  261. begin
  262. Comment(V_Normal,'');
  263. inc(Lines);
  264. end;
  265. { page full ? }
  266. if (lines >= page_size - 1) then
  267. begin
  268. if not NoPressEnter then
  269. begin
  270. Message(option_help_press_enter);
  271. readln(input);
  272. if upper(input)='Q' then
  273. StopOptions;
  274. end;
  275. lines:=0;
  276. end;
  277. Comment(V_Normal,PadEnd('',ident)+opt+Copy(s,j+1,255));
  278. LastIdent:=Ident;
  279. inc(Lines);
  280. end;
  281. end;
  282. StopOptions;
  283. end;
  284. procedure Toption.IllegalPara(const opt:string);
  285. begin
  286. Message1(option_illegal_para,opt);
  287. Message(option_help_pages_para);
  288. StopOptions;
  289. end;
  290. function Toption.Unsetbool(var Opts:string; Pos: Longint):boolean;
  291. { checks if the character after pos in Opts is a + or a - and returns resp.
  292. false or true. If it is another character (or none), it also returns false }
  293. begin
  294. UnsetBool := false;
  295. if Length(Opts)>Pos then
  296. begin
  297. inc(Pos);
  298. UnsetBool := Opts[Pos] = '-';
  299. if Opts[Pos] in ['-','+']then
  300. delete(Opts,Pos,1);
  301. end;
  302. end;
  303. procedure TOption.interpret_proc_specific_options(const opt:string);
  304. begin
  305. end;
  306. procedure TOption.interpret_option(const opt:string;ispara:boolean);
  307. var
  308. code : integer;
  309. c : char;
  310. more : string;
  311. major,minor : longint;
  312. error : integer;
  313. j,l : longint;
  314. d : DirStr;
  315. e : ExtStr;
  316. forceasm : tasm;
  317. begin
  318. if opt='' then
  319. exit;
  320. { only parse define,undef,target,verbosity and link options the firsttime }
  321. if firstpass and
  322. not((opt[1]='-') and (opt[2] in ['i','d','v','T','u','n','X'])) then
  323. exit;
  324. Message1(option_handling_option,opt);
  325. case opt[1] of
  326. '-' : begin
  327. more:=Copy(opt,3,255);
  328. case opt[2] of
  329. '!' : initlocalswitches:=initlocalswitches+[cs_ansistrings];
  330. '?' : WriteHelpPages;
  331. 'a' : begin
  332. initglobalswitches:=initglobalswitches+[cs_asm_leave];
  333. for j:=1 to length(more) do
  334. case more[j] of
  335. 'l' : include(initglobalswitches,cs_asm_source);
  336. 'r' : include(initglobalswitches,cs_asm_regalloc);
  337. 't' : include(initglobalswitches,cs_asm_tempalloc);
  338. 'n' : include(initglobalswitches,cs_asm_nodes);
  339. '-' : initglobalswitches:=initglobalswitches -
  340. [cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc];
  341. else
  342. IllegalPara(opt);
  343. end;
  344. end;
  345. 'A' : begin
  346. if set_target_asm_by_string(More) then
  347. asm_is_set:=true
  348. else
  349. IllegalPara(opt);
  350. end;
  351. 'b' : begin
  352. if UnsetBool(More,0) then
  353. begin
  354. exclude(initmoduleswitches,cs_browser);
  355. exclude(initmoduleswitches,cs_local_browser);
  356. {$ifdef BrowserLog}
  357. exclude(initglobalswitches,cs_browser_log);
  358. {$endif}
  359. end
  360. else
  361. begin
  362. include(initmoduleswitches,cs_browser);
  363. {$ifdef BrowserLog}
  364. include(initglobalswitches,cs_browser_log);
  365. {$endif}
  366. end;
  367. if More<>'' then
  368. if (More='l') or (More='l+') then
  369. include(initmoduleswitches,cs_local_browser)
  370. else
  371. if More='l-' then
  372. exclude(initmoduleswitches,cs_local_browser)
  373. else
  374. {$ifdef BrowserLog}
  375. browserlog.elements_to_list.insert(more);
  376. {$else}
  377. IllegalPara(opt);
  378. {$endif}
  379. end;
  380. 'B' : do_build:=not UnSetBool(more,0);
  381. 'C' : begin
  382. j := 1;
  383. while j <= length(more) Do
  384. Begin
  385. case more[j] of
  386. 'a' : Message2(option_obsolete_switch_use_new,'-Ca','-Or');
  387. 'c' :
  388. begin
  389. if not SetAktProcCall(upper(copy(more,j+1,length(more)-j)),true) then
  390. IllegalPara(opt);
  391. break;
  392. end;
  393. 'h' :
  394. begin
  395. val(copy(more,j+1,length(more)-j),heapsize,code);
  396. if (code<>0) or (heapsize>=67107840) or (heapsize<1024) then
  397. IllegalPara(opt);
  398. break;
  399. end;
  400. 'i' :
  401. If UnsetBool(More, j) then
  402. exclude(initlocalswitches,cs_check_io)
  403. else
  404. include(initlocalswitches,cs_check_io);
  405. 'n' :
  406. If UnsetBool(More, j) then
  407. exclude(initglobalswitches,cs_link_extern)
  408. Else
  409. include(initglobalswitches,cs_link_extern);
  410. 'o' :
  411. If UnsetBool(More, j) then
  412. exclude(initlocalswitches,cs_check_overflow)
  413. Else
  414. include(initlocalswitches,cs_check_overflow);
  415. 'r' :
  416. If UnsetBool(More, j) then
  417. exclude(initlocalswitches,cs_check_range)
  418. Else
  419. include(initlocalswitches,cs_check_range);
  420. 'R' :
  421. If UnsetBool(More, j) then
  422. begin
  423. exclude(initlocalswitches,cs_check_range);
  424. exclude(initlocalswitches,cs_check_object);
  425. end
  426. Else
  427. begin
  428. include(initlocalswitches,cs_check_range);
  429. include(initlocalswitches,cs_check_object);
  430. end;
  431. 's' :
  432. begin
  433. val(copy(more,j+1,length(more)-j),stacksize,code);
  434. if (code<>0) or (stacksize>=67107840) or (stacksize<1024) then
  435. IllegalPara(opt);
  436. break;
  437. end;
  438. 't' :
  439. If UnsetBool(More, j) then
  440. exclude(initlocalswitches,cs_check_stack)
  441. Else
  442. include(initlocalswitches,cs_check_stack);
  443. 'D' :
  444. If UnsetBool(More, j) then
  445. exclude(initmoduleswitches,cs_create_dynamic)
  446. Else
  447. include(initmoduleswitches,cs_create_dynamic);
  448. 'X' :
  449. If UnsetBool(More, j) then
  450. exclude(initmoduleswitches,cs_create_smart)
  451. Else
  452. include(initmoduleswitches,cs_create_smart);
  453. else
  454. IllegalPara(opt);
  455. end;
  456. inc(j);
  457. end;
  458. end;
  459. 'd' : def_symbol(more);
  460. 'D' : begin
  461. include(initglobalswitches,cs_link_deffile);
  462. for j:=1 to length(more) do
  463. case more[j] of
  464. 'd' : begin
  465. description:=Copy(more,j+1,255);
  466. break;
  467. end;
  468. 'v' : begin
  469. dllversion:=Copy(more,j+1,255);
  470. l:=pos('.',dllversion);
  471. dllminor:=0;
  472. error:=0;
  473. if l>0 then
  474. begin
  475. valint(copy(dllversion,l+1,255),minor,error);
  476. if (error=0) and
  477. (minor>=0) and (minor<=$ffff) then
  478. dllminor:=minor
  479. else if error=0 then
  480. error:=1;
  481. end;
  482. if l=0 then l:=256;
  483. dllmajor:=1;
  484. if error=0 then
  485. valint(copy(dllversion,1,l-1),major,error);
  486. if (error=0) and (major>=0) and (major<=$ffff) then
  487. dllmajor:=major
  488. else if error=0 then
  489. error:=1;
  490. if error<>0 then
  491. Message1(scan_w_wrong_version_ignored,dllversion);
  492. break;
  493. end;
  494. 'w' : usewindowapi:=true;
  495. '-' : begin
  496. exclude(initglobalswitches,cs_link_deffile);
  497. usewindowapi:=false;
  498. end;
  499. else
  500. IllegalPara(opt);
  501. end;
  502. end;
  503. 'e' : exepath:=FixPath(More,true);
  504. { Just used by RHIDE }
  505. 'E' : if UnsetBool(More, 0) then
  506. exclude(initglobalswitches,cs_link_extern)
  507. else
  508. include(initglobalswitches,cs_link_extern);
  509. 'F' : begin
  510. c:=more[1];
  511. Delete(more,1,1);
  512. DefaultReplacements(More);
  513. case c of
  514. 'D' : utilsdirectory:=FixPath(More,true);
  515. 'e' : SetRedirectFile(More);
  516. 'E' : OutputExeDir:=FixPath(More,true);
  517. 'i' : if ispara then
  518. ParaIncludePath.AddPath(More,false)
  519. else
  520. includesearchpath.AddPath(More,true);
  521. 'g' : Message2(option_obsolete_switch_use_new,'-Fg','-Fl');
  522. 'l' : if ispara then
  523. ParaLibraryPath.AddPath(More,false)
  524. else
  525. LibrarySearchPath.AddPath(More,true);
  526. 'L' : if More<>'' then
  527. ParaDynamicLinker:=More
  528. else
  529. IllegalPara(opt);
  530. 'o' : if ispara then
  531. ParaObjectPath.AddPath(More,false)
  532. else
  533. ObjectSearchPath.AddPath(More,true);
  534. 'r' : Msgfilename:=More;
  535. 'u' : if ispara then
  536. ParaUnitPath.AddPath(More,false)
  537. else
  538. unitsearchpath.AddPath(More,true);
  539. 'U' : OutputUnitDir:=FixPath(More,true);
  540. else
  541. IllegalPara(opt);
  542. end;
  543. end;
  544. 'g' : begin
  545. if UnsetBool(More, 0) then
  546. begin
  547. exclude(initmoduleswitches,cs_debuginfo);
  548. exclude(initglobalswitches,cs_gdb_dbx);
  549. exclude(initglobalswitches,cs_gdb_gsym);
  550. exclude(initglobalswitches,cs_gdb_heaptrc);
  551. exclude(initglobalswitches,cs_gdb_lineinfo);
  552. exclude(initglobalswitches,cs_checkpointer);
  553. end
  554. else
  555. begin
  556. {$ifdef GDB}
  557. include(initmoduleswitches,cs_debuginfo);
  558. if not RelocSectionSetExplicitly then
  559. RelocSection:=false;
  560. for j:=1 to length(more) do
  561. case more[j] of
  562. 'd' : if UnsetBool(More, j) then
  563. exclude(initglobalswitches,cs_gdb_dbx)
  564. else
  565. include(initglobalswitches,cs_gdb_dbx);
  566. 'g' : if UnsetBool(More, j) then
  567. exclude(initglobalswitches,cs_gdb_gsym)
  568. else
  569. include(initglobalswitches,cs_gdb_gsym);
  570. 'h' : if UnsetBool(More, j) then
  571. exclude(initglobalswitches,cs_gdb_heaptrc)
  572. else
  573. include(initglobalswitches,cs_gdb_heaptrc);
  574. 'l' : if UnsetBool(More, j) then
  575. exclude(initglobalswitches,cs_gdb_lineinfo)
  576. else
  577. include(initglobalswitches,cs_gdb_lineinfo);
  578. 'c' : if UnsetBool(More, j) then
  579. exclude(initglobalswitches,cs_checkpointer)
  580. else
  581. include(initglobalswitches,cs_checkpointer);
  582. else
  583. IllegalPara(opt);
  584. end;
  585. {$else GDB}
  586. Message(option_no_debug_support);
  587. Message(option_no_debug_support_recompile_fpc);
  588. {$endif GDB}
  589. end;
  590. end;
  591. 'h' : begin
  592. NoPressEnter:=true;
  593. WriteHelpPages;
  594. end;
  595. 'i' : if More='' then
  596. WriteInfo
  597. else
  598. QuickInfo:=QuickInfo+More;
  599. 'I' : if ispara then
  600. ParaIncludePath.AddPath(More,false)
  601. else
  602. includesearchpath.AddPath(More,false);
  603. 'k' : if more<>'' then
  604. ParaLinkOptions:=ParaLinkOptions+' '+More
  605. else
  606. IllegalPara(opt);
  607. 'l' : DoWriteLogo:=not UnSetBool(more,0);
  608. 'm' : parapreprocess:=not UnSetBool(more,0);
  609. 'n' : if More='' then
  610. begin
  611. read_configfile:=false;
  612. disable_configfile:=true;
  613. end
  614. else
  615. IllegalPara(opt);
  616. 'o' : if More<>'' then
  617. Fsplit(More,d,OutputFile,e)
  618. else
  619. IllegalPara(opt);
  620. 'p' : begin
  621. if UnsetBool(More, 0) then
  622. begin
  623. initmoduleswitches:=initmoduleswitches-[cs_profile];
  624. undef_symbol('FPC_PROFILE');
  625. end
  626. else
  627. if Length(More)=0 then
  628. IllegalPara(opt)
  629. else
  630. case more[1] of
  631. 'g' : if UnsetBool(more, 1) then
  632. begin
  633. exclude(initmoduleswitches,cs_profile);
  634. undef_symbol('FPC_PROFILE');
  635. end
  636. else
  637. begin
  638. include(initmoduleswitches,cs_profile);
  639. def_symbol('FPC_PROFILE');
  640. end;
  641. else
  642. IllegalPara(opt);
  643. end;
  644. end;
  645. {$ifdef Unix}
  646. 'P' : if UnsetBool(More, 0) then
  647. exclude(initglobalswitches,cs_asm_pipe)
  648. else
  649. include(initglobalswitches,cs_asm_pipe);
  650. {$endif Unix}
  651. 's' :
  652. begin
  653. if UnsetBool(More, 0) then
  654. begin
  655. initglobalswitches:=initglobalswitches-[cs_asm_extern,cs_link_extern];
  656. if more<>'' then
  657. IllegalPara(opt);
  658. end
  659. else
  660. begin
  661. initglobalswitches:=initglobalswitches+[cs_asm_extern,cs_link_extern];
  662. if more='h' then
  663. initglobalswitches:=initglobalswitches-[cs_link_on_target]
  664. else if more='t' then
  665. initglobalswitches:=initglobalswitches+[cs_link_on_target]
  666. else if more<>'' then
  667. IllegalPara(opt);
  668. end;
  669. end;
  670. 'S' : begin
  671. if more[1]='I' then
  672. begin
  673. if upper(more)='ICOM' then
  674. initinterfacetype:=it_interfacecom
  675. else if upper(more)='ICORBA' then
  676. initinterfacetype:=it_interfacecorba
  677. else
  678. IllegalPara(opt);
  679. end
  680. else
  681. for j:=1 to length(more) do
  682. case more[j] of
  683. '2' : SetCompileMode('OBJFPC',true);
  684. 'a' : include(initlocalswitches,cs_do_assertion);
  685. 'c' : include(initmoduleswitches,cs_support_c_operators);
  686. 'd' : SetCompileMode('DELPHI',true);
  687. 'e' : begin
  688. SetErrorFlags(copy(more,j+1,length(more)));
  689. break;
  690. end;
  691. 'g' : include(initmoduleswitches,cs_support_goto);
  692. 'h' : include(initlocalswitches,cs_ansistrings);
  693. 'i' : include(initmoduleswitches,cs_support_inline);
  694. 'm' : include(initmoduleswitches,cs_support_macro);
  695. 'o' : SetCompileMode('TP',true);
  696. 'p' : SetCompileMode('GPC',true);
  697. 's' : include(initglobalswitches,cs_constructor_name);
  698. 't' : include(initmoduleswitches,cs_static_keyword);
  699. '-' : begin
  700. exclude(initglobalswitches,cs_constructor_name);
  701. initlocalswitches:=InitLocalswitches - [cs_do_assertion, cs_ansistrings];
  702. initmoduleswitches:=initmoduleswitches - [cs_support_c_operators, cs_support_goto,
  703. cs_support_inline, cs_support_macro,
  704. cs_static_keyword];
  705. end;
  706. else
  707. IllegalPara(opt);
  708. end;
  709. end;
  710. 'T' : begin
  711. more:=Upper(More);
  712. if not target_is_set then
  713. begin
  714. { remove old target define }
  715. TargetDefines(false);
  716. { Save assembler if set }
  717. if asm_is_set then
  718. forceasm:=target_asm.id;
  719. { load new target }
  720. if not(set_target_by_string(More)) then
  721. IllegalPara(opt);
  722. { also initialize assembler if not explicitly set }
  723. if asm_is_set then
  724. set_target_asm(forceasm);
  725. { set new define }
  726. TargetDefines(true);
  727. target_is_set:=true;
  728. end
  729. else
  730. if More<>upper(target_info.shortname) then
  731. Message1(option_target_is_already_set,target_info.shortname);
  732. end;
  733. 'u' : undef_symbol(upper(More));
  734. 'U' : begin
  735. for j:=1 to length(more) do
  736. case more[j] of
  737. {$ifdef UNITALIASES}
  738. 'a' : begin
  739. AddUnitAlias(Copy(More,j+1,255));
  740. break;
  741. end;
  742. {$endif UNITALIASES}
  743. 'n' : exclude(initglobalswitches,cs_check_unit_name);
  744. 'p' : begin
  745. Message2(option_obsolete_switch_use_new,'-Up','-Fu');
  746. break;
  747. end;
  748. 'r' : do_release:=true;
  749. 's' : include(initmoduleswitches,cs_compilesystem);
  750. '-' : begin
  751. exclude(initmoduleswitches,cs_compilesystem);
  752. exclude(initglobalswitches,cs_check_unit_name);
  753. end;
  754. else
  755. IllegalPara(opt);
  756. end;
  757. end;
  758. 'v' : if not setverbosity(More) then
  759. IllegalPara(opt);
  760. 'W' : begin
  761. j:=0;
  762. while j<length(More) do
  763. begin
  764. inc(j);
  765. case More[j] of
  766. 'B': begin
  767. { -WB200000 means set trefered base address
  768. to $200000, but does not change relocsection boolean
  769. this way we can create both relocatble and
  770. non relocatable DLL at a specific base address PM }
  771. if (length(More)>j) then
  772. begin
  773. if DLLImageBase=nil then
  774. DLLImageBase:=StringDup(Copy(More,j+1,255));
  775. end
  776. else
  777. begin
  778. RelocSection:=true;
  779. RelocSectionSetExplicitly:=true;
  780. end;
  781. break;
  782. end;
  783. 'C': if UnsetBool(More, j) then
  784. apptype:=app_gui
  785. else
  786. apptype:=app_cui;
  787. 'D': ForceDeffileForExport:=not UnsetBool(More, j);
  788. 'F': apptype:=app_fs;
  789. 'G': if UnsetBool(More, j) then
  790. apptype:=app_cui
  791. else
  792. apptype:=app_gui;
  793. 'N': begin
  794. RelocSection:=UnsetBool(More,j);
  795. RelocSectionSetExplicitly:=true;
  796. end;
  797. 'R': begin
  798. { support -WR+ / -WR- as synonims to -WR / -WN }
  799. RelocSection:=not UnsetBool(More,j);
  800. RelocSectionSetExplicitly:=true;
  801. end;
  802. else
  803. IllegalPara(opt);
  804. end;
  805. end; {of while}
  806. end;
  807. 'X' : begin
  808. for j:=1 to length(More) do
  809. case More[j] of
  810. 's' : include(initglobalswitches,cs_link_strip);
  811. 't' : include(initglobalswitches,cs_link_staticflag);
  812. 'D' : begin
  813. def_symbol('FPC_LINK_DYNAMIC');
  814. undef_symbol('FPC_LINK_SMART');
  815. undef_symbol('FPC_LINK_STATIC');
  816. exclude(initglobalswitches,cs_link_static);
  817. exclude(initglobalswitches,cs_link_smart);
  818. include(initglobalswitches,cs_link_shared);
  819. LinkTypeSetExplicitly:=true;
  820. end;
  821. 'S' : begin
  822. def_symbol('FPC_LINK_STATIC');
  823. undef_symbol('FPC_LINK_SMART');
  824. undef_symbol('FPC_LINK_DYNAMIC');
  825. include(initglobalswitches,cs_link_static);
  826. exclude(initglobalswitches,cs_link_smart);
  827. exclude(initglobalswitches,cs_link_shared);
  828. LinkTypeSetExplicitly:=true;
  829. end;
  830. 'X' : begin
  831. def_symbol('FPC_LINK_SMART');
  832. undef_symbol('FPC_LINK_STATIC');
  833. undef_symbol('FPC_LINK_DYNAMIC');
  834. exclude(initglobalswitches,cs_link_static);
  835. include(initglobalswitches,cs_link_smart);
  836. exclude(initglobalswitches,cs_link_shared);
  837. LinkTypeSetExplicitly:=true;
  838. end;
  839. '-' : begin
  840. exclude(initglobalswitches,cs_link_staticflag);
  841. exclude(initglobalswitches,cs_link_strip);
  842. set_default_link_type;
  843. end;
  844. else
  845. IllegalPara(opt);
  846. end;
  847. end;
  848. { give processor specific options a chance }
  849. else
  850. interpret_proc_specific_options(opt);
  851. end;
  852. end;
  853. '@' : begin
  854. Message(option_no_nested_response_file);
  855. StopOptions;
  856. end;
  857. else
  858. begin
  859. if (length(param_file)<>0) then
  860. Message(option_only_one_source_support);
  861. param_file:=opt;
  862. end;
  863. end;
  864. end;
  865. procedure Toption.Interpret_file(const filename : string);
  866. procedure RemoveSep(var fn:string);
  867. var
  868. i : longint;
  869. begin
  870. i:=0;
  871. while (i<length(fn)) and (fn[i+1] in [',',' ',#9]) do
  872. inc(i);
  873. Delete(fn,1,i);
  874. i:=length(fn);
  875. while (i>0) and (fn[i] in [',',' ',#9]) do
  876. dec(i);
  877. fn:=copy(fn,1,i);
  878. end;
  879. function GetName(var fn:string):string;
  880. var
  881. i : longint;
  882. begin
  883. i:=0;
  884. while (i<length(fn)) and (fn[i+1] in ['a'..'z','A'..'Z','0'..'9','_','-']) do
  885. inc(i);
  886. GetName:=Copy(fn,1,i);
  887. Delete(fn,1,i);
  888. end;
  889. const
  890. maxlevel=16;
  891. var
  892. f : text;
  893. s,
  894. opts : string;
  895. skip : array[0..maxlevel-1] of boolean;
  896. level : longint;
  897. option_read : boolean;
  898. begin
  899. { avoid infinite loop }
  900. Inc(FileLevel);
  901. Option_read:=false;
  902. If FileLevel>MaxLevel then
  903. Message(option_too_many_cfg_files);
  904. { open file }
  905. Message1(option_using_file,filename);
  906. assign(f,filename);
  907. {$I-}
  908. reset(f);
  909. {$I+}
  910. if ioresult<>0 then
  911. begin
  912. Message1(option_unable_open_file,filename);
  913. exit;
  914. end;
  915. fillchar(skip,sizeof(skip),0);
  916. level:=0;
  917. while not eof(f) do
  918. begin
  919. readln(f,opts);
  920. RemoveSep(opts);
  921. if (opts<>'') and (opts[1]<>';') then
  922. begin
  923. if opts[1]='#' then
  924. begin
  925. Delete(opts,1,1);
  926. s:=upper(GetName(opts));
  927. if (s='SECTION') then
  928. begin
  929. RemoveSep(opts);
  930. s:=upper(GetName(opts));
  931. if level=0 then
  932. skip[level]:=not (check_symbol(s) or (s='COMMON'));
  933. end
  934. else
  935. if (s='IFDEF') then
  936. begin
  937. RemoveSep(opts);
  938. if Level>=maxlevel then
  939. begin
  940. Message(option_too_many_ifdef);
  941. stopOptions;
  942. end;
  943. inc(Level);
  944. skip[level]:=(skip[level-1] or (not check_symbol(upper(GetName(opts)))));
  945. end
  946. else
  947. if (s='IFNDEF') then
  948. begin
  949. RemoveSep(opts);
  950. if Level>=maxlevel then
  951. begin
  952. Message(option_too_many_ifdef);
  953. stopOptions;
  954. end;
  955. inc(Level);
  956. skip[level]:=(skip[level-1] or (check_symbol(upper(GetName(opts)))));
  957. end
  958. else
  959. if (s='ELSE') then
  960. skip[level]:=skip[level-1] or (not skip[level])
  961. else
  962. if (s='ENDIF') then
  963. begin
  964. skip[level]:=false;
  965. if Level=0 then
  966. begin
  967. Message(option_too_many_endif);
  968. stopOptions;
  969. end;
  970. dec(level);
  971. end
  972. else
  973. if (not skip[level]) then
  974. begin
  975. if (s='DEFINE') then
  976. begin
  977. RemoveSep(opts);
  978. def_symbol(upper(GetName(opts)));
  979. end
  980. else
  981. if (s='UNDEF') then
  982. begin
  983. RemoveSep(opts);
  984. undef_symbol(upper(GetName(opts)));
  985. end
  986. else
  987. if (s='WRITE') then
  988. begin
  989. Delete(opts,1,1);
  990. WriteLn(opts);
  991. end
  992. else
  993. if (s='INCLUDE') then
  994. begin
  995. Delete(opts,1,1);
  996. Interpret_file(opts);
  997. end;
  998. end;
  999. end
  1000. else
  1001. begin
  1002. if (opts[1]='-') or (opts[1]='@') then
  1003. begin
  1004. if (not skip[level]) then
  1005. interpret_option(opts,false);
  1006. Option_read:=true;
  1007. end
  1008. else
  1009. Message1(option_illegal_para,opts);
  1010. end;
  1011. end;
  1012. end;
  1013. if Level>0 then
  1014. Message(option_too_less_endif);
  1015. if Not Option_read then
  1016. Message1(option_no_option_found,filename);
  1017. Close(f);
  1018. Dec(FileLevel);
  1019. end;
  1020. procedure Toption.Interpret_envvar(const envname : string);
  1021. var
  1022. argstart,
  1023. env,
  1024. pc : pchar;
  1025. arglen : longint;
  1026. quote : set of char;
  1027. hs : string;
  1028. begin
  1029. Message1(option_using_env,envname);
  1030. env:=GetEnvPChar(envname);
  1031. pc:=env;
  1032. if assigned(pc) then
  1033. begin
  1034. repeat
  1035. { skip leading spaces }
  1036. while pc^ in [' ',#9,#13] do
  1037. inc(pc);
  1038. case pc^ of
  1039. #0 :
  1040. break;
  1041. '"' :
  1042. begin
  1043. quote:=['"'];
  1044. inc(pc);
  1045. end;
  1046. '''' :
  1047. begin
  1048. quote:=[''''];
  1049. inc(pc);
  1050. end;
  1051. else
  1052. quote:=[' ',#9,#13];
  1053. end;
  1054. { scan until the end of the argument }
  1055. argstart:=pc;
  1056. while (pc^<>#0) and not(pc^ in quote) do
  1057. inc(pc);
  1058. { create argument }
  1059. arglen:=pc-argstart;
  1060. hs[0]:=chr(arglen);
  1061. move(argstart^,hs[1],arglen);
  1062. interpret_option(hs,true);
  1063. { skip quote }
  1064. if pc^ in quote then
  1065. inc(pc);
  1066. until false;
  1067. end
  1068. else
  1069. Message1(option_no_option_found,'(env) '+envname);
  1070. FreeEnvPChar(env);
  1071. end;
  1072. procedure toption.read_parameters;
  1073. var
  1074. opts : string;
  1075. paramindex : longint;
  1076. begin
  1077. paramindex:=0;
  1078. while paramindex<paramcount do
  1079. begin
  1080. inc(paramindex);
  1081. opts:=system.paramstr(paramindex);
  1082. case opts[1] of
  1083. '@' :
  1084. if not firstpass then
  1085. begin
  1086. Delete(opts,1,1);
  1087. Message1(option_reading_further_from,opts);
  1088. interpret_file(opts);
  1089. end;
  1090. '!' :
  1091. if not firstpass then
  1092. begin
  1093. Delete(opts,1,1);
  1094. Message1(option_reading_further_from,'(env) '+opts);
  1095. interpret_envvar(opts);
  1096. end;
  1097. else
  1098. interpret_option(opts,true);
  1099. end;
  1100. end;
  1101. end;
  1102. procedure toption.parsecmd(cmd:string);
  1103. var
  1104. i,ps : longint;
  1105. opts : string;
  1106. begin
  1107. while (cmd<>'') do
  1108. begin
  1109. while cmd[1]=' ' do
  1110. delete(cmd,1,1);
  1111. i:=pos(' ',cmd);
  1112. if i=0 then
  1113. i:=256;
  1114. opts:=Copy(cmd,1,i-1);
  1115. Delete(cmd,1,i);
  1116. case opts[1] of
  1117. '@' :
  1118. if not firstpass then
  1119. begin
  1120. Delete(opts,1,1);
  1121. Message1(option_reading_further_from,opts);
  1122. interpret_file(opts);
  1123. end;
  1124. '!' :
  1125. if not firstpass then
  1126. begin
  1127. Delete(opts,1,1);
  1128. Message1(option_reading_further_from,'(env) '+opts);
  1129. interpret_envvar(opts);
  1130. end;
  1131. '"' :
  1132. begin
  1133. Delete(opts,1,1);
  1134. ps:=pos('"',cmd);
  1135. if (i<>256) and (ps>0) then
  1136. begin
  1137. opts:=opts + ' '+ copy(cmd,1,ps-1);
  1138. cmd:=copy(cmd,ps+1,255);
  1139. end;
  1140. interpret_option(opts,true);
  1141. end;
  1142. else
  1143. interpret_option(opts,true);
  1144. end;
  1145. end;
  1146. end;
  1147. procedure toption.writequickinfo;
  1148. var
  1149. s : string;
  1150. i : longint;
  1151. procedure addinfo(const hs:string);
  1152. begin
  1153. if s<>'' then
  1154. s:=s+' '+hs
  1155. else
  1156. s:=hs;
  1157. end;
  1158. begin
  1159. s:='';
  1160. i:=0;
  1161. while (i<length(quickinfo)) do
  1162. begin
  1163. inc(i);
  1164. case quickinfo[i] of
  1165. 'S' :
  1166. begin
  1167. inc(i);
  1168. case quickinfo[i] of
  1169. 'O' :
  1170. addinfo(lower(source_info.shortname));
  1171. {$ifdef Delphi}
  1172. 'P' :
  1173. addinfo('i386');
  1174. {$else Delphi}
  1175. 'P' :
  1176. addinfo(source_cpu_string);
  1177. {$endif Delphi}
  1178. else
  1179. IllegalPara('-iS'+QuickInfo);
  1180. end;
  1181. end;
  1182. 'T' :
  1183. begin
  1184. inc(i);
  1185. case quickinfo[i] of
  1186. 'O' :
  1187. addinfo(lower(target_info.shortname));
  1188. 'P' :
  1189. AddInfo(target_cpu_string);
  1190. else
  1191. IllegalPara('-iT'+QuickInfo);
  1192. end;
  1193. end;
  1194. 'V' :
  1195. AddInfo(version_string);
  1196. 'D' :
  1197. AddInfo(date_string);
  1198. '_' :
  1199. ;
  1200. else
  1201. IllegalPara('-i'+QuickInfo);
  1202. end;
  1203. end;
  1204. if s<>'' then
  1205. begin
  1206. writeln(s);
  1207. stopoptions;
  1208. end;
  1209. end;
  1210. procedure TOption.TargetDefines(def:boolean);
  1211. var
  1212. s : string;
  1213. i : integer;
  1214. begin
  1215. if def then
  1216. def_symbol(upper(target_info.shortname))
  1217. else
  1218. undef_symbol(upper(target_info.shortname));
  1219. s:=target_info.extradefines;
  1220. while (s<>'') do
  1221. begin
  1222. i:=pos(';',s);
  1223. if i=0 then
  1224. i:=length(s)+1;
  1225. if def then
  1226. def_symbol(Copy(s,1,i-1))
  1227. else
  1228. undef_symbol(Copy(s,1,i-1));
  1229. delete(s,1,i);
  1230. end;
  1231. end;
  1232. constructor TOption.create;
  1233. begin
  1234. DoWriteLogo:=false;
  1235. NoPressEnter:=false;
  1236. FirstPass:=false;
  1237. FileLevel:=0;
  1238. Quickinfo:='';
  1239. ParaIncludePath:=TSearchPathList.Create;
  1240. ParaObjectPath:=TSearchPathList.Create;
  1241. ParaUnitPath:=TSearchPathList.Create;
  1242. ParaLibraryPath:=TSearchPathList.Create;
  1243. FillChar(ParaAlignment,sizeof(ParaAlignment),0);
  1244. end;
  1245. destructor TOption.destroy;
  1246. begin
  1247. ParaIncludePath.Free;
  1248. ParaObjectPath.Free;
  1249. ParaUnitPath.Free;
  1250. ParaLibraryPath.Free;
  1251. end;
  1252. {****************************************************************************
  1253. Callable Routines
  1254. ****************************************************************************}
  1255. procedure read_arguments(cmd:string);
  1256. var
  1257. configpath : pathstr;
  1258. begin
  1259. option:=coption.create;
  1260. disable_configfile:=false;
  1261. { default defines }
  1262. def_symbol(upper(target_info.shortname));
  1263. def_symbol('FPC');
  1264. def_symbol('VER'+version_nr);
  1265. def_symbol('VER'+version_nr+'_'+release_nr);
  1266. def_symbol('VER'+version_nr+'_'+release_nr+'_'+patch_nr);
  1267. {$ifdef newcg}
  1268. def_symbol('WITHNEWCG');
  1269. {$endif}
  1270. { Temporary defines, until things settle down }
  1271. def_symbol('HASWIDECHAR');
  1272. def_symbol('HASWIDESTRING');
  1273. def_symbol('HASOUT');
  1274. def_symbol('HASINTF');
  1275. def_symbol('HASVARIANT');
  1276. def_symbol('INTERNSETLENGTH');
  1277. def_symbol('INTERNLENGTH');
  1278. def_symbol('INT64FUNCRESOK');
  1279. def_symbol('HAS_ADDR_STACK_ON_STACK');
  1280. def_symbol('NOBOUNDCHECK');
  1281. def_symbol('HASCOMPILERPROC');
  1282. def_symbol('VALUEGETMEM');
  1283. def_symbol('VALUEFREEMEM');
  1284. { some stuff for TP compatibility }
  1285. case target_info.cpu of
  1286. cpu_i386:
  1287. begin
  1288. def_symbol('CPU86');
  1289. def_symbol('CPU87');
  1290. def_symbol('CPUI386');
  1291. end;
  1292. cpu_m68k:
  1293. begin
  1294. def_symbol('CPU68');
  1295. def_symbol('CPU68K');
  1296. end;
  1297. cpu_alpha:
  1298. begin
  1299. def_symbol('CPUALPHA');
  1300. end;
  1301. cpu_powerpc:
  1302. begin
  1303. def_symbol('CPUPOWERPC');
  1304. end;
  1305. cpu_sparc:
  1306. begin
  1307. def_symbol('CPUSPARC');
  1308. end;
  1309. cpu_vm:
  1310. begin
  1311. def_symbol('CPUVIS');
  1312. end;
  1313. else
  1314. internalerror(1295969);
  1315. end;
  1316. { get default messagefile }
  1317. {$ifdef Delphi}
  1318. msgfilename:=dmisc.getenv('PPC_ERROR_FILE');
  1319. {$else Delphi}
  1320. msgfilename:=dos.getenv('PPC_ERROR_FILE');
  1321. {$endif Delphi}
  1322. { default configfile }
  1323. if (cmd<>'') and (cmd[1]='[') then
  1324. begin
  1325. ppccfg:=Copy(cmd,2,pos(']',cmd)-2);
  1326. Delete(cmd,1,pos(']',cmd));
  1327. end
  1328. else
  1329. begin
  1330. ppcaltcfg:='ppc386.cfg';
  1331. ppccfg:='fpc.cfg';
  1332. end;
  1333. { Order to read configuration file :
  1334. try reading ppc386.cfg in :
  1335. 1 - current dir
  1336. 2 - configpath
  1337. 3 - compiler path
  1338. else try reading fpc.cfg in :
  1339. 1 - current dir
  1340. 2 - configpath
  1341. 3 - compiler path
  1342. }
  1343. {$ifdef Delphi}
  1344. configpath:=FixPath(dmisc.getenv('PPC_CONFIG_PATH'),false);
  1345. {$else Delphi}
  1346. configpath:=FixPath(dos.getenv('PPC_CONFIG_PATH'),false);
  1347. {$endif Delphi}
  1348. {$ifdef Unix}
  1349. if configpath='' then
  1350. configpath:='/etc/';
  1351. {$endif}
  1352. if ppccfg<>'' then
  1353. begin
  1354. read_configfile:=true;
  1355. if not FileExists(ppcaltcfg) then
  1356. begin
  1357. {$ifdef Unix}
  1358. if (dos.getenv('HOME')<>'') and FileExists(FixPath(dos.getenv('HOME'),false)+'.'+ppcaltcfg) then
  1359. ppccfg:=FixPath(dos.getenv('HOME'),false)+'.'+ppcaltcfg
  1360. else
  1361. {$endif}
  1362. if FileExists(configpath+ppcaltcfg) then
  1363. ppccfg:=configpath+ppcaltcfg
  1364. else
  1365. {$ifndef Unix}
  1366. if FileExists(exepath+ppcaltcfg) then
  1367. ppccfg:=exepath+ppcaltcfg
  1368. else
  1369. {$endif}
  1370. read_configfile:=false;
  1371. end
  1372. else
  1373. ppccfg := ppcaltcfg; { file is found, then set it to ppccfg }
  1374. if not read_configfile then
  1375. begin
  1376. read_configfile := true;
  1377. if not FileExists(ppccfg) then
  1378. begin
  1379. {$ifdef Unix}
  1380. if (dos.getenv('HOME')<>'') and FileExists(FixPath(dos.getenv('HOME'),false)+'.'+ppccfg) then
  1381. ppccfg:=FixPath(dos.getenv('HOME'),false)+'.'+ppccfg
  1382. else
  1383. {$endif}
  1384. if FileExists(configpath+ppccfg) then
  1385. ppccfg:=configpath+ppccfg
  1386. else
  1387. {$ifndef Unix}
  1388. if FileExists(exepath+ppccfg) then
  1389. ppccfg:=exepath+ppccfg
  1390. else
  1391. {$endif}
  1392. read_configfile:=false;
  1393. end;
  1394. end
  1395. end
  1396. else
  1397. read_configfile := false;
  1398. { Read commandline and configfile }
  1399. target_is_set:=false;
  1400. asm_is_set:=false;
  1401. param_file:='';
  1402. if read_configfile then
  1403. begin
  1404. { read the parameters quick, only -i -v -T }
  1405. option.firstpass:=true;
  1406. if cmd<>'' then
  1407. option.parsecmd(cmd)
  1408. else
  1409. begin
  1410. option.read_parameters;
  1411. { Write only quickinfo }
  1412. if option.quickinfo<>'' then
  1413. option.writequickinfo;
  1414. end;
  1415. { Read the configfile }
  1416. option.firstpass:=false;
  1417. if read_configfile then
  1418. option.interpret_file(ppccfg);
  1419. end;
  1420. if cmd<>'' then
  1421. option.parsecmd(cmd)
  1422. else
  1423. begin
  1424. option.read_parameters;
  1425. { Write only quickinfo }
  1426. if option.quickinfo<>'' then
  1427. option.writequickinfo;
  1428. end;
  1429. { Write help pages }
  1430. if (cmd='') and (paramcount=0) then
  1431. Option.WriteHelpPages;
  1432. { Stop if errors in options }
  1433. if ErrorCount>0 then
  1434. StopOptions;
  1435. { Non-core target defines }
  1436. Option.TargetDefines(true);
  1437. { endian define }
  1438. case target_info.endian of
  1439. endian_little :
  1440. def_symbol('ENDIAN_LITTLE');
  1441. endian_big :
  1442. def_symbol('ENDIAN_BIG');
  1443. end;
  1444. {$ifdef m68k}
  1445. { Disable fpu emulation for linux and netbsd on m68k machines }
  1446. { FIXME: this overrides possible explicit command line emulation setting,
  1447. but this isn't supported yet anyhow PM }
  1448. if (target_info.target in [target_m68k_netbsd,target_m68k_linux]) then
  1449. exclude(initmoduleswitches,cs_fp_emulation)
  1450. else
  1451. def_symbol('M68K_FPU_EMULATED');
  1452. {$endif m68k}
  1453. { write logo if set }
  1454. if option.DoWriteLogo then
  1455. option.WriteLogo;
  1456. { Check file to compile }
  1457. if param_file='' then
  1458. begin
  1459. Message(option_no_source_found);
  1460. StopOptions;
  1461. end;
  1462. {$ifndef Unix}
  1463. param_file:=FixFileName(param_file);
  1464. {$endif}
  1465. fsplit(param_file,inputdir,inputfile,inputextension);
  1466. if inputextension='' then
  1467. begin
  1468. if FileExists(inputdir+inputfile+target_info.sourceext) then
  1469. inputextension:=target_info.sourceext
  1470. else
  1471. if FileExists(inputdir+inputfile+target_info.pasext) then
  1472. inputextension:=target_info.pasext;
  1473. end;
  1474. { Add paths specified with parameters to the searchpaths }
  1475. UnitSearchPath.AddList(option.ParaUnitPath,true);
  1476. ObjectSearchPath.AddList(option.ParaObjectPath,true);
  1477. IncludeSearchPath.AddList(option.ParaIncludePath,true);
  1478. LibrarySearchPath.AddList(option.ParaLibraryPath,true);
  1479. { add unit environment and exepath to the unit search path }
  1480. if inputdir<>'' then
  1481. Unitsearchpath.AddPath(inputdir,true);
  1482. if not disable_configfile then
  1483. {$ifdef Delphi}
  1484. UnitSearchPath.AddPath(dmisc.getenv(target_info.unit_env),false);
  1485. {$else}
  1486. UnitSearchPath.AddPath(dos.getenv(target_info.unit_env),false);
  1487. {$endif Delphi}
  1488. {$ifdef Unix}
  1489. fpcdir:=FixPath(getenv('FPCDIR'),false);
  1490. if fpcdir='' then
  1491. begin
  1492. if PathExists('/usr/local/lib/fpc/'+version_string) then
  1493. fpcdir:='/usr/local/lib/fpc/'+version_string+'/'
  1494. else
  1495. fpcdir:='/usr/lib/fpc/'+version_string+'/';
  1496. end;
  1497. {$else}
  1498. fpcdir:=FixPath(getenv('FPCDIR'),false);
  1499. if fpcdir='' then
  1500. begin
  1501. fpcdir:=ExePath+'../';
  1502. if not(PathExists(fpcdir+'/units')) and
  1503. not(PathExists(fpcdir+'/rtl')) then
  1504. fpcdir:=fpcdir+'../';
  1505. end;
  1506. {$endif}
  1507. { first try development RTL, else use the default installation path }
  1508. if not disable_configfile then
  1509. begin
  1510. if PathExists(FpcDir+'rtl/'+lower(target_info.shortname)) then
  1511. UnitSearchPath.AddPath(FpcDir+'rtl/'+lower(target_info.shortname),false)
  1512. else
  1513. begin
  1514. UnitSearchPath.AddPath(FpcDir+'units/'+lower(target_info.shortname),false);
  1515. UnitSearchPath.AddPath(FpcDir+'units/'+lower(target_info.shortname)+'/rtl',false);
  1516. end;
  1517. end;
  1518. { Add exepath if the exe is not in the current dir, because that is always searched already }
  1519. if ExePath<>GetCurrentDir then
  1520. UnitSearchPath.AddPath(ExePath,false);
  1521. { Add unit dir to the object and library path }
  1522. objectsearchpath.AddList(unitsearchpath,false);
  1523. librarysearchpath.AddList(unitsearchpath,false);
  1524. { switch assembler if it's binary and we got -a on the cmdline }
  1525. if (cs_asm_leave in initglobalswitches) and
  1526. (target_asm.outputbinary) then
  1527. begin
  1528. Message(option_switch_bin_to_src_assembler);
  1529. set_target_asm(target_info.assemextern);
  1530. end;
  1531. if (target_asm.supported_target <> target_any) and
  1532. (target_asm.supported_target <> target_info.target) then
  1533. begin
  1534. Message2(option_incompatible_asm,target_asm.idtxt,target_info.name);
  1535. set_target_asm(target_info.assemextern);
  1536. Message1(option_asm_forced,target_asm.idtxt);
  1537. end;
  1538. { turn off stripping if compiling with debuginfo or profile }
  1539. if (cs_debuginfo in initmoduleswitches) or
  1540. (cs_profile in initmoduleswitches) then
  1541. exclude(initglobalswitches,cs_link_strip);
  1542. if not LinkTypeSetExplicitly then
  1543. set_default_link_type;
  1544. { Default alignment settings,
  1545. 1. load the defaults for the target
  1546. 2. override with generic optimizer setting (little size)
  1547. 3. override with the user specified -Oa }
  1548. UpdateAlignment(initalignment,target_info.alignment);
  1549. if (cs_littlesize in aktglobalswitches) then
  1550. begin
  1551. initalignment.procalign:=1;
  1552. initalignment.jumpalign:=1;
  1553. initalignment.loopalign:=1;
  1554. end;
  1555. UpdateAlignment(initalignment,option.paraalignment);
  1556. option.free;
  1557. Option:=nil;
  1558. end;
  1559. initialization
  1560. coption:=toption;
  1561. finalization
  1562. if assigned(option) then
  1563. option.free;
  1564. end.
  1565. {
  1566. $Log$
  1567. Revision 1.72 2002-05-16 19:46:41 carl
  1568. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1569. + try to fix temp allocation (still in ifdef)
  1570. + generic constructor calls
  1571. + start of tassembler / tmodulebase class cleanup
  1572. Revision 1.70 2002/05/12 16:53:08 peter
  1573. * moved entry and exitcode to ncgutil and cgobj
  1574. * foreach gets extra argument for passing local data to the
  1575. iterator function
  1576. * -CR checks also class typecasts at runtime by changing them
  1577. into as
  1578. * fixed compiler to cycle with the -CR option
  1579. * fixed stabs with elf writer, finally the global variables can
  1580. be watched
  1581. * removed a lot of routines from cga unit and replaced them by
  1582. calls to cgobj
  1583. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1584. u32bit then the other is typecasted also to u32bit without giving
  1585. a rangecheck warning/error.
  1586. * fixed pascal calling method with reversing also the high tree in
  1587. the parast, detected by tcalcst3 test
  1588. Revision 1.69 2002/04/21 19:02:04 peter
  1589. * removed newn and disposen nodes, the code is now directly
  1590. inlined from pexpr
  1591. * -an option that will write the secondpass nodes to the .s file, this
  1592. requires EXTDEBUG define to actually write the info
  1593. * fixed various internal errors and crashes due recent code changes
  1594. Revision 1.68 2002/04/20 21:32:24 carl
  1595. + generic FPC_CHECKPOINTER
  1596. + first parameter offset in stack now portable
  1597. * rename some constants
  1598. + move some cpu stuff to other units
  1599. - remove unused constents
  1600. * fix stacksize for some targets
  1601. * fix generic size problems which depend now on EXTEND_SIZE constant
  1602. Revision 1.67 2002/04/07 10:22:35 carl
  1603. + CPU defines now depends on current target
  1604. Revision 1.66 2002/04/04 19:05:58 peter
  1605. * removed unused units
  1606. * use tlocation.size in cg.a_*loc*() routines
  1607. Revision 1.65 2002/04/04 18:39:45 carl
  1608. + added wdosx support (patch from Pavel)
  1609. Revision 1.64 2001/12/03 21:48:42 peter
  1610. * freemem change to value parameter
  1611. * torddef low/high range changed to int64
  1612. Revision 1.63 2001/11/24 02:09:54 carl
  1613. * Renamed ppc.cfg -> fpc.cfg
  1614. Revision 1.62 2001/11/23 02:48:46 carl
  1615. + ppc.cfg is now configuration file for compiler.
  1616. (first tries loading ppc386.cfg for backward compatibility)
  1617. Revision 1.61 2001/10/23 21:49:42 peter
  1618. * $calling directive and -Cc commandline patch added
  1619. from Pavel Ozerski
  1620. Revision 1.60 2001/09/17 21:29:12 peter
  1621. * merged netbsd, fpu-overflow from fixes branch
  1622. Revision 1.59 2001/09/12 12:46:54 marco
  1623. * fix from peter
  1624. Revision 1.58 2001/08/30 20:57:09 peter
  1625. * asbsd merged
  1626. Revision 1.57 2001/08/30 20:13:53 peter
  1627. * rtti/init table updates
  1628. * rttisym for reusable global rtti/init info
  1629. * support published for interfaces
  1630. Revision 1.56 2001/08/20 10:58:48 florian
  1631. * renamed messages unit to cmsgs to avoid conflicts with the
  1632. win32 messages unit
  1633. Revision 1.55 2001/08/19 11:22:23 peter
  1634. * palmos support from v10 merged
  1635. Revision 1.54 2001/08/12 17:57:06 peter
  1636. * under development flag for targets
  1637. Revision 1.53 2001/08/07 18:42:46 peter
  1638. * list targets with -i
  1639. Revision 1.52 2001/08/01 15:07:29 jonas
  1640. + "compilerproc" directive support, which turns both the public and mangled
  1641. name to lowercase(declaration_name). This prevents a normal user from
  1642. accessing the routine, but they can still be easily looked up within
  1643. the compiler. This is used for helper procedures and should facilitate
  1644. the writing of more processor independent code in the code generator
  1645. itself (mostly written by Peter)
  1646. + new "createintern" constructor for tcal nodes to create a call to
  1647. helper exported using the "compilerproc" directive
  1648. + support for high(dynamic_array) using the the above new things
  1649. + definition of 'HASCOMPILERPROC' symbol (to be able to check in the
  1650. compiler and rtl whether the "compilerproc" directive is supported)
  1651. Revision 1.51 2001/07/31 19:38:46 peter
  1652. * removed fpu_in_rtl define (merged)
  1653. Revision 1.50 2001/07/30 21:39:26 peter
  1654. * declare fpu in rtl for m68k linux
  1655. Revision 1.49 2001/07/09 21:15:40 peter
  1656. * Length made internal
  1657. * Add array support for Length
  1658. Revision 1.48 2001/07/08 21:00:15 peter
  1659. * various widestring updates, it works now mostly without charset
  1660. mapping supported
  1661. Revision 1.47 2001/07/01 20:16:16 peter
  1662. * alignmentinfo record added
  1663. * -Oa argument supports more alignment settings that can be specified
  1664. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  1665. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  1666. required alignment and the maximum usefull alignment. The final
  1667. alignment will be choosen per variable size dependent on these
  1668. settings
  1669. Revision 1.46 2001/06/29 19:41:54 peter
  1670. * patch from Pavel Ozerski to support +/- better
  1671. Revision 1.45 2001/06/19 14:55:45 jonas
  1672. * fixed typo in NOBOUNDCHECK define
  1673. Revision 1.44 2001/06/18 20:36:24 peter
  1674. * -Ur switch (merged)
  1675. * masm fixes (merged)
  1676. * quoted filenames for go32v2 and win32
  1677. Revision 1.43 2001/06/02 19:21:45 peter
  1678. * extradefines field added to target_info, so that targets don't
  1679. need to put code in options.pas for it
  1680. Revision 1.42 2001/05/18 22:28:59 peter
  1681. * endian define
  1682. Revision 1.41 2001/05/12 12:11:31 peter
  1683. * simplify_ppu is now the default, a recompile of the compiler now
  1684. only compiles pp.pas
  1685. Revision 1.40 2001/04/18 22:01:54 peter
  1686. * registration of targets and assemblers
  1687. Revision 1.39 2001/04/13 01:22:10 peter
  1688. * symtable change to classes
  1689. * range check generation and errors fixed, make cycle DEBUG=1 works
  1690. * memory leaks fixed
  1691. Revision 1.38 2001/03/25 12:27:31 peter
  1692. * fixed -Se (merged)
  1693. Revision 1.37 2001/03/23 00:16:07 florian
  1694. + some stuff to compile FreeCLX added
  1695. Revision 1.36 2001/03/13 20:59:56 peter
  1696. * message loading fixes from Sergey (merged)
  1697. Revision 1.35 2001/03/10 13:19:10 peter
  1698. * don't check messagefile for numbers, this allows the usage of
  1699. 1.1 msgfiles with a 1.0.x compiler
  1700. Revision 1.34 2001/03/05 21:50:29 peter
  1701. * press enter moved to errore.msg
  1702. Revision 1.33 2001/03/03 12:41:22 jonas
  1703. * simplified and optimized range checking code, FPC_BOUNDCHECK is no longer necessary
  1704. Revision 1.32 2001/02/26 19:44:53 peter
  1705. * merged generic m68k updates from fixes branch
  1706. Revision 1.31 2001/02/26 12:47:46 jonas
  1707. * fixed bug in type checking for compatibility of set elements (merged)
  1708. * released fix in options.pas from Carl also for FPC (merged)
  1709. Revision 1.30 2001/02/26 08:08:39 michael
  1710. * option_help_pages:
  1711. allow to omit an option (use one space char insteed an option)
  1712. but to indent a continuation line as if option is present. For lines:
  1713. 3*2CX_first line
  1714. 3*2 _second line
  1715. 3*2*_third line
  1716. we could get:
  1717. -CX first line
  1718. second line
  1719. third line
  1720. Revision 1.29 2001/02/26 07:49:50 michael
  1721. Support replacements for all -F<x> options
  1722. Revision 1.28 2001/02/05 21:26:36 peter
  1723. * applied patches from Sergey Korshunoff
  1724. Revision 1.27 2001/01/20 18:36:51 hajny
  1725. + APPTYPE support under OS/2, app_fs, GetEnvPChar for OS/2
  1726. Revision 1.26 2001/01/12 19:21:09 peter
  1727. * fixed writing of quickinfo when no ppc386.cfg is available
  1728. Revision 1.25 2001/01/05 17:36:57 florian
  1729. * the info about exception frames is stored now on the stack
  1730. instead on the heap
  1731. Revision 1.24 2000/12/25 00:07:26 peter
  1732. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  1733. tlinkedlist objects)
  1734. Revision 1.23 2000/12/24 12:21:41 peter
  1735. * use system.paramstr()
  1736. Revision 1.22 2000/12/23 19:46:49 peter
  1737. * object to class conversion
  1738. * more verbosity for -vt and -vd
  1739. * -i options can be put after eachother so the Makefiles only need
  1740. to call fpc once for all info (will be twice as the first one will
  1741. be to check the version if fpc supports multiple info)
  1742. Revision 1.21 2000/12/16 15:56:19 jonas
  1743. - removed all ifdef cardinalmulfix code
  1744. Revision 1.20 2000/12/15 13:26:01 jonas
  1745. * only return int64's from functions if it int64funcresok is defined
  1746. + added int64funcresok define to options.pas
  1747. Revision 1.19 2000/11/30 22:48:23 florian
  1748. * opts386 renamed
  1749. Revision 1.18 2000/11/29 00:30:34 florian
  1750. * unused units removed from uses clause
  1751. * some changes for widestrings
  1752. Revision 1.17 2000/11/13 15:26:12 marco
  1753. * Renamefest
  1754. Revision 1.16 2000/11/12 22:20:37 peter
  1755. * create generic toutputsection for binary writers
  1756. Revision 1.15 2000/11/07 15:09:27 marco
  1757. * Define UNIX for FreeBSD and Linux. Checked crosscompile thingy.
  1758. Revision 1.14 2000/11/07 14:25:08 marco
  1759. * FreeBSD defines (FreeBSD,Linux,BSD,Unix) Linux defines (Linux,Unix)
  1760. Revision 1.13 2000/11/06 20:30:54 peter
  1761. * more fixes to get make cycle working
  1762. Revision 1.12 2000/11/04 14:25:20 florian
  1763. + merged Attila's changes for interfaces, not tested yet
  1764. Revision 1.11 2000/09/26 10:50:41 jonas
  1765. * initmodeswitches is changed is you change the compiler mode from the
  1766. command line (the -S<x> switches didn't work anymore for changing the
  1767. compiler mode) (merged from fixes branch)
  1768. Revision 1.10 2000/09/24 21:33:47 peter
  1769. * message updates merges
  1770. Revision 1.9 2000/09/24 15:06:20 peter
  1771. * use defines.inc
  1772. Revision 1.8 2000/09/18 12:28:41 marco
  1773. * Definition of multiple FreeBSD target defines moved to after error check
  1774. commandline parsing
  1775. Revision 1.7 2000/09/16 12:22:52 peter
  1776. * freebsd support merged
  1777. Revision 1.6 2000/08/27 16:11:51 peter
  1778. * moved some util functions from globals,cobjects to cutils
  1779. * splitted files into finput,fmodule
  1780. Revision 1.5 2000/08/07 11:31:04 jonas
  1781. * fixed bug in type conversions between enum subranges (it didn't take
  1782. the packenum directive into account)
  1783. + define PACKENUMFIXED symbol in options.pas
  1784. (merged from fixes branch)
  1785. Revision 1.4 2000/07/14 05:11:48 michael
  1786. + Patch to 1.1
  1787. Revision 1.3 2000/07/13 12:08:26 michael
  1788. + patched to 1.1.0 with former 1.09patch from peter
  1789. Revision 1.2 2000/07/13 11:32:44 michael
  1790. + removed logs
  1791. }