options.pas 58 KB

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