options.pas 53 KB

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