options.pas 54 KB

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