options.pas 56 KB

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