options.pas 53 KB

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