options.pas 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 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 fpcdefs.inc}
  20. interface
  21. uses
  22. globtype,globals,verbose,systems,cpuinfo;
  23. type
  24. TOption=class
  25. FirstPass,
  26. NoPressEnter,
  27. DoWriteLogo : boolean;
  28. FileLevel : longint;
  29. QuickInfo : string;
  30. ParaIncludePath,
  31. ParaUnitPath,
  32. ParaObjectPath,
  33. ParaLibraryPath : TSearchPathList;
  34. ParaAlignment : TAlignmentInfo;
  35. Constructor Create;
  36. Destructor Destroy;override;
  37. procedure WriteLogo;
  38. procedure WriteInfo;
  39. procedure WriteHelpPages;
  40. procedure WriteQuickInfo;
  41. procedure IllegalPara(const opt:string);
  42. function Unsetbool(var Opts:string; Pos: Longint):boolean;
  43. procedure interpret_proc_specific_options(const opt:string);virtual;
  44. procedure interpret_option(const opt :string;ispara:boolean);
  45. procedure Interpret_envvar(const envname : string);
  46. procedure Interpret_file(const filename : string);
  47. procedure Read_Parameters;
  48. procedure parsecmd(cmd:string);
  49. procedure TargetDefines(def:boolean);
  50. end;
  51. TOptionClass=class of toption;
  52. var
  53. coption : TOptionClass;
  54. procedure read_arguments(cmd:string);
  55. implementation
  56. uses
  57. widestr,
  58. {$ifdef Delphi}
  59. dmisc,
  60. {$else Delphi}
  61. dos,
  62. {$endif Delphi}
  63. version,
  64. cutils,cmsgs
  65. {$ifdef BrowserLog}
  66. ,browlog
  67. {$endif BrowserLog}
  68. ;
  69. const
  70. page_size = 24;
  71. var
  72. option : toption;
  73. read_configfile, { read config file, set when a cfgfile is found }
  74. disable_configfile,
  75. target_is_set : boolean; { do not allow contradictory target settings }
  76. asm_is_set : boolean; { -T also change initoutputformat if not set idrectly }
  77. fpcdir,
  78. ppccfg,
  79. ppcaltcfg,
  80. param_file : string; { file to compile specified on the commandline }
  81. {****************************************************************************
  82. Defines
  83. ****************************************************************************}
  84. procedure def_symbol(const s : string);
  85. begin
  86. if s='' then
  87. exit;
  88. initdefines.insert(upper(s));
  89. Message1(option_defining_symbol,s);
  90. end;
  91. procedure undef_symbol(const s : string);
  92. begin
  93. if s='' then
  94. exit;
  95. InitDefines.Remove(s);
  96. Message1(option_undefining_symbol,s);
  97. end;
  98. function check_symbol(const s:string):boolean;
  99. begin
  100. check_symbol:=(initdefines.find(s)<>nil);
  101. end;
  102. procedure set_default_link_type;
  103. begin
  104. { win32 and wdosx need smartlinking by default to prevent including too much
  105. dll dependencies }
  106. if (target_info.system in [system_i386_win32,system_i386_wdosx]) then
  107. begin
  108. def_symbol('FPC_LINK_SMART');
  109. undef_symbol('FPC_LINK_STATIC');
  110. undef_symbol('FPC_LINK_DYNAMIC');
  111. initglobalswitches:=initglobalswitches+[cs_link_smart];
  112. initglobalswitches:=initglobalswitches-[cs_link_shared,cs_link_static];
  113. end
  114. else
  115. begin
  116. undef_symbol('FPC_LINK_SMART');
  117. def_symbol('FPC_LINK_STATIC');
  118. undef_symbol('FPC_LINK_DYNAMIC');
  119. initglobalswitches:=initglobalswitches+[cs_link_static];
  120. initglobalswitches:=initglobalswitches-[cs_link_shared,cs_link_smart];
  121. end;
  122. end;
  123. {****************************************************************************
  124. Toption
  125. ****************************************************************************}
  126. procedure StopOptions(err:longint);
  127. begin
  128. if assigned(Option) then
  129. begin
  130. Option.free;
  131. Option:=nil;
  132. end;
  133. DoneVerbose;
  134. Stop(err);
  135. end;
  136. procedure Toption.WriteLogo;
  137. var
  138. p : pchar;
  139. begin
  140. p:=MessagePchar(option_logo);
  141. while assigned(p) do
  142. Comment(V_Normal,GetMsgLine(p));
  143. end;
  144. procedure Toption.WriteInfo;
  145. var
  146. p : pchar;
  147. hs,hs1,s : string;
  148. target : tsystem;
  149. begin
  150. p:=MessagePchar(option_info);
  151. while assigned(p) do
  152. begin
  153. s:=GetMsgLine(p);
  154. { list OS Targets }
  155. if pos('$OSTARGETS',s)>0 then
  156. begin
  157. for target:=low(tsystem) to high(tsystem) do
  158. if assigned(targetinfos[target]) then
  159. begin
  160. hs:=s;
  161. hs1:=targetinfos[target]^.name;
  162. if tf_under_development in targetinfos[target]^.flags then
  163. hs1:=hs1+' (under development)';
  164. Replace(hs,'$OSTARGETS',hs1);
  165. Comment(V_Normal,hs);
  166. end;
  167. end
  168. else
  169. Comment(V_Normal,s);
  170. end;
  171. StopOptions(0);
  172. end;
  173. procedure Toption.WriteHelpPages;
  174. function PadEnd(s:string;i:longint):string;
  175. begin
  176. while (length(s)<i) do
  177. s:=s+' ';
  178. PadEnd:=s;
  179. end;
  180. var
  181. lastident,
  182. j,outline,
  183. ident,
  184. lines : longint;
  185. show : boolean;
  186. opt : string[32];
  187. input,
  188. s : string;
  189. p : pchar;
  190. begin
  191. WriteLogo;
  192. Lines:=4;
  193. Message1(option_usage,system.paramstr(0));
  194. lastident:=0;
  195. p:=MessagePChar(option_help_pages);
  196. while assigned(p) do
  197. begin
  198. { get a line and reset }
  199. s:=GetMsgLine(p);
  200. ident:=0;
  201. show:=false;
  202. { parse options }
  203. case s[1] of
  204. {$ifdef UNITALIASES}
  205. 'a',
  206. {$endif}
  207. {$ifdef EXTDEBUG}
  208. 'e',
  209. {$endif EXTDEBUG}
  210. {$ifdef i386}
  211. '3',
  212. {$endif}
  213. {$ifdef powerpc}
  214. 'P',
  215. {$endif}
  216. {$ifdef vis}
  217. 'V',
  218. {$endif}
  219. {$ifdef sparc}
  220. 'S',
  221. {$endif}
  222. {$ifdef m68k}
  223. '6',
  224. {$endif}
  225. '*' : show:=true;
  226. end;
  227. if show then
  228. begin
  229. case s[2] of
  230. {$ifdef GDB}
  231. 'g',
  232. {$endif}
  233. {$ifdef Unix}
  234. 'L',
  235. {$endif}
  236. {$ifdef os2}
  237. 'O',
  238. {$endif}
  239. '*' : show:=true;
  240. else
  241. show:=false;
  242. end;
  243. end;
  244. { now we may show the message or not }
  245. if show then
  246. begin
  247. case s[3] of
  248. '0' : begin
  249. ident:=0;
  250. outline:=0;
  251. end;
  252. '1' : begin
  253. ident:=2;
  254. outline:=7;
  255. end;
  256. '2' : begin
  257. ident:=6;
  258. outline:=11;
  259. end;
  260. '3' : begin
  261. ident:=9;
  262. outline:=6;
  263. end;
  264. end;
  265. j:=pos('_',s);
  266. opt:=Copy(s,4,j-4);
  267. if opt='*' then
  268. opt:=''
  269. else
  270. if opt=' ' then
  271. opt:=PadEnd(opt,outline)
  272. else
  273. opt:=PadEnd('-'+opt,outline);
  274. if (ident=0) and (lastident<>0) then
  275. begin
  276. Comment(V_Normal,'');
  277. inc(Lines);
  278. end;
  279. { page full ? }
  280. if (lines >= page_size - 1) then
  281. begin
  282. if not NoPressEnter then
  283. begin
  284. Message(option_help_press_enter);
  285. readln(input);
  286. if upper(input)='Q' then
  287. StopOptions(0);
  288. end;
  289. lines:=0;
  290. end;
  291. Comment(V_Normal,PadEnd('',ident)+opt+Copy(s,j+1,255));
  292. LastIdent:=Ident;
  293. inc(Lines);
  294. end;
  295. end;
  296. StopOptions(0);
  297. end;
  298. procedure Toption.IllegalPara(const opt:string);
  299. begin
  300. Message1(option_illegal_para,opt);
  301. Message(option_help_pages_para);
  302. StopOptions(1);
  303. end;
  304. function Toption.Unsetbool(var Opts:string; Pos: Longint):boolean;
  305. { checks if the character after pos in Opts is a + or a - and returns resp.
  306. false or true. If it is another character (or none), it also returns false }
  307. begin
  308. UnsetBool := false;
  309. if Length(Opts)>Pos then
  310. begin
  311. inc(Pos);
  312. UnsetBool := Opts[Pos] = '-';
  313. if Opts[Pos] in ['-','+']then
  314. delete(Opts,Pos,1);
  315. end;
  316. end;
  317. procedure TOption.interpret_proc_specific_options(const opt:string);
  318. begin
  319. end;
  320. procedure TOption.interpret_option(const opt:string;ispara:boolean);
  321. var
  322. code : integer;
  323. c : char;
  324. more : string;
  325. major,minor : longint;
  326. error : integer;
  327. j,l : longint;
  328. d : DirStr;
  329. e : ExtStr;
  330. s : string;
  331. forceasm : tasm;
  332. begin
  333. if opt='' then
  334. exit;
  335. { only parse define,undef,target,verbosity and link options the firsttime }
  336. if firstpass and
  337. not((opt[1]='-') and (opt[2] in ['i','d','v','T','u','n','X'])) then
  338. exit;
  339. Message1(option_handling_option,opt);
  340. case opt[1] of
  341. '-' :
  342. begin
  343. more:=Copy(opt,3,255);
  344. if firstpass then
  345. Message1(option_interpreting_firstpass_option,opt)
  346. else
  347. Message1(option_interpreting_option,opt);
  348. case opt[2] of
  349. '?' :
  350. WriteHelpPages;
  351. 'a' :
  352. begin
  353. include(initglobalswitches,cs_asm_leave);
  354. j:=1;
  355. while j<=length(more) do
  356. begin
  357. case more[j] of
  358. 'l' :
  359. include(initglobalswitches,cs_asm_source);
  360. 'r' :
  361. include(initglobalswitches,cs_asm_regalloc);
  362. 't' :
  363. include(initglobalswitches,cs_asm_tempalloc);
  364. 'n' :
  365. include(initglobalswitches,cs_asm_nodes);
  366. 'p' :
  367. begin
  368. exclude(initglobalswitches,cs_asm_leave);
  369. if UnsetBool(More, 0) then
  370. exclude(initglobalswitches,cs_asm_pipe)
  371. else
  372. include(initglobalswitches,cs_asm_pipe);
  373. end;
  374. '-' :
  375. initglobalswitches:=initglobalswitches -
  376. [cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc,
  377. cs_asm_nodes, cs_asm_pipe];
  378. else
  379. IllegalPara(opt);
  380. end;
  381. inc(j);
  382. end;
  383. end;
  384. 'A' :
  385. begin
  386. if set_target_asm_by_string(More) then
  387. asm_is_set:=true
  388. else
  389. IllegalPara(opt);
  390. end;
  391. 'b' :
  392. begin
  393. {$ifdef supportbrowser}
  394. if UnsetBool(More,0) then
  395. begin
  396. exclude(initmoduleswitches,cs_browser);
  397. exclude(initmoduleswitches,cs_local_browser);
  398. {$ifdef BrowserLog}
  399. exclude(initglobalswitches,cs_browser_log);
  400. {$endif}
  401. end
  402. else
  403. begin
  404. include(initmoduleswitches,cs_browser);
  405. {$ifdef BrowserLog}
  406. include(initglobalswitches,cs_browser_log);
  407. {$endif}
  408. end;
  409. if More<>'' then
  410. if (More='l') or (More='l+') then
  411. include(initmoduleswitches,cs_local_browser)
  412. else
  413. if More='l-' then
  414. exclude(initmoduleswitches,cs_local_browser)
  415. else
  416. {$ifdef BrowserLog}
  417. browserlog.elements_to_list.insert(more);
  418. {$else}
  419. IllegalPara(opt);
  420. {$endif}
  421. {$endif supportbrowser}
  422. end;
  423. 'B' :
  424. do_build:=not UnSetBool(more,0);
  425. 'C' :
  426. begin
  427. j:=1;
  428. while j<=length(more) do
  429. begin
  430. case more[j] of
  431. 'a' :
  432. Message2(option_obsolete_switch_use_new,'-Ca','-Or');
  433. 'c' :
  434. begin
  435. if not SetAktProcCall(upper(copy(more,j+1,length(more)-j)),true) then
  436. IllegalPara(opt);
  437. break;
  438. end;
  439. {$ifdef cpufpemu}
  440. 'e' :
  441. begin
  442. If UnsetBool(More, j) then
  443. exclude(initmoduleswitches,cs_fp_emulation)
  444. Else
  445. include(initmoduleswitches,cs_fp_emulation);
  446. end;
  447. {$endif cpufpemu}
  448. 'f' :
  449. begin
  450. s:=upper(copy(more,j+1,length(more)-j));
  451. if not(SetFpuType(s,true)) then
  452. IllegalPara(opt);
  453. break;
  454. end;
  455. 'g' :
  456. include(initmoduleswitches,cs_create_pic);
  457. 'h' :
  458. begin
  459. val(copy(more,j+1,length(more)-j),heapsize,code);
  460. if (code<>0) or
  461. {$WARNING Is the upper limit for heapsize needed / useful?}
  462. { (heapsize>=67107840) or }
  463. (heapsize<1024) then
  464. IllegalPara(opt);
  465. break;
  466. end;
  467. 'i' :
  468. If UnsetBool(More, j) then
  469. exclude(initlocalswitches,cs_check_io)
  470. else
  471. include(initlocalswitches,cs_check_io);
  472. 'n' :
  473. If UnsetBool(More, j) then
  474. exclude(initglobalswitches,cs_link_extern)
  475. Else
  476. include(initglobalswitches,cs_link_extern);
  477. 'o' :
  478. If UnsetBool(More, j) then
  479. exclude(initlocalswitches,cs_check_overflow)
  480. Else
  481. include(initlocalswitches,cs_check_overflow);
  482. 'p' :
  483. begin
  484. s:=upper(copy(more,j+1,length(more)-j));
  485. if not(SetProcessor(s,true)) then
  486. IllegalPara(opt);
  487. break;
  488. end;
  489. 'r' :
  490. If UnsetBool(More, j) then
  491. exclude(initlocalswitches,cs_check_range)
  492. Else
  493. include(initlocalswitches,cs_check_range);
  494. 'R' :
  495. If UnsetBool(More, j) then
  496. begin
  497. exclude(initlocalswitches,cs_check_range);
  498. exclude(initlocalswitches,cs_check_object);
  499. end
  500. Else
  501. begin
  502. include(initlocalswitches,cs_check_range);
  503. include(initlocalswitches,cs_check_object);
  504. end;
  505. 's' :
  506. begin
  507. val(copy(more,j+1,length(more)-j),stacksize,code);
  508. if (code<>0) or (stacksize>=67107840) or (stacksize<1024) then
  509. IllegalPara(opt);
  510. break;
  511. end;
  512. 't' :
  513. If UnsetBool(More, j) then
  514. exclude(initlocalswitches,cs_check_stack)
  515. Else
  516. include(initlocalswitches,cs_check_stack);
  517. 'D' :
  518. If UnsetBool(More, j) then
  519. exclude(initmoduleswitches,cs_create_dynamic)
  520. Else
  521. include(initmoduleswitches,cs_create_dynamic);
  522. 'X' :
  523. If UnsetBool(More, j) then
  524. exclude(initmoduleswitches,cs_create_smart)
  525. Else
  526. include(initmoduleswitches,cs_create_smart);
  527. else
  528. IllegalPara(opt);
  529. end;
  530. inc(j);
  531. end;
  532. end;
  533. 'd' :
  534. def_symbol(more);
  535. 'D' :
  536. begin
  537. include(initglobalswitches,cs_link_deffile);
  538. j:=1;
  539. while j<=length(more) do
  540. begin
  541. case more[j] of
  542. 'd' :
  543. begin
  544. description:=Copy(more,j+1,255);
  545. break;
  546. end;
  547. 'v' :
  548. begin
  549. dllversion:=Copy(more,j+1,255);
  550. l:=pos('.',dllversion);
  551. dllminor:=0;
  552. error:=0;
  553. if l>0 then
  554. begin
  555. valint(copy(dllversion,l+1,255),minor,error);
  556. if (error=0) and
  557. (minor>=0) and (minor<=$ffff) then
  558. dllminor:=minor
  559. else
  560. if error=0 then
  561. error:=1;
  562. end;
  563. if l=0 then
  564. l:=256;
  565. dllmajor:=1;
  566. if error=0 then
  567. valint(copy(dllversion,1,l-1),major,error);
  568. if (error=0) and (major>=0) and (major<=$ffff) then
  569. dllmajor:=major
  570. else
  571. if error=0 then
  572. error:=1;
  573. if error<>0 then
  574. Message1(scan_w_wrong_version_ignored,dllversion);
  575. break;
  576. end;
  577. 'w' :
  578. usewindowapi:=true;
  579. '-' :
  580. begin
  581. exclude(initglobalswitches,cs_link_deffile);
  582. usewindowapi:=false;
  583. end;
  584. else
  585. IllegalPara(opt);
  586. end;
  587. inc(j);
  588. end;
  589. end;
  590. 'e' :
  591. exepath:=FixPath(FExpand(More),true);
  592. 'E' :
  593. begin
  594. if UnsetBool(More, 0) then
  595. exclude(initglobalswitches,cs_link_extern)
  596. else
  597. include(initglobalswitches,cs_link_extern);
  598. end;
  599. 'F' :
  600. begin
  601. c:=more[1];
  602. Delete(more,1,1);
  603. DefaultReplacements(More);
  604. case c of
  605. 'c' :
  606. begin
  607. if not(cpavailable(more)) then
  608. Message1(option_code_page_not_available,more)
  609. else
  610. initsourcecodepage:=more;
  611. end;
  612. 'D' :
  613. utilsdirectory:=FixPath(FExpand(More),true);
  614. 'e' :
  615. SetRedirectFile(More);
  616. 'E' :
  617. OutputExeDir:=FixPath(FExpand(More),true);
  618. 'i' :
  619. begin
  620. if ispara then
  621. ParaIncludePath.AddPath(More,false)
  622. else
  623. includesearchpath.AddPath(More,true);
  624. end;
  625. 'g' :
  626. Message2(option_obsolete_switch_use_new,'-Fg','-Fl');
  627. 'l' :
  628. begin
  629. if ispara then
  630. ParaLibraryPath.AddPath(More,false)
  631. else
  632. LibrarySearchPath.AddPath(More,true);
  633. end;
  634. 'L' :
  635. begin
  636. if More<>'' then
  637. ParaDynamicLinker:=More
  638. else
  639. IllegalPara(opt);
  640. end;
  641. 'o' :
  642. begin
  643. if ispara then
  644. ParaObjectPath.AddPath(More,false)
  645. else
  646. ObjectSearchPath.AddPath(More,true);
  647. end;
  648. 'r' :
  649. Msgfilename:=More;
  650. 'u' :
  651. begin
  652. if ispara then
  653. ParaUnitPath.AddPath(More,false)
  654. else
  655. unitsearchpath.AddPath(More,true);
  656. end;
  657. 'U' :
  658. OutputUnitDir:=FixPath(FExpand(More),true);
  659. else
  660. IllegalPara(opt);
  661. end;
  662. end;
  663. 'g' : begin
  664. if UnsetBool(More, 0) then
  665. begin
  666. exclude(initmoduleswitches,cs_debuginfo);
  667. exclude(initglobalswitches,cs_gdb_dbx);
  668. exclude(initglobalswitches,cs_gdb_gsym);
  669. exclude(initglobalswitches,cs_gdb_heaptrc);
  670. exclude(initglobalswitches,cs_gdb_lineinfo);
  671. exclude(initglobalswitches,cs_checkpointer);
  672. end
  673. else
  674. begin
  675. {$ifdef GDB}
  676. include(initmoduleswitches,cs_debuginfo);
  677. {$else GDB}
  678. Message(option_no_debug_support);
  679. Message(option_no_debug_support_recompile_fpc);
  680. {$endif GDB}
  681. end;
  682. {$ifdef GDB}
  683. if not RelocSectionSetExplicitly then
  684. RelocSection:=false;
  685. j:=1;
  686. while j<=length(more) do
  687. begin
  688. case more[j] of
  689. 'd' :
  690. begin
  691. if UnsetBool(More, j) then
  692. exclude(initglobalswitches,cs_gdb_dbx)
  693. else
  694. include(initglobalswitches,cs_gdb_dbx);
  695. end;
  696. 'g' :
  697. begin
  698. if UnsetBool(More, j) then
  699. exclude(initglobalswitches,cs_gdb_gsym)
  700. else
  701. include(initglobalswitches,cs_gdb_gsym);
  702. end;
  703. 'h' :
  704. begin
  705. if UnsetBool(More, j) then
  706. exclude(initglobalswitches,cs_gdb_heaptrc)
  707. else
  708. include(initglobalswitches,cs_gdb_heaptrc);
  709. end;
  710. 'l' :
  711. begin
  712. if UnsetBool(More, j) then
  713. exclude(initglobalswitches,cs_gdb_lineinfo)
  714. else
  715. include(initglobalswitches,cs_gdb_lineinfo);
  716. end;
  717. 'c' :
  718. begin
  719. if UnsetBool(More, j) then
  720. exclude(initglobalswitches,cs_checkpointer)
  721. else
  722. include(initglobalswitches,cs_checkpointer);
  723. end;
  724. 'v' :
  725. begin
  726. if UnsetBool(More, j) then
  727. exclude(initglobalswitches,cs_gdb_valgrind)
  728. else
  729. include(initglobalswitches,cs_gdb_valgrind);
  730. end;
  731. 'w' :
  732. begin
  733. if UnsetBool(More, j) then
  734. exclude(initglobalswitches,cs_gdb_dwarf)
  735. else
  736. include(initglobalswitches,cs_gdb_dwarf);
  737. end;
  738. else
  739. IllegalPara(opt);
  740. end;
  741. inc(j);
  742. end;
  743. {$endif GDB}
  744. end;
  745. 'h' :
  746. begin
  747. NoPressEnter:=true;
  748. WriteHelpPages;
  749. end;
  750. 'i' :
  751. begin
  752. if More='' then
  753. WriteInfo
  754. else
  755. QuickInfo:=QuickInfo+More;
  756. end;
  757. 'I' :
  758. begin
  759. if ispara then
  760. ParaIncludePath.AddPath(More,false)
  761. else
  762. includesearchpath.AddPath(More,false);
  763. end;
  764. 'k' :
  765. begin
  766. if more<>'' then
  767. ParaLinkOptions:=ParaLinkOptions+' '+More
  768. else
  769. IllegalPara(opt);
  770. end;
  771. 'l' :
  772. DoWriteLogo:=not UnSetBool(more,0);
  773. 'm' :
  774. parapreprocess:=not UnSetBool(more,0);
  775. 'n' :
  776. begin
  777. if More='' then
  778. disable_configfile:=true
  779. else
  780. IllegalPara(opt);
  781. end;
  782. 'o' :
  783. begin
  784. if More<>'' then
  785. Fsplit(More,d,OutputFile,e)
  786. else
  787. IllegalPara(opt);
  788. end;
  789. 'p' :
  790. begin
  791. if UnsetBool(More, 0) then
  792. begin
  793. initmoduleswitches:=initmoduleswitches-[cs_profile];
  794. undef_symbol('FPC_PROFILE');
  795. end
  796. else
  797. if Length(More)=0 then
  798. IllegalPara(opt)
  799. else
  800. case more[1] of
  801. 'g' : if UnsetBool(more, 1) then
  802. begin
  803. exclude(initmoduleswitches,cs_profile);
  804. undef_symbol('FPC_PROFILE');
  805. end
  806. else
  807. begin
  808. include(initmoduleswitches,cs_profile);
  809. def_symbol('FPC_PROFILE');
  810. end;
  811. else
  812. IllegalPara(opt);
  813. end;
  814. end;
  815. {$ifdef Unix}
  816. 'P' : ; { Ignore used by fpc.pp }
  817. {$endif Unix}
  818. 's' :
  819. begin
  820. if UnsetBool(More, 0) then
  821. begin
  822. initglobalswitches:=initglobalswitches-[cs_asm_extern,cs_link_extern];
  823. if more<>'' then
  824. IllegalPara(opt);
  825. end
  826. else
  827. begin
  828. initglobalswitches:=initglobalswitches+[cs_asm_extern,cs_link_extern];
  829. if more='h' then
  830. initglobalswitches:=initglobalswitches-[cs_link_on_target]
  831. else if more='t' then
  832. initglobalswitches:=initglobalswitches+[cs_link_on_target]
  833. else if more='r' then
  834. initglobalswitches:=initglobalswitches+[cs_asm_leave,cs_no_regalloc]
  835. else if more<>'' then
  836. IllegalPara(opt);
  837. end;
  838. end;
  839. 'M' :
  840. begin
  841. more:=Upper(more);
  842. if not SetCompileMode(more, true) then
  843. IllegalPara(opt);
  844. end;
  845. 'S' :
  846. begin
  847. if more[1]='I' then
  848. begin
  849. if upper(more)='ICOM' then
  850. initinterfacetype:=it_interfacecom
  851. else if upper(more)='ICORBA' then
  852. initinterfacetype:=it_interfacecorba
  853. else
  854. IllegalPara(opt);
  855. end
  856. else
  857. begin
  858. j:=1;
  859. while j<=length(more) do
  860. begin
  861. case more[j] of
  862. '2' : //an alternative to -Mobjfpc
  863. SetCompileMode('OBJFPC',true);
  864. 'a' :
  865. include(initlocalswitches,cs_do_assertion);
  866. 'c' :
  867. include(initmoduleswitches,cs_support_c_operators);
  868. 'd' : //an alternative to -Mdelphi
  869. SetCompileMode('DELPHI',true);
  870. 'e' :
  871. begin
  872. SetErrorFlags(copy(more,j+1,length(more)));
  873. break;
  874. end;
  875. 'g' :
  876. include(initmoduleswitches,cs_support_goto);
  877. 'h' :
  878. include(initlocalswitches,cs_ansistrings);
  879. 'i' :
  880. include(initmoduleswitches,cs_support_inline);
  881. 'm' :
  882. include(initmoduleswitches,cs_support_macro);
  883. 'o' : //an alternative to -Mtp
  884. SetCompileMode('TP',true);
  885. 'p' : //an alternative to -Mgpc
  886. SetCompileMode('GPC',true);
  887. 's' :
  888. include(initglobalswitches,cs_constructor_name);
  889. 't' :
  890. include(initmoduleswitches,cs_static_keyword);
  891. '-' :
  892. begin
  893. exclude(initglobalswitches,cs_constructor_name);
  894. initlocalswitches:=InitLocalswitches - [cs_do_assertion, cs_ansistrings];
  895. initmoduleswitches:=initmoduleswitches - [cs_support_c_operators, cs_support_goto,
  896. cs_support_inline, cs_support_macro,
  897. cs_static_keyword];
  898. end;
  899. else
  900. IllegalPara(opt);
  901. end;
  902. inc(j);
  903. end;
  904. end;
  905. end;
  906. 'T' :
  907. begin
  908. more:=Upper(More);
  909. if not target_is_set then
  910. begin
  911. { remove old target define }
  912. TargetDefines(false);
  913. { Save assembler if set }
  914. if asm_is_set then
  915. forceasm:=target_asm.id;
  916. { load new target }
  917. if not(set_target_by_string(More)) then
  918. IllegalPara(opt);
  919. { also initialize assembler if not explicitly set }
  920. if asm_is_set then
  921. set_target_asm(forceasm);
  922. { set new define }
  923. TargetDefines(true);
  924. target_is_set:=true;
  925. end
  926. else
  927. if More<>upper(target_info.shortname) then
  928. Message1(option_target_is_already_set,target_info.shortname);
  929. end;
  930. 'u' :
  931. undef_symbol(upper(More));
  932. 'U' :
  933. begin
  934. j:=1;
  935. while j<=length(more) do
  936. begin
  937. case more[j] of
  938. {$ifdef UNITALIASES}
  939. 'a' :
  940. begin
  941. AddUnitAlias(Copy(More,j+1,255));
  942. break;
  943. end;
  944. {$endif UNITALIASES}
  945. 'n' :
  946. exclude(initglobalswitches,cs_check_unit_name);
  947. 'p' :
  948. begin
  949. Message2(option_obsolete_switch_use_new,'-Up','-Fu');
  950. break;
  951. end;
  952. 'r' :
  953. do_release:=true;
  954. 's' :
  955. include(initmoduleswitches,cs_compilesystem);
  956. '-' :
  957. begin
  958. exclude(initmoduleswitches,cs_compilesystem);
  959. exclude(initglobalswitches,cs_check_unit_name);
  960. end;
  961. else
  962. IllegalPara(opt);
  963. end;
  964. inc(j);
  965. end;
  966. end;
  967. 'v' :
  968. begin
  969. if not setverbosity(More) then
  970. IllegalPara(opt);
  971. end;
  972. 'V' : ; { Ignore used by fpc }
  973. 'W' :
  974. begin
  975. j:=1;
  976. while j<=length(More) do
  977. begin
  978. case More[j] of
  979. 'B':
  980. begin
  981. { -WB200000 means set trefered base address
  982. to $200000, but does not change relocsection boolean
  983. this way we can create both relocatble and
  984. non relocatable DLL at a specific base address PM }
  985. if (length(More)>j) then
  986. begin
  987. if DLLImageBase=nil then
  988. DLLImageBase:=StringDup(Copy(More,j+1,255));
  989. end
  990. else
  991. begin
  992. RelocSection:=true;
  993. RelocSectionSetExplicitly:=true;
  994. end;
  995. break;
  996. end;
  997. 'C':
  998. begin
  999. if UnsetBool(More, j) then
  1000. apptype:=app_gui
  1001. else
  1002. apptype:=app_cui;
  1003. end;
  1004. 'D':
  1005. begin
  1006. UseDeffileForExports:=not UnsetBool(More, j);
  1007. UseDeffileForExportsSetExplicitly:=true;
  1008. end;
  1009. 'F':
  1010. begin
  1011. if UnsetBool(More, j) then
  1012. apptype:=app_cui
  1013. else
  1014. apptype:=app_fs;
  1015. end;
  1016. 'G':
  1017. begin
  1018. if UnsetBool(More, j) then
  1019. apptype:=app_cui
  1020. else
  1021. apptype:=app_gui;
  1022. end;
  1023. 'T':
  1024. begin
  1025. if UnsetBool(More, j) then
  1026. apptype:=app_cui
  1027. else
  1028. apptype:=app_tool;
  1029. end;
  1030. 'N':
  1031. begin
  1032. RelocSection:=UnsetBool(More,j);
  1033. RelocSectionSetExplicitly:=true;
  1034. end;
  1035. 'R':
  1036. begin
  1037. { support -WR+ / -WR- as synonyms to -WR / -WN }
  1038. RelocSection:=not UnsetBool(More,j);
  1039. RelocSectionSetExplicitly:=true;
  1040. end;
  1041. else
  1042. IllegalPara(opt);
  1043. end;
  1044. inc(j);
  1045. end;
  1046. end;
  1047. 'X' :
  1048. begin
  1049. j:=1;
  1050. while j<=length(more) do
  1051. begin
  1052. case More[j] of
  1053. 'i' :
  1054. include(initglobalswitches,cs_link_internal);
  1055. 'm' :
  1056. include(initglobalswitches,cs_link_map);
  1057. 'f' :
  1058. include(initglobalswitches,cs_link_pthread);
  1059. 's' :
  1060. include(initglobalswitches,cs_link_strip);
  1061. 'c' : Cshared:=TRUE;
  1062. 't' :
  1063. include(initglobalswitches,cs_link_staticflag);
  1064. 'D' :
  1065. begin
  1066. def_symbol('FPC_LINK_DYNAMIC');
  1067. undef_symbol('FPC_LINK_SMART');
  1068. undef_symbol('FPC_LINK_STATIC');
  1069. exclude(initglobalswitches,cs_link_static);
  1070. exclude(initglobalswitches,cs_link_smart);
  1071. include(initglobalswitches,cs_link_shared);
  1072. LinkTypeSetExplicitly:=true;
  1073. end;
  1074. 'd' : Dontlinkstdlibpath:=TRUE;
  1075. 'P' : Begin
  1076. utilsprefix:=Copy(more,2,length(More)-1);
  1077. More:='';
  1078. End;
  1079. 'r' : Begin
  1080. rlinkpath:=Copy(more,2,length(More)-1);
  1081. More:='';
  1082. end;
  1083. 'S' :
  1084. begin
  1085. def_symbol('FPC_LINK_STATIC');
  1086. undef_symbol('FPC_LINK_SMART');
  1087. undef_symbol('FPC_LINK_DYNAMIC');
  1088. include(initglobalswitches,cs_link_static);
  1089. exclude(initglobalswitches,cs_link_smart);
  1090. exclude(initglobalswitches,cs_link_shared);
  1091. LinkTypeSetExplicitly:=true;
  1092. end;
  1093. 'X' :
  1094. begin
  1095. def_symbol('FPC_LINK_SMART');
  1096. undef_symbol('FPC_LINK_STATIC');
  1097. undef_symbol('FPC_LINK_DYNAMIC');
  1098. exclude(initglobalswitches,cs_link_static);
  1099. include(initglobalswitches,cs_link_smart);
  1100. exclude(initglobalswitches,cs_link_shared);
  1101. LinkTypeSetExplicitly:=true;
  1102. end;
  1103. '-' :
  1104. begin
  1105. exclude(initglobalswitches,cs_link_staticflag);
  1106. exclude(initglobalswitches,cs_link_strip);
  1107. exclude(initglobalswitches,cs_link_map);
  1108. set_default_link_type;
  1109. end;
  1110. else
  1111. IllegalPara(opt);
  1112. end;
  1113. inc(j);
  1114. end;
  1115. end;
  1116. { give processor specific options a chance }
  1117. else
  1118. interpret_proc_specific_options(opt);
  1119. end;
  1120. end;
  1121. '@' :
  1122. begin
  1123. Message(option_no_nested_response_file);
  1124. StopOptions(1);
  1125. end;
  1126. else
  1127. begin
  1128. if (length(param_file)<>0) then
  1129. Message(option_only_one_source_support);
  1130. param_file:=opt;
  1131. Message1(option_found_file,opt);
  1132. end;
  1133. end;
  1134. end;
  1135. procedure Toption.Interpret_file(const filename : string);
  1136. procedure RemoveSep(var fn:string);
  1137. var
  1138. i : longint;
  1139. begin
  1140. i:=0;
  1141. while (i<length(fn)) and (fn[i+1] in [',',' ',#9]) do
  1142. inc(i);
  1143. Delete(fn,1,i);
  1144. i:=length(fn);
  1145. while (i>0) and (fn[i] in [',',' ',#9]) do
  1146. dec(i);
  1147. fn:=copy(fn,1,i);
  1148. end;
  1149. function GetName(var fn:string):string;
  1150. var
  1151. i : longint;
  1152. begin
  1153. i:=0;
  1154. while (i<length(fn)) and (fn[i+1] in ['a'..'z','A'..'Z','0'..'9','_','-']) do
  1155. inc(i);
  1156. GetName:=Copy(fn,1,i);
  1157. Delete(fn,1,i);
  1158. end;
  1159. const
  1160. maxlevel=16;
  1161. var
  1162. f : text;
  1163. s,
  1164. opts : string;
  1165. skip : array[0..maxlevel-1] of boolean;
  1166. level : longint;
  1167. option_read : boolean;
  1168. begin
  1169. { avoid infinite loop }
  1170. Inc(FileLevel);
  1171. Option_read:=false;
  1172. If FileLevel>MaxLevel then
  1173. Message(option_too_many_cfg_files);
  1174. { open file }
  1175. Message1(option_using_file,filename);
  1176. assign(f,filename);
  1177. {$I-}
  1178. reset(f);
  1179. {$I+}
  1180. if ioresult<>0 then
  1181. begin
  1182. Message1(option_unable_open_file,filename);
  1183. exit;
  1184. end;
  1185. Message1(option_start_reading_configfile,filename);
  1186. fillchar(skip,sizeof(skip),0);
  1187. level:=0;
  1188. while not eof(f) do
  1189. begin
  1190. readln(f,opts);
  1191. RemoveSep(opts);
  1192. if (opts<>'') and (opts[1]<>';') then
  1193. begin
  1194. if opts[1]='#' then
  1195. begin
  1196. Message1(option_interpreting_file_option,opts);
  1197. Delete(opts,1,1);
  1198. s:=upper(GetName(opts));
  1199. if (s='SECTION') then
  1200. begin
  1201. RemoveSep(opts);
  1202. s:=upper(GetName(opts));
  1203. if level=0 then
  1204. skip[level]:=not (check_symbol(s) or (s='COMMON'));
  1205. end
  1206. else
  1207. if (s='IFDEF') then
  1208. begin
  1209. RemoveSep(opts);
  1210. if Level>=maxlevel then
  1211. begin
  1212. Message(option_too_many_ifdef);
  1213. stopOptions(1);
  1214. end;
  1215. inc(Level);
  1216. skip[level]:=(skip[level-1] or (not check_symbol(upper(GetName(opts)))));
  1217. end
  1218. else
  1219. if (s='IFNDEF') then
  1220. begin
  1221. RemoveSep(opts);
  1222. if Level>=maxlevel then
  1223. begin
  1224. Message(option_too_many_ifdef);
  1225. stopOptions(1);
  1226. end;
  1227. inc(Level);
  1228. skip[level]:=(skip[level-1] or (check_symbol(upper(GetName(opts)))));
  1229. end
  1230. else
  1231. if (s='ELSE') then
  1232. skip[level]:=skip[level-1] or (not skip[level])
  1233. else
  1234. if (s='ENDIF') then
  1235. begin
  1236. skip[level]:=false;
  1237. if Level=0 then
  1238. begin
  1239. Message(option_too_many_endif);
  1240. stopOptions(1);
  1241. end;
  1242. dec(level);
  1243. end
  1244. else
  1245. if (not skip[level]) then
  1246. begin
  1247. if (s='DEFINE') then
  1248. begin
  1249. RemoveSep(opts);
  1250. def_symbol(upper(GetName(opts)));
  1251. end
  1252. else
  1253. if (s='UNDEF') then
  1254. begin
  1255. RemoveSep(opts);
  1256. undef_symbol(upper(GetName(opts)));
  1257. end
  1258. else
  1259. if (s='WRITE') then
  1260. begin
  1261. Delete(opts,1,1);
  1262. WriteLn(opts);
  1263. end
  1264. else
  1265. if (s='INCLUDE') then
  1266. begin
  1267. Delete(opts,1,1);
  1268. Interpret_file(opts);
  1269. end;
  1270. end;
  1271. end
  1272. else
  1273. begin
  1274. if (opts[1]='-') or (opts[1]='@') then
  1275. begin
  1276. if (not skip[level]) then
  1277. interpret_option(opts,false);
  1278. Option_read:=true;
  1279. end
  1280. else
  1281. Message1(option_illegal_para,opts);
  1282. end;
  1283. end;
  1284. end;
  1285. if Level>0 then
  1286. Message(option_too_less_endif);
  1287. if Not Option_read then
  1288. Message1(option_no_option_found,filename)
  1289. else
  1290. Message1(option_end_reading_configfile,filename);
  1291. Close(f);
  1292. Dec(FileLevel);
  1293. end;
  1294. procedure Toption.Interpret_envvar(const envname : string);
  1295. var
  1296. argstart,
  1297. env,
  1298. pc : pchar;
  1299. arglen : longint;
  1300. quote : set of char;
  1301. hs : string;
  1302. begin
  1303. Message1(option_using_env,envname);
  1304. env:=GetEnvPChar(envname);
  1305. pc:=env;
  1306. if assigned(pc) then
  1307. begin
  1308. repeat
  1309. { skip leading spaces }
  1310. while pc^ in [' ',#9,#13] do
  1311. inc(pc);
  1312. case pc^ of
  1313. #0 :
  1314. break;
  1315. '"' :
  1316. begin
  1317. quote:=['"'];
  1318. inc(pc);
  1319. end;
  1320. '''' :
  1321. begin
  1322. quote:=[''''];
  1323. inc(pc);
  1324. end;
  1325. else
  1326. quote:=[' ',#9,#13];
  1327. end;
  1328. { scan until the end of the argument }
  1329. argstart:=pc;
  1330. while (pc^<>#0) and not(pc^ in quote) do
  1331. inc(pc);
  1332. { create argument }
  1333. arglen:=pc-argstart;
  1334. hs[0]:=chr(arglen);
  1335. move(argstart^,hs[1],arglen);
  1336. interpret_option(hs,true);
  1337. { skip quote }
  1338. if pc^ in quote then
  1339. inc(pc);
  1340. until false;
  1341. end
  1342. else
  1343. Message1(option_no_option_found,'(env) '+envname);
  1344. FreeEnvPChar(env);
  1345. end;
  1346. procedure toption.read_parameters;
  1347. var
  1348. opts : string;
  1349. paramindex : longint;
  1350. begin
  1351. paramindex:=0;
  1352. while paramindex<paramcount do
  1353. begin
  1354. inc(paramindex);
  1355. opts:=system.paramstr(paramindex);
  1356. case opts[1] of
  1357. '@' :
  1358. if not firstpass then
  1359. begin
  1360. Delete(opts,1,1);
  1361. Message1(option_reading_further_from,opts);
  1362. interpret_file(opts);
  1363. end;
  1364. '!' :
  1365. if not firstpass then
  1366. begin
  1367. Delete(opts,1,1);
  1368. Message1(option_reading_further_from,'(env) '+opts);
  1369. interpret_envvar(opts);
  1370. end;
  1371. else
  1372. interpret_option(opts,true);
  1373. end;
  1374. end;
  1375. end;
  1376. procedure toption.parsecmd(cmd:string);
  1377. var
  1378. i,ps : longint;
  1379. opts : string;
  1380. begin
  1381. while (cmd<>'') do
  1382. begin
  1383. while cmd[1]=' ' do
  1384. delete(cmd,1,1);
  1385. i:=pos(' ',cmd);
  1386. if i=0 then
  1387. i:=256;
  1388. opts:=Copy(cmd,1,i-1);
  1389. Delete(cmd,1,i);
  1390. case opts[1] of
  1391. '@' :
  1392. if not firstpass then
  1393. begin
  1394. Delete(opts,1,1);
  1395. Message1(option_reading_further_from,opts);
  1396. interpret_file(opts);
  1397. end;
  1398. '!' :
  1399. if not firstpass then
  1400. begin
  1401. Delete(opts,1,1);
  1402. Message1(option_reading_further_from,'(env) '+opts);
  1403. interpret_envvar(opts);
  1404. end;
  1405. '"' :
  1406. begin
  1407. Delete(opts,1,1);
  1408. ps:=pos('"',cmd);
  1409. if (i<>256) and (ps>0) then
  1410. begin
  1411. opts:=opts + ' '+ copy(cmd,1,ps-1);
  1412. cmd:=copy(cmd,ps+1,255);
  1413. end;
  1414. interpret_option(opts,true);
  1415. end;
  1416. else
  1417. interpret_option(opts,true);
  1418. end;
  1419. end;
  1420. end;
  1421. procedure toption.writequickinfo;
  1422. var
  1423. s : string;
  1424. i : longint;
  1425. procedure addinfo(const hs:string);
  1426. begin
  1427. if s<>'' then
  1428. s:=s+' '+hs
  1429. else
  1430. s:=hs;
  1431. end;
  1432. begin
  1433. s:='';
  1434. i:=0;
  1435. while (i<length(quickinfo)) do
  1436. begin
  1437. inc(i);
  1438. case quickinfo[i] of
  1439. 'S' :
  1440. begin
  1441. inc(i);
  1442. case quickinfo[i] of
  1443. 'O' :
  1444. addinfo(lower(source_info.shortname));
  1445. {$ifdef Delphi}
  1446. 'P' :
  1447. addinfo('i386');
  1448. {$else Delphi}
  1449. 'P' :
  1450. addinfo(source_cpu_string);
  1451. {$endif Delphi}
  1452. else
  1453. IllegalPara('-i'+QuickInfo);
  1454. end;
  1455. end;
  1456. 'T' :
  1457. begin
  1458. inc(i);
  1459. case quickinfo[i] of
  1460. 'O' :
  1461. addinfo(lower(target_info.shortname));
  1462. 'P' :
  1463. AddInfo(target_cpu_string);
  1464. else
  1465. IllegalPara('-i'+QuickInfo);
  1466. end;
  1467. end;
  1468. 'V' :
  1469. AddInfo(version_string);
  1470. 'D' :
  1471. AddInfo(date_string);
  1472. '_' :
  1473. ;
  1474. else
  1475. IllegalPara('-i'+QuickInfo);
  1476. end;
  1477. end;
  1478. if s<>'' then
  1479. begin
  1480. writeln(s);
  1481. stopoptions(0);
  1482. end;
  1483. end;
  1484. procedure TOption.TargetDefines(def:boolean);
  1485. var
  1486. s : string;
  1487. i : integer;
  1488. begin
  1489. if def then
  1490. def_symbol(upper(target_info.shortname))
  1491. else
  1492. undef_symbol(upper(target_info.shortname));
  1493. s:=target_info.extradefines;
  1494. while (s<>'') do
  1495. begin
  1496. i:=pos(';',s);
  1497. if i=0 then
  1498. i:=length(s)+1;
  1499. if def then
  1500. def_symbol(Copy(s,1,i-1))
  1501. else
  1502. undef_symbol(Copy(s,1,i-1));
  1503. delete(s,1,i);
  1504. end;
  1505. end;
  1506. constructor TOption.create;
  1507. begin
  1508. DoWriteLogo:=false;
  1509. NoPressEnter:=false;
  1510. FirstPass:=false;
  1511. FileLevel:=0;
  1512. Quickinfo:='';
  1513. ParaIncludePath:=TSearchPathList.Create;
  1514. ParaObjectPath:=TSearchPathList.Create;
  1515. ParaUnitPath:=TSearchPathList.Create;
  1516. ParaLibraryPath:=TSearchPathList.Create;
  1517. FillChar(ParaAlignment,sizeof(ParaAlignment),0);
  1518. end;
  1519. destructor TOption.destroy;
  1520. begin
  1521. ParaIncludePath.Free;
  1522. ParaObjectPath.Free;
  1523. ParaUnitPath.Free;
  1524. ParaLibraryPath.Free;
  1525. end;
  1526. {****************************************************************************
  1527. Callable Routines
  1528. ****************************************************************************}
  1529. function check_configfile(const fn:string;var foundfn:string):boolean;
  1530. function CfgFileExists(const fn:string):boolean;
  1531. begin
  1532. Comment(V_Tried,'Configfile search: '+fn);
  1533. CfgFileExists:=FileExists(fn);
  1534. end;
  1535. var
  1536. configpath : pathstr;
  1537. begin
  1538. foundfn:=fn;
  1539. check_configfile:=true;
  1540. { retrieve configpath }
  1541. {$ifdef Delphi}
  1542. configpath:=FixPath(dmisc.getenv('PPC_CONFIG_PATH'),false);
  1543. {$else Delphi}
  1544. configpath:=FixPath(dos.getenv('PPC_CONFIG_PATH'),false);
  1545. {$endif Delphi}
  1546. {$ifdef Unix}
  1547. if configpath='' then
  1548. configpath:='/etc/';
  1549. {$endif}
  1550. {
  1551. Order to read configuration file :
  1552. try reading fpc.cfg in :
  1553. 1 - current dir
  1554. 2 - configpath
  1555. 3 - compiler path
  1556. }
  1557. if not FileExists(fn) then
  1558. begin
  1559. {$ifdef Unix}
  1560. if (dos.getenv('HOME')<>'') and CfgFileExists(FixPath(dos.getenv('HOME'),false)+'.'+fn) then
  1561. foundfn:=FixPath(dos.getenv('HOME'),false)+'.'+fn
  1562. else
  1563. {$endif}
  1564. if CfgFileExists(configpath+fn) then
  1565. foundfn:=configpath+fn
  1566. else
  1567. {$ifndef Unix}
  1568. if CfgFileExists(exepath+fn) then
  1569. foundfn:=exepath+fn
  1570. else
  1571. {$endif}
  1572. check_configfile:=false;
  1573. end;
  1574. end;
  1575. procedure read_arguments(cmd:string);
  1576. begin
  1577. option:=coption.create;
  1578. disable_configfile:=false;
  1579. { default defines }
  1580. def_symbol(upper(target_info.shortname));
  1581. def_symbol('FPC');
  1582. def_symbol('VER'+version_nr);
  1583. def_symbol('VER'+version_nr+'_'+release_nr);
  1584. def_symbol('VER'+version_nr+'_'+release_nr+'_'+patch_nr);
  1585. { Temporary defines, until things settle down }
  1586. def_symbol('HASWIDECHAR');
  1587. def_symbol('HASWIDESTRING');
  1588. def_symbol('HASOUT');
  1589. def_symbol('HASGLOBALPROPERTY');
  1590. def_symbol('FPC_HASPREFETCH');
  1591. {$ifdef i386}
  1592. def_symbol('HASINTF');
  1593. def_symbol('HASVARIANT');
  1594. {$endif i386}
  1595. {$ifdef x86_64}
  1596. def_symbol('HASINTF');
  1597. def_symbol('HASVARIANT');
  1598. {$endif x86_64}
  1599. {$ifdef powerpc}
  1600. def_symbol('HASINTF');
  1601. def_symbol('HASVARIANT');
  1602. def_symbol('FPC_MTFSB0_CORRECTED');
  1603. {$endif powerpc}
  1604. {$ifdef arm}
  1605. def_symbol('HASINTF');
  1606. def_symbol('HASVARIANT');
  1607. {$endif arm}
  1608. {$ifdef sparc}
  1609. def_symbol('HASINTF');
  1610. def_symbol('HASVARIANT');
  1611. {$endif sparc}
  1612. def_symbol('INTERNSETLENGTH');
  1613. def_symbol('INTERNLENGTH');
  1614. def_symbol('INTERNCOPY');
  1615. def_symbol('INT64FUNCRESOK');
  1616. def_symbol('HAS_ADDR_STACK_ON_STACK');
  1617. def_symbol('NOBOUNDCHECK');
  1618. def_symbol('HASCOMPILERPROC');
  1619. def_symbol('VALUEGETMEM');
  1620. def_symbol('VALUEFREEMEM');
  1621. def_symbol('HASCURRENCY');
  1622. def_symbol('HASTHREADVAR');
  1623. def_symbol('HAS_GENERICCONSTRUCTOR');
  1624. def_symbol('NOCLASSHELPERS');
  1625. if pocall_default = pocall_register then
  1626. def_symbol('REGCALL');
  1627. def_symbol('DECRREFNOTNIL');
  1628. def_symbol('HAS_INTERNAL_INTTYPES');
  1629. def_symbol('STR_USES_VALINT');
  1630. { using a case is pretty useless here (FK) }
  1631. { some stuff for TP compatibility }
  1632. {$ifdef i386}
  1633. def_symbol('CPU86');
  1634. def_symbol('CPU87');
  1635. {$endif}
  1636. {$ifdef m68k}
  1637. def_symbol('CPU68');
  1638. {$endif}
  1639. { new processor stuff }
  1640. {$ifdef i386}
  1641. def_symbol('CPUI386');
  1642. def_symbol('CPU32');
  1643. def_symbol('FPC_HAS_TYPE_EXTENDED');
  1644. def_symbol('FPC_HAS_TYPE_DOUBLE');
  1645. def_symbol('FPC_HAS_TYPE_SINGLE');
  1646. {$endif}
  1647. {$ifdef m68k}
  1648. def_symbol('CPU68K');
  1649. def_symbol('CPUM68K');
  1650. def_symbol('CPU32');
  1651. def_symbol('FPC_CURRENCY_IS_INT64');
  1652. def_symbol('FPC_COMP_IS_INT64');
  1653. {$endif}
  1654. {$ifdef ALPHA}
  1655. def_symbol('CPUALPHA');
  1656. def_symbol('CPU64');
  1657. {$endif}
  1658. {$ifdef powerpc}
  1659. def_symbol('CPUPOWERPC');
  1660. def_symbol('CPUPOWERPC32');
  1661. def_symbol('CPU32');
  1662. def_symbol('FPC_HAS_TYPE_DOUBLE');
  1663. def_symbol('FPC_HAS_TYPE_SINGLE');
  1664. def_symbol('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
  1665. def_symbol('FPC_CURRENCY_IS_INT64');
  1666. def_symbol('FPC_COMP_IS_INT64');
  1667. {$endif}
  1668. {$ifdef iA64}
  1669. def_symbol('CPUIA64');
  1670. def_symbol('CPU64');
  1671. {$endif}
  1672. {$ifdef x86_64}
  1673. def_symbol('CPUX86_64');
  1674. def_symbol('CPUAMD64');
  1675. def_symbol('CPU64');
  1676. { not supported for now, afaik (FK)
  1677. def_symbol('FPC_HAS_TYPE_FLOAT128'); }
  1678. def_symbol('FPC_HAS_TYPE_EXTENDED');
  1679. def_symbol('FPC_HAS_TYPE_DOUBLE');
  1680. def_symbol('FPC_HAS_TYPE_SINGLE');
  1681. {$endif}
  1682. {$ifdef sparc}
  1683. def_symbol('CPUSPARC');
  1684. def_symbol('CPUSPARC32');
  1685. def_symbol('CPU32');
  1686. def_symbol('FPC_HAS_TYPE_DOUBLE');
  1687. def_symbol('FPC_HAS_TYPE_SINGLE');
  1688. def_symbol('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
  1689. def_symbol('FPC_CURRENCY_IS_INT64');
  1690. def_symbol('FPC_COMP_IS_INT64');
  1691. def_symbol('FPC_REQUIRES_PROPER_ALIGNMENT');
  1692. {$endif}
  1693. {$ifdef vis}
  1694. def_symbol('CPUVIS');
  1695. def_symbol('CPU32');
  1696. {$endif}
  1697. {$ifdef arm}
  1698. def_symbol('CPUARM');
  1699. def_symbol('CPU32');
  1700. def_symbol('FPC_HAS_TYPE_DOUBLE');
  1701. def_symbol('FPC_HAS_TYPE_SINGLE');
  1702. def_symbol('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
  1703. def_symbol('FPC_CURRENCY_IS_INT64');
  1704. def_symbol('FPC_COMP_IS_INT64');
  1705. def_symbol('FPC_REQUIRES_PROPER_ALIGNMENT');
  1706. {$endif arm}
  1707. { get default messagefile }
  1708. {$ifdef Delphi}
  1709. msgfilename:=dmisc.getenv('PPC_ERROR_FILE');
  1710. {$else Delphi}
  1711. msgfilename:=dos.getenv('PPC_ERROR_FILE');
  1712. {$endif Delphi}
  1713. { default configfile can be specified on the commandline,
  1714. remove it first }
  1715. if (cmd<>'') and (cmd[1]='[') then
  1716. begin
  1717. ppccfg:=Copy(cmd,2,pos(']',cmd)-2);
  1718. Delete(cmd,1,pos(']',cmd));
  1719. end
  1720. else
  1721. begin
  1722. ppccfg:='fpc.cfg';
  1723. ppcaltcfg:='ppc386.cfg';
  1724. end;
  1725. { read the parameters quick, only -i -v -T }
  1726. option.firstpass:=true;
  1727. if cmd<>'' then
  1728. option.parsecmd(cmd)
  1729. else
  1730. begin
  1731. option.read_parameters;
  1732. { Write only quickinfo }
  1733. if option.quickinfo<>'' then
  1734. option.writequickinfo;
  1735. end;
  1736. option.firstpass:=false;
  1737. { read configuration file }
  1738. if (not disable_configfile) and
  1739. (ppccfg<>'') then
  1740. begin
  1741. read_configfile:=check_configfile(ppccfg,ppccfg);
  1742. { Maybe alternative configfile ? }
  1743. if (not read_configfile) and
  1744. (ppcaltcfg<>'') then
  1745. read_configfile:=check_configfile(ppcaltcfg,ppccfg);
  1746. end
  1747. else
  1748. read_configfile := false;
  1749. { Read commandline and configfile }
  1750. target_is_set:=false;
  1751. asm_is_set:=false;
  1752. param_file:='';
  1753. { read configfile }
  1754. if read_configfile then
  1755. option.interpret_file(ppccfg);
  1756. { read parameters again to override config file }
  1757. if cmd<>'' then
  1758. option.parsecmd(cmd)
  1759. else
  1760. begin
  1761. option.read_parameters;
  1762. { Write only quickinfo }
  1763. if option.quickinfo<>'' then
  1764. option.writequickinfo;
  1765. end;
  1766. { Write help pages }
  1767. if (cmd='') and (paramcount=0) then
  1768. Option.WriteHelpPages;
  1769. { Stop if errors in options }
  1770. if ErrorCount>0 then
  1771. StopOptions(1);
  1772. { Non-core target defines }
  1773. Option.TargetDefines(true);
  1774. { endian define }
  1775. case target_info.endian of
  1776. endian_little :
  1777. begin
  1778. def_symbol('ENDIAN_LITTLE');
  1779. def_symbol('FPC_LITTLE_ENDIAN');
  1780. end;
  1781. endian_big :
  1782. begin
  1783. def_symbol('ENDIAN_BIG');
  1784. def_symbol('FPC_BIG_ENDIAN');
  1785. end;
  1786. end;
  1787. { abi define }
  1788. case target_info.abi of
  1789. abi_powerpc_sysv :
  1790. def_symbol('FPC_ABI_SYSV');
  1791. abi_powerpc_aix :
  1792. def_symbol('FPC_ABI_AIX');
  1793. end;
  1794. {$ifdef m68k}
  1795. if initoptprocessor=MC68020 then
  1796. def_symbol('CPUM68020');
  1797. {$endif m68k}
  1798. { write logo if set }
  1799. if option.DoWriteLogo then
  1800. option.WriteLogo;
  1801. { Check file to compile }
  1802. if param_file='' then
  1803. begin
  1804. Message(option_no_source_found);
  1805. StopOptions(1);
  1806. end;
  1807. {$ifndef Unix}
  1808. param_file:=FixFileName(param_file);
  1809. {$endif}
  1810. fsplit(param_file,inputdir,inputfile,inputextension);
  1811. if inputextension='' then
  1812. begin
  1813. if FileExists(inputdir+inputfile+target_info.sourceext) then
  1814. inputextension:=target_info.sourceext
  1815. else if FileExists(inputdir+inputfile+target_info.pasext) then
  1816. inputextension:=target_info.pasext
  1817. else if (m_mac in aktmodeswitches) and FileExists(inputdir+inputfile+'.p') then
  1818. inputextension:='.p';
  1819. end;
  1820. { Check output dir }
  1821. if (OutputExeDir<>'') and
  1822. not PathExists(OutputExeDir) then
  1823. begin
  1824. Message1(general_e_path_does_not_exists,OutputExeDir);
  1825. StopOptions(1);
  1826. end;
  1827. { Add paths specified with parameters to the searchpaths }
  1828. UnitSearchPath.AddList(option.ParaUnitPath,true);
  1829. ObjectSearchPath.AddList(option.ParaObjectPath,true);
  1830. IncludeSearchPath.AddList(option.ParaIncludePath,true);
  1831. LibrarySearchPath.AddList(option.ParaLibraryPath,true);
  1832. { add unit environment and exepath to the unit search path }
  1833. if inputdir<>'' then
  1834. Unitsearchpath.AddPath(inputdir,true);
  1835. if not disable_configfile then
  1836. begin
  1837. {$ifdef Delphi}
  1838. UnitSearchPath.AddPath(dmisc.getenv(target_info.unit_env),false);
  1839. {$else}
  1840. UnitSearchPath.AddPath(dos.getenv(target_info.unit_env),false);
  1841. {$endif Delphi}
  1842. end;
  1843. {$ifdef Unix}
  1844. fpcdir:=FixPath(getenv('FPCDIR'),false);
  1845. if fpcdir='' then
  1846. begin
  1847. if source_info.cpu<>target_info.cpu then
  1848. begin
  1849. if PathExists('/usr/local/lib/fpc/'+version_string+'/cross/'+cpu2str[target_info.cpu]+'-'+target_info.shortname) then
  1850. fpcdir:='/usr/local/lib/fpc/'+version_string+'/cross/'+cpu2str[target_info.cpu]+'-'+target_info.shortname+'/'
  1851. else
  1852. fpcdir:='/usr/lib/fpc/'+version_string+'/cross/'+cpu2str[target_info.cpu]+'-'+target_info.shortname+'/';
  1853. end
  1854. else
  1855. begin
  1856. if PathExists('/usr/local/lib/fpc/'+version_string) then
  1857. fpcdir:='/usr/local/lib/fpc/'+version_string+'/'
  1858. else
  1859. fpcdir:='/usr/lib/fpc/'+version_string+'/';
  1860. end;
  1861. end;
  1862. {$else}
  1863. fpcdir:=FixPath(getenv('FPCDIR'),false);
  1864. if fpcdir='' then
  1865. begin
  1866. fpcdir:=ExePath+'../';
  1867. if not(PathExists(fpcdir+'/units')) and
  1868. not(PathExists(fpcdir+'/rtl')) then
  1869. fpcdir:=fpcdir+'../';
  1870. end;
  1871. {$endif}
  1872. { first try development RTL, else use the default installation path }
  1873. if not disable_configfile then
  1874. begin
  1875. if source_info.cpu<>target_info.cpu then
  1876. begin
  1877. if PathExists(FpcDir+'rtl/'+lower(target_info.shortname)) then
  1878. UnitSearchPath.AddPath(FpcDir+'rtl/'+lower(target_info.shortname),false)
  1879. else
  1880. begin
  1881. UnitSearchPath.AddPath(FpcDir+'units/',false);
  1882. UnitSearchPath.AddPath(FpcDir+'units/rtl',false);
  1883. end;
  1884. end
  1885. else
  1886. begin
  1887. if PathExists(FpcDir+'rtl/'+lower(target_info.shortname)) then
  1888. UnitSearchPath.AddPath(FpcDir+'rtl/'+lower(target_info.shortname),false)
  1889. else
  1890. begin
  1891. UnitSearchPath.AddPath(FpcDir+'units/'+lower(target_info.shortname),false);
  1892. UnitSearchPath.AddPath(FpcDir+'units/'+lower(target_info.shortname)+'/rtl',false);
  1893. end;
  1894. end;
  1895. end;
  1896. { Add exepath if the exe is not in the current dir, because that is always searched already.
  1897. Do not add it when linking on the target because then we can maybe already find
  1898. .o files that are not for the target }
  1899. if (ExePath<>GetCurrentDir) and
  1900. not(cs_link_on_target in initglobalswitches) then
  1901. UnitSearchPath.AddPath(ExePath,false);
  1902. { Add unit dir to the object and library path }
  1903. objectsearchpath.AddList(unitsearchpath,false);
  1904. librarysearchpath.AddList(unitsearchpath,false);
  1905. { switch assembler if it's binary and we got -a on the cmdline }
  1906. if (cs_asm_leave in initglobalswitches) and
  1907. (af_outputbinary in target_asm.flags) then
  1908. begin
  1909. Message(option_switch_bin_to_src_assembler);
  1910. set_target_asm(target_info.assemextern);
  1911. end;
  1912. if (target_asm.supported_target <> system_any) and
  1913. (target_asm.supported_target <> target_info.system) then
  1914. begin
  1915. Message2(option_incompatible_asm,target_asm.idtxt,target_info.name);
  1916. set_target_asm(target_info.assemextern);
  1917. Message1(option_asm_forced,target_asm.idtxt);
  1918. end;
  1919. { turn off stripping if compiling with debuginfo or profile }
  1920. if (cs_debuginfo in initmoduleswitches) or
  1921. (cs_profile in initmoduleswitches) then
  1922. exclude(initglobalswitches,cs_link_strip);
  1923. {$ifdef x86_64}
  1924. {$warning HACK: turn off smartlinking}
  1925. exclude(initmoduleswitches,cs_create_smart);
  1926. {$endif}
  1927. if not LinkTypeSetExplicitly then
  1928. set_default_link_type;
  1929. { Default alignment settings,
  1930. 1. load the defaults for the target
  1931. 2. override with generic optimizer setting (little size)
  1932. 3. override with the user specified -Oa }
  1933. UpdateAlignment(initalignment,target_info.alignment);
  1934. if (cs_littlesize in aktglobalswitches) then
  1935. begin
  1936. initalignment.procalign:=1;
  1937. initalignment.jumpalign:=1;
  1938. initalignment.loopalign:=1;
  1939. end;
  1940. UpdateAlignment(initalignment,option.paraalignment);
  1941. option.free;
  1942. Option:=nil;
  1943. end;
  1944. initialization
  1945. coption:=toption;
  1946. finalization
  1947. if assigned(option) then
  1948. option.free;
  1949. end.
  1950. {
  1951. $Log$
  1952. Revision 1.143 2004-09-21 17:25:12 peter
  1953. * paraloc branch merged
  1954. Revision 1.142 2004/09/16 16:31:53 peter
  1955. * Use FExpand on paths passed to compiler
  1956. Revision 1.141 2004/09/10 21:00:23 jonas
  1957. * exit with exit code 0 instead of 1 after writing out quick options
  1958. (such as -iV)
  1959. Revision 1.140 2004/09/08 11:23:31 michael
  1960. + Check if outputdir exists, Fix exitcode when displaying help pages
  1961. Revision 1.139.4.1 2004/09/19 20:53:33 peter
  1962. * fixed compile without gdb
  1963. Revision 1.139 2004/08/27 21:59:26 peter
  1964. browser disabled
  1965. uf_local_symtable ppu flag when a localsymtable is stored
  1966. Revision 1.138 2004/07/05 21:26:28 olle
  1967. + allow fileextension .p, in mode macpas
  1968. Revision 1.137 2004/07/04 12:24:04 jonas
  1969. * fixed "-g-l" (and other "-g-*" combinations)
  1970. Revision 1.136 2004/06/20 08:55:30 florian
  1971. * logs truncated
  1972. Revision 1.135 2004/06/16 20:07:09 florian
  1973. * dwarf branch merged
  1974. Revision 1.134 2004/05/06 20:30:51 florian
  1975. * m68k compiler compilation fixed
  1976. Revision 1.133.2.10 2004/05/18 20:24:03 florian
  1977. * fixed crash with unknown symbols
  1978. Revision 1.133.2.9 2004/05/13 20:10:38 florian
  1979. * released variant and interface support
  1980. Revision 1.133.2.8 2004/05/03 14:59:57 peter
  1981. * no dlltool needed for win32 linking executables
  1982. }