options.pas 58 KB

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