options.pas 56 KB

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