fpswitch.pas 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998-2000 by Berczi Gabor
  4. Compiler switches routines for the IDE
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit FPSwitch;
  12. interface
  13. uses
  14. Objects,
  15. Systems,
  16. WUtils,
  17. FPConst;
  18. const
  19. MinMemSize = 1024; { min. local heap and stack size }
  20. MaxMemSize = 67107840; { max. local heap and stack size }
  21. type
  22. TParamID =
  23. (idNone,idAlign,idRangeChecks,idStackChecks,idIOChecks,
  24. idOverflowChecks,idObjMethCallChecks,
  25. idAsmDirect,idAsmATT,idAsmIntel,idAsmMot,
  26. idSymInfNone,idSymInfGlobalOnly,idSymInfGlobalLocal,
  27. idStackSize,idHeapSize,idStrictVarStrings,idExtendedSyntax,
  28. idMMXOps,idTypedAddress,idPackRecords,idPackEnum,idStackFrames,
  29. idReferenceInfo,idDebugInfo,idBoolEval,
  30. idLongString,idTypeInfo);
  31. TSwitchMode = (om_Normal,om_Debug,om_Release);
  32. TSwitchItemTyp = (ot_Select,ot_Boolean,ot_String,ot_MultiString,ot_Longint);
  33. PSwitchItem = ^TSwitchItem;
  34. TSwitchItem = object(TObject)
  35. Typ : TSwitchItemTyp;
  36. Name : string[50];
  37. Param : string[10];
  38. ParamID : TParamID;
  39. constructor Init(const n,p:string; AID: TParamID);
  40. function NeedParam:boolean;virtual;
  41. function ParamValue(nr:sw_integer):string;virtual;
  42. function ParamValueBool(SM: TSwitchMode):boolean;virtual;
  43. function ParamCount:sw_integer;virtual;
  44. function GetSwitchStr(SM: TSwitchMode): string; virtual;
  45. function GetNumberStr(SM: TSwitchMode): string; virtual;
  46. function GetOptionStr(SM: TSwitchMode): string; virtual;
  47. procedure Reset;virtual;
  48. end;
  49. PSelectItem = ^TSelectItem;
  50. TSelectItem = object(TSwitchItem)
  51. IsDefault : boolean;
  52. constructor Init(const n,p:string; AID: TParamID);
  53. { Select to avoid anything in config file }
  54. constructor InitDefault(const n:string);
  55. end;
  56. PBooleanItem = ^TBooleanItem;
  57. TBooleanItem = object(TSwitchItem)
  58. IsSet : array[TSwitchMode] of boolean;
  59. constructor Init(const n,p:string; AID: TParamID);
  60. function NeedParam:boolean;virtual;
  61. procedure Reset;virtual;
  62. function GetSwitchStr(SM: TSwitchMode): string; virtual;
  63. function ParamValueBool(SM: TSwitchMode):boolean;virtual;
  64. end;
  65. PStringItem = ^TStringItem;
  66. TStringItem = object(TSwitchItem)
  67. Str : array[TSwitchMode] of string;
  68. multiple : boolean;
  69. SeparateSpaces : boolean;
  70. constructor Init(const n,p:string;AID: TParamID; mult,allowspaces:boolean);
  71. function NeedParam:boolean;virtual;
  72. function ParamValue(nr:sw_integer):string;virtual;
  73. procedure Reset;virtual;
  74. end;
  75. PMultiStringItem = ^TMultiStringItem;
  76. TMultiStringItem = object(TSwitchItem)
  77. MultiStr : array[TSwitchMode] of PunsortedStringCollection;
  78. constructor Init(const n,p:string;AID: TParamID);
  79. function NeedParam:boolean;virtual;
  80. function ParamValue(nr:sw_integer):string;virtual;
  81. function ParamCount:sw_integer;virtual;
  82. procedure Reset;virtual;
  83. destructor done;virtual;
  84. end;
  85. PLongintItem = ^TLongintItem;
  86. TLongintItem = object(TSwitchItem)
  87. Val : array[TSwitchMode] of longint;
  88. constructor Init(const n,p:string; AID: TParamID);
  89. function NeedParam:boolean;virtual;
  90. function ParamValue:string;virtual;
  91. function GetNumberStr(SM: TSwitchMode): string; virtual;
  92. procedure Reset;virtual;
  93. end;
  94. PSwitches = ^TSwitches;
  95. TSwitches = object
  96. constructor Init(ch:char);
  97. constructor InitSelect(ch:char);
  98. destructor Done;
  99. { general items }
  100. function ItemCount:integer;
  101. function ItemName(index:integer):string;
  102. function ItemParam(index:integer):string;
  103. { type specific }
  104. procedure AddSelectItem(const name,param:string; AID: TParamID);
  105. procedure AddDefaultSelect(const name:string);
  106. procedure AddBooleanItem(const name,param:string; AID: TParamID);
  107. procedure AddLongintItem(const name,param:string; AID: TParamID);
  108. procedure AddStringItem(const name,param:string;AID: TParamID;mult,allowspaces:boolean);
  109. procedure AddMultiStringItem(const name,param:string;AID: TParamID);
  110. function GetCurrSel:integer;
  111. function GetCurrSelParam : String;
  112. function GetBooleanItem(index:integer):boolean;
  113. function GetLongintItem(index:integer):longint;
  114. function GetStringItem(index:integer):string;
  115. function GetMultiStringItem(index:integer):PunsortedStringCollection;
  116. function GetItemTyp(index:integer):TSwitchItemTyp;
  117. procedure SetCurrSel(index:integer);
  118. function SetCurrSelParam(const s:string) : boolean;
  119. procedure SetBooleanItem(index:integer;b:boolean);
  120. procedure SetLongintItem(index:integer;l:longint);
  121. procedure SetStringItem(index:integer;const s:string);
  122. { read / write to cfgfile which must be open }
  123. procedure WriteItemsCfg;
  124. function ReadItemsCfg(const s:string):boolean;
  125. private
  126. IsSel : boolean;
  127. Prefix : char;
  128. SelNr : array[TSwitchMode] of integer;
  129. Items : PCollection;
  130. end;
  131. const
  132. SwitchesMode : TSwitchMode = om_Normal;
  133. SwitchesModeName : array[TSwitchMode] of string[10]=
  134. ('~N~ormal','~D~ebug','~R~elease');
  135. SwitchesModeStr : array[TSwitchMode] of string[8]=
  136. ('NORMAL','DEBUG','RELEASE');
  137. CustomArg : array[TSwitchMode] of string{$ifndef FPC}[128]{$endif}=
  138. ('','','');
  139. var
  140. LibLinkerSwitches,
  141. OtherLinkerSwitches,
  142. DebugInfoSwitches,
  143. LinkAfterSwitches,
  144. ProfileInfoSwitches,
  145. {MemorySizeSwitches, doubled !! }
  146. SyntaxSwitches,
  147. CompilerModeSwitches,
  148. VerboseSwitches,
  149. CodegenSwitches,
  150. OptimizationSwitches,
  151. OptimizingGoalSwitches,
  152. ProcessorSwitches,
  153. AsmReaderSwitches,
  154. AsmInfoSwitches,
  155. AsmOutputSwitches,
  156. TargetSwitches,
  157. ConditionalSwitches,
  158. MemorySwitches,
  159. BrowserSwitches,
  160. DirectorySwitches : PSwitches;
  161. { write/read the Switches to fpc.cfg file }
  162. procedure WriteSwitches(const fn:string);
  163. procedure ReadSwitches(const fn:string);
  164. { initialize }
  165. procedure InitSwitches;
  166. procedure SetDefaultSwitches;
  167. procedure DoneSwitches;
  168. function GetSourceDirectories : string;
  169. procedure GetCompilerOptionLines(C: PUnsortedStringCollection);
  170. implementation
  171. uses
  172. Dos,
  173. GlobType,
  174. FPString,FPVars,FPUtils;
  175. var
  176. CfgFile : text;
  177. {*****************************************************************************
  178. TSwitchItem
  179. *****************************************************************************}
  180. constructor TSwitchItem.Init(const n,p:string; AID: TParamID);
  181. begin
  182. Inherited Init;
  183. Name:=n;
  184. Param:=p;
  185. ParamID:=AID;
  186. end;
  187. function TSwitchItem.NeedParam:boolean;
  188. begin
  189. NeedParam:=false;
  190. end;
  191. function TSwitchItem.ParamValue(nr:sw_integer):string;
  192. begin
  193. ParamValue:='';
  194. end;
  195. function TSwitchItem.ParamValueBool(SM: TSwitchMode):boolean;
  196. begin
  197. Abstract;
  198. ParamValueBool:=false;
  199. end;
  200. function TSwitchItem.ParamCount:sw_integer;
  201. begin
  202. ParamCount:=1;
  203. end;
  204. function TSwitchItem.GetSwitchStr(SM: TSwitchMode): string;
  205. begin
  206. Abstract;
  207. GetSwitchStr:='';
  208. end;
  209. function TSwitchItem.GetNumberStr(SM: TSwitchMode): string;
  210. begin
  211. Abstract;
  212. GetNumberStr:='';
  213. end;
  214. function TSwitchItem.GetOptionStr(SM: TSwitchMode): string;
  215. begin
  216. Abstract;
  217. GetOptionStr:='';
  218. end;
  219. procedure TSwitchItem.Reset;
  220. begin
  221. end;
  222. {*****************************************************************************
  223. TSelectItem
  224. *****************************************************************************}
  225. constructor TSelectItem.Init(const n,p:string; AID: TParamID);
  226. begin
  227. Inherited Init(n,p,AID);
  228. Typ:=ot_Select;
  229. IsDefault:=false;
  230. end;
  231. constructor TSelectItem.InitDefault(const n:string);
  232. begin
  233. Inherited Init(n,'',idNone);
  234. Typ:=ot_Select;
  235. IsDefault:=true;
  236. end;
  237. {*****************************************************************************
  238. TBooleanItem
  239. *****************************************************************************}
  240. constructor TBooleanItem.Init(const n,p:string; AID: TParamID);
  241. begin
  242. Inherited Init(n,p,AID);
  243. Typ:=ot_Boolean;
  244. Reset;
  245. end;
  246. function TBooleanItem.NeedParam:boolean;
  247. begin
  248. NeedParam:=IsSet[SwitchesMode];
  249. end;
  250. procedure TBooleanItem.Reset;
  251. begin
  252. FillChar(IsSet,sizeof(IsSet),0);
  253. end;
  254. function TBooleanItem.ParamValueBool(SM: TSwitchMode):boolean;
  255. begin
  256. ParamValueBool:=IsSet[SM];
  257. end;
  258. function TBooleanItem.GetSwitchStr(SM: TSwitchMode): string;
  259. begin
  260. GetSwitchStr:=BoolToStr(IsSet[SM],'+','-');
  261. end;
  262. {*****************************************************************************
  263. TStringItem
  264. *****************************************************************************}
  265. constructor TStringItem.Init(const n,p:string; AID: TParamID; mult,allowspaces:boolean);
  266. begin
  267. Inherited Init(n,p,AID);
  268. Typ:=ot_String;
  269. Multiple:=mult;
  270. SeparateSpaces:=not allowspaces;
  271. Reset;
  272. end;
  273. function TStringItem.NeedParam:boolean;
  274. begin
  275. NeedParam:=(Str[SwitchesMode]<>'');
  276. end;
  277. function TStringItem.ParamValue(nr:sw_integer):string;
  278. begin
  279. ParamValue:=Str[SwitchesMode];
  280. end;
  281. procedure TStringItem.Reset;
  282. begin
  283. FillChar(Str,sizeof(Str),0);
  284. end;
  285. {*****************************************************************************
  286. TMultiStringItem
  287. *****************************************************************************}
  288. constructor TMultiStringItem.Init(const n,p:string;AID:TParamID);
  289. var i:TSwitchMode;
  290. begin
  291. inherited Init(n,p,AID);
  292. typ:=ot_MultiString;
  293. for i:=low(MultiStr) to high(MultiStr) do
  294. new(MultiStr[i],init(5,5));
  295. { Reset;}
  296. end;
  297. function TMultiStringItem.NeedParam:boolean;
  298. begin
  299. NeedParam:=(multistr[SwitchesMode]^.count<>0);
  300. end;
  301. function TMultiStringItem.ParamValue(nr:sw_integer):string;
  302. begin
  303. ParamValue:=MultiStr[SwitchesMode]^.at(nr)^;
  304. end;
  305. function TMultiStringItem.ParamCount:sw_integer;
  306. begin
  307. ParamCount:=Multistr[SwitchesMode]^.count;
  308. end;
  309. procedure TMultiStringItem.Reset;
  310. var i:TSwitchMode;
  311. begin
  312. for i:=low(multiStr) to high(multiStr) do
  313. MultiStr[i]^.freeall;
  314. end;
  315. destructor TmultiStringItem.done;
  316. var i:TSwitchMode;
  317. begin
  318. for i:=low(MultiStr) to high(MultiStr) do
  319. dispose(MultiStr[i],done);
  320. inherited done;
  321. end;
  322. {*****************************************************************************
  323. TLongintItem
  324. *****************************************************************************}
  325. constructor TLongintItem.Init(const n,p:string; AID: TParamID);
  326. begin
  327. Inherited Init(n,p,AID);
  328. Typ:=ot_Longint;
  329. Reset;
  330. end;
  331. function TLongintItem.NeedParam:boolean;
  332. begin
  333. NeedParam:=(Val[SwitchesMode]<>0);
  334. end;
  335. function TLongintItem.ParamValue:string;
  336. var
  337. s : string;
  338. begin
  339. Str(Val[SwitchesMode],s);
  340. ParamValue:=s;
  341. end;
  342. procedure TLongintItem.Reset;
  343. begin
  344. FillChar(Val,sizeof(Val),0);
  345. end;
  346. function TLongintItem.GetNumberStr(SM: TSwitchMode): string;
  347. begin
  348. GetNumberStr:=IntToStr(Val[SM]);
  349. end;
  350. {*****************************************************************************
  351. TSwitch
  352. *****************************************************************************}
  353. constructor TSwitches.Init(ch:char);
  354. begin
  355. new(Items,Init(10,5));
  356. Prefix:=ch;
  357. FillChar(SelNr,SizeOf(SelNr),#0);
  358. IsSel:=false;
  359. end;
  360. constructor TSwitches.InitSelect(ch:char);
  361. begin
  362. new(Items,Init(10,5));
  363. Prefix:=ch;
  364. FillChar(SelNr,SizeOf(SelNr),#0);
  365. IsSel:=true;
  366. end;
  367. destructor TSwitches.Done;
  368. begin
  369. dispose(Items,Done);
  370. end;
  371. procedure TSwitches.AddSelectItem(const name,param:string; AID: TParamID);
  372. begin
  373. Items^.Insert(New(PSelectItem,Init(name,Param,AID)));
  374. end;
  375. procedure TSwitches.AddDefaultSelect(const name:string);
  376. begin
  377. Items^.Insert(New(PSelectItem,InitDefault(name)));
  378. end;
  379. procedure TSwitches.AddBooleanItem(const name,param:string; AID: TParamID);
  380. begin
  381. Items^.Insert(New(PBooleanItem,Init(name,Param,AID)));
  382. end;
  383. procedure TSwitches.AddLongintItem(const name,param:string; AID: TParamID);
  384. begin
  385. Items^.Insert(New(PLongintItem,Init(name,Param,AID)));
  386. end;
  387. procedure TSwitches.AddStringItem(const name,param:string;AID:TParamID;mult,allowspaces:boolean);
  388. begin
  389. Items^.Insert(New(PStringItem,Init(name,Param,AID,mult,allowspaces)));
  390. end;
  391. procedure TSwitches.AddMultiStringItem(const name,param:string;AID:TParamID);
  392. begin
  393. Items^.Insert(New(PMultiStringItem,Init(name,Param,AID)));
  394. end;
  395. function TSwitches.ItemCount:integer;
  396. begin
  397. ItemCount:=Items^.Count;
  398. end;
  399. function TSwitches.ItemName(index:integer):string;
  400. var
  401. P : PSwitchItem;
  402. begin
  403. if index<ItemCount then
  404. P:=Items^.At(Index)
  405. else
  406. P:=nil;
  407. if assigned(P) then
  408. ItemName:=P^.Name
  409. else
  410. ItemName:='';
  411. end;
  412. function TSwitches.ItemParam(index:integer):string;
  413. var
  414. P : PSwitchItem;
  415. begin
  416. if index<ItemCount then
  417. P:=Items^.At(Index)
  418. else
  419. P:=nil;
  420. if assigned(P) then
  421. ItemParam:='-'+Prefix+P^.Param
  422. else
  423. ItemParam:='';
  424. end;
  425. function TSwitches.GetBooleanItem(index:integer):boolean;
  426. var
  427. P : PBooleanItem;
  428. begin
  429. if index<ItemCount then
  430. P:=Items^.At(Index)
  431. else
  432. P:=nil;
  433. if assigned(P) and (P^.Typ=ot_boolean) then
  434. GetBooleanItem:=P^.IsSet[SwitchesMode]
  435. else
  436. GetBooleanItem:=false;
  437. end;
  438. function TSwitches.GetLongintItem(index:integer):longint;
  439. var
  440. P : PLongintItem;
  441. begin
  442. if index<ItemCount then
  443. P:=Items^.At(Index)
  444. else
  445. P:=nil;
  446. if assigned(P) and (P^.Typ=ot_longint) then
  447. GetLongintItem:=P^.Val[SwitchesMode]
  448. else
  449. GetLongintItem:=0;
  450. end;
  451. function TSwitches.GetStringItem(index:integer):string;
  452. var
  453. P : PStringItem;
  454. begin
  455. if index<ItemCount then
  456. P:=Items^.At(Index)
  457. else
  458. P:=nil;
  459. if assigned(P) and (P^.Typ=ot_string) then
  460. GetStringItem:=P^.Str[SwitchesMode]
  461. else
  462. GetStringItem:='';
  463. end;
  464. function TSwitches.GetMultiStringItem(index:integer):PUnsortedStringCollection;
  465. var p:PMultiStringItem;
  466. begin
  467. if index<ItemCount then
  468. p:=Items^.at(Index)
  469. else
  470. p:=nil;
  471. if (p<>nil) and (p^.typ=ot_multistring) then
  472. GetMultiStringItem:=p^.MultiStr[SwitchesMode]
  473. else
  474. GetMultiStringItem:=nil;
  475. end;
  476. function TSwitches.GetItemTyp(index:integer):TSwitchItemTyp;
  477. var p:PSwitchItem;
  478. begin
  479. assert(index<itemcount);
  480. GetItemTyp:=PSwitchItem(items^.at(index))^.typ;
  481. end;
  482. procedure TSwitches.SetBooleanItem(index:integer;b:boolean);
  483. var
  484. P : PBooleanItem;
  485. begin
  486. if index<ItemCount then
  487. P:=Items^.At(Index)
  488. else
  489. P:=nil;
  490. if assigned(P) and (P^.Typ=ot_boolean) then
  491. P^.IsSet[SwitchesMode]:=b;
  492. end;
  493. procedure TSwitches.SetLongintItem(index:integer;l:longint);
  494. var
  495. P : PLongintItem;
  496. begin
  497. if index<ItemCount then
  498. P:=Items^.At(Index)
  499. else
  500. P:=nil;
  501. if assigned(P) and (P^.Typ=ot_longint) then
  502. P^.Val[SwitchesMode]:=l;
  503. end;
  504. procedure TSwitches.SetStringItem(index:integer;const s:string);
  505. var
  506. P : PStringItem;
  507. begin
  508. if index<ItemCount then
  509. P:=Items^.At(Index)
  510. else
  511. P:=nil;
  512. if assigned(P) and (P^.Typ=ot_string) then
  513. P^.Str[SwitchesMode]:=s;
  514. end;
  515. function TSwitches.GetCurrSel:integer;
  516. begin
  517. if IsSel then
  518. GetCurrSel:=SelNr[SwitchesMode]
  519. else
  520. GetCurrSel:=-1;
  521. end;
  522. function TSwitches.GetCurrSelParam : String;
  523. begin
  524. if IsSel then
  525. GetCurrSelParam:=PSwitchItem(Items^.At(SelNr[SwitchesMode]))^.Param
  526. else
  527. GetCurrSelParam:='';
  528. end;
  529. procedure TSwitches.SetCurrSel(index:integer);
  530. begin
  531. if IsSel then
  532. SelNr[SwitchesMode]:=index;
  533. end;
  534. function TSwitches.SetCurrSelParam(const s : String) : boolean;
  535. function checkitem(P:PSwitchItem):boolean;{$ifndef FPC}far;{$endif}
  536. begin
  537. { empty items are not equivalent to others !! }
  538. CheckItem:=((S='') and (P^.Param='')) or
  539. ((Length(S)>0) and (P^.Param=s));
  540. end;
  541. var
  542. FoundP : PSwitchItem;
  543. begin
  544. FoundP:=Items^.FirstThat(@CheckItem);
  545. if Assigned(FoundP) then
  546. begin
  547. SetCurrSelParam:=true;
  548. SelNr[SwitchesMode]:=Items^.IndexOf(FoundP);
  549. end
  550. else
  551. SetCurrSelParam:=false;
  552. end;
  553. procedure TSwitches.WriteItemsCfg;
  554. var
  555. Pref : char;
  556. procedure writeitem(P:PSwitchItem);{$ifndef FPC}far;{$endif}
  557. var
  558. s,s1 : string;
  559. i,j : integer;
  560. begin
  561. if P^.NeedParam then
  562. begin
  563. if (P^.Typ=ot_string) and (PStringItem(P)^.Multiple) then
  564. begin
  565. s:=PStringItem(P)^.Str[SwitchesMode];
  566. repeat
  567. i:=pos(';',s);
  568. if PStringItem(P)^.SeparateSpaces then
  569. j:=pos(' ',s)
  570. else
  571. j:=0;
  572. if i=0 then
  573. i:=256;
  574. if (j>0) and (j<i) then
  575. i:=j;
  576. s1:=Copy(s,1,i-1);
  577. if s1<>'' then
  578. writeln(CfgFile,' -'+Pref+P^.Param+s1);
  579. Delete(s,1,i);
  580. until s='';
  581. end
  582. else
  583. if P^.Param<>'/' then
  584. for i:=0 to p^.ParamCount-1 do
  585. Writeln(CfgFile,' -'+Pref+P^.Param+P^.ParamValue(i));
  586. end;
  587. end;
  588. var
  589. P : PSelectItem;
  590. begin
  591. Pref:=Prefix;
  592. if IsSel then
  593. begin
  594. { can be empty for some targets }
  595. If Items^.count>0 then
  596. begin
  597. P:=Items^.At(SelNr[SwitchesMode]);
  598. if not P^.IsDefault then
  599. writeln(CfgFile,' '+ItemParam(SelNr[SwitchesMode]));
  600. end;
  601. end
  602. else
  603. Items^.ForEach(@writeitem);
  604. end;
  605. procedure WriteCustom;
  606. var
  607. s : string;
  608. i : longint;
  609. begin
  610. s:=CustomArg[SwitchesMode];
  611. While s<>'' do
  612. begin
  613. i:=pos(' ',s);
  614. if i=0 then i:=256;
  615. writeln(CfgFile,' '+Copy(s,1,i-1));
  616. if i=256 then
  617. s:=''
  618. else
  619. s:=copy(s,i+1,255);
  620. end;
  621. end;
  622. function TSwitches.ReadItemsCfg(const s:string):boolean;
  623. function checkitem(P:PSwitchItem):boolean;{$ifndef FPC}far;{$endif}
  624. begin
  625. { empty items are not equivalent to others !! }
  626. { but -dGDB didn't work because of this PM }
  627. CheckItem:=((P^.Param='') and ((S='') or (P^.typ=ot_String))) or
  628. ((Length(P^.Param)>0) and (P^.Param=Copy(s,1,length(P^.Param))));
  629. end;
  630. var
  631. FoundP : PSwitchItem;
  632. code : integer;
  633. begin
  634. FoundP:=Items^.FirstThat(@checkitem);
  635. if assigned(FoundP) then
  636. begin
  637. case FoundP^.Typ of
  638. ot_Select : SelNr[SwitchesMode]:=Items^.IndexOf(FoundP);
  639. ot_Boolean : PBooleanItem(FoundP)^.IsSet[SwitchesMode]:=true;
  640. ot_String : begin
  641. if (PStringItem(FoundP)^.Multiple) and (PStringItem(FoundP)^.Str[SwitchesMode]<>'') then
  642. PStringItem(FoundP)^.Str[SwitchesMode]:=PStringItem(FoundP)^.Str[SwitchesMode]+';'+
  643. Copy(s,length(FoundP^.Param)+1,255)
  644. else
  645. PStringItem(FoundP)^.Str[SwitchesMode]:=Copy(s,length(FoundP^.Param)+1,255);
  646. end;
  647. ot_MultiString :
  648. PMultiStringItem(foundP)^.MultiStr[SwitchesMode]^.insert(newstr(copy(s,length(foundP^.param)+1,255)));
  649. ot_Longint : Val(Copy(s,length(FoundP^.Param)+1,255),PLongintItem(FoundP)^.Val[SwitchesMode],code);
  650. end;
  651. ReadItemsCfg:=true;
  652. end
  653. else
  654. ReadItemsCfg:=false;
  655. end;
  656. {*****************************************************************************
  657. Read / Write
  658. *****************************************************************************}
  659. procedure WriteSwitches(const fn:string);
  660. var
  661. OldSwitchesMode, SWM: TSwitchMode;
  662. begin
  663. { create the switches }
  664. assign(CfgFile,fn);
  665. {$I-}
  666. rewrite(CfgFile);
  667. {$I+}
  668. if ioresult<>0 then
  669. exit;
  670. writeln(CfgFile,'# '+msg_automaticallycreateddontedit);
  671. OldSwitchesMode:=SwitchesMode;
  672. for SWM:=low(TSwitchMode) to high(TSwitchMode) do
  673. begin
  674. SwitchesMode := SWM;
  675. Writeln(CfgFile,'#IFDEF '+SwitchesModeStr[SwitchesMode]);
  676. TargetSwitches^.WriteItemsCfg;
  677. VerboseSwitches^.WriteItemsCfg;
  678. SyntaxSwitches^.WriteItemsCfg;
  679. CompilerModeSwitches^.WriteItemsCfg;
  680. CodegenSwitches^.WriteItemsCfg;
  681. OptimizationSwitches^.WriteItemsCfg;
  682. OptimizingGoalSwitches^.WriteItemsCfg;
  683. ProcessorSwitches^.WriteItemsCfg;
  684. AsmReaderSwitches^.WriteItemsCfg;
  685. AsmInfoSwitches^.WriteItemsCfg;
  686. AsmOutputSwitches^.WriteItemsCfg;
  687. DirectorySwitches^.WriteItemsCfg;
  688. MemorySwitches^.WriteItemsCfg;
  689. ConditionalSwitches^.WriteItemsCfg;
  690. LibLinkerSwitches^.WriteItemsCfg;
  691. OtherLinkerSwitches^.WriteItemsCfg;
  692. DebugInfoSwitches^.WriteItemsCfg;
  693. ProfileInfoSwitches^.WriteItemsCfg;
  694. LinkAfterSwitches^.WriteItemsCfg;
  695. BrowserSwitches^.WriteItemsCfg;
  696. {MemorySizeSwitches^.WriteItemsCfg;}
  697. WriteCustom;
  698. Writeln(CfgFile,'#ENDIF');
  699. Writeln(CfgFile,'');
  700. end;
  701. close(CfgFile);
  702. SwitchesMode:=OldSwitchesMode;
  703. end;
  704. procedure ReadSwitches(const fn:string);
  705. var
  706. c : char;
  707. s : string;
  708. res : boolean;
  709. OldSwitchesMode,i : TSwitchMode;
  710. begin
  711. assign(CfgFile,fn);
  712. {$I-}
  713. reset(CfgFile);
  714. {$I+}
  715. if ioresult<>0 then
  716. begin
  717. SetDefaultSwitches;
  718. exit;
  719. end;
  720. OldSwitchesMode:=SwitchesMode;
  721. SwitchesMode:=om_Normal;
  722. while not eof(CfgFile) do
  723. begin
  724. readln(CfgFile,s);
  725. s:=LTrim(s);
  726. if (length(s)>=2) and (s[1]='-') then
  727. begin
  728. c:=s[2];
  729. res:=false;
  730. Delete(s,1,2);
  731. case c of
  732. 'a' : res:=AsmInfoSwitches^.ReadItemsCfg(s);
  733. 'A' : res:=AsmOutputSwitches^.ReadItemsCfg(s);
  734. 'b' : res:=BrowserSwitches^.ReadItemsCfg(s);
  735. 'C' : begin
  736. res:=CodegenSwitches^.ReadItemsCfg(s);
  737. if not res then
  738. res:=MemorySwitches^.ReadItemsCfg(s);
  739. end;
  740. 'd' : res:=ConditionalSwitches^.ReadItemsCfg(s);
  741. 'F' : res:=DirectorySwitches^.ReadItemsCfg(s);
  742. 'g' : res:=DebugInfoSwitches^.ReadItemsCfg(s);
  743. 'O' : begin
  744. res:=true;
  745. if not OptimizationSwitches^.ReadItemsCfg(s) then
  746. if not ProcessorSwitches^.ReadItemsCfg(s) then
  747. res:=OptimizingGoalSwitches^.ReadItemsCfg(s);
  748. end;
  749. 'M' : res:=CompilerModeSwitches^.ReadItemsCfg(s);
  750. 'p' : res:=ProfileInfoSwitches^.ReadItemsCfg(s);
  751. 's' : res:=LinkAfterSwitches^.ReadItemsCfg(s);
  752. 'R' : res:=AsmReaderSwitches^.ReadItemsCfg(s);
  753. 'S' : res:=SyntaxSwitches^.ReadItemsCfg(s);
  754. 'T' : res:=TargetSwitches^.ReadItemsCfg(s);
  755. 'v' : res:=VerboseSwitches^.ReadItemsCfg(s);
  756. 'X' : begin
  757. res:=LibLinkerSwitches^.ReadItemsCfg(s);
  758. if not res then
  759. res:=OtherLinkerSwitches^.ReadItemsCfg(s);
  760. end;
  761. end;
  762. { keep all others as a string }
  763. if not res then
  764. CustomArg[SwitchesMode]:=CustomArg[SwitchesMode]+' -'+c+s;
  765. end
  766. else
  767. if (Copy(s,1,7)='#IFDEF ') then
  768. begin
  769. Delete(s,1,7);
  770. for i:=low(TSwitchMode) to high(TSwitchMode) do
  771. if s=SwitchesModeStr[i] then
  772. begin
  773. SwitchesMode:=i;
  774. break;
  775. end;
  776. end
  777. else;
  778. end;
  779. close(CfgFile);
  780. SwitchesMode:=OldSwitchesMode;
  781. end;
  782. function GetSourceDirectories : string;
  783. var
  784. P : PStringItem;
  785. S : String;
  786. c : char;
  787. function checkitem(P:PSwitchItem):boolean;{$ifndef FPC}far;{$endif}
  788. begin
  789. CheckItem:=(P^.Typ=ot_string) and (P^.Param=c);
  790. end;
  791. begin
  792. GetSourceDirectories:='';
  793. c:='u';
  794. P:=DirectorySwitches^.Items^.FirstThat(@CheckItem);
  795. S:='';
  796. if assigned(P) then
  797. S:=P^.Str[SwitchesMode];
  798. c:='i';
  799. P:=DirectorySwitches^.Items^.FirstThat(@CheckItem);
  800. if assigned(P) then
  801. S:=P^.Str[SwitchesMode]+';'+S;
  802. if S='' then
  803. GetSourceDirectories:=SourceDirs+';'
  804. else
  805. GetSourceDirectories:=SourceDirs+';'+S+';';
  806. end;
  807. {*****************************************************************************
  808. Initialize
  809. *****************************************************************************}
  810. procedure InitSwitches;
  811. var
  812. t : tsystem;
  813. begin
  814. New(SyntaxSwitches,Init('S'));
  815. with SyntaxSwitches^ do
  816. begin
  817. // AddBooleanItem(opt_objectpascal,'2',idNone);
  818. AddBooleanItem(opt_stopafterfirsterror,'e',idNone);
  819. AddBooleanItem(opt_allowlabelandgoto,'g',idNone);
  820. AddBooleanItem(opt_globalcmacros,'m',idNone);
  821. AddBooleanItem(opt_cplusplusstyledinline,'i',idNone);
  822. // AddBooleanItem(opt_tp7compatibility,'o',idNone);
  823. // AddBooleanItem(opt_delphicompatibility,'d',idNone);
  824. AddBooleanItem(opt_assertions,'a',idNone);
  825. AddBooleanItem(opt_kylix,'k',idNone);
  826. AddBooleanItem(opt_allowstaticinobjects,'s',idNone);
  827. AddBooleanItem(opt_clikeoperators,'c',idNone);
  828. { Useless as they are not passed to the compiler PM
  829. AddBooleanItem(opt_strictvarstrings,'/',idStrictVarStrings);
  830. AddBooleanItem(opt_extendedsyntax,'/',idExtendedSyntax);
  831. AddBooleanItem(opt_allowmmxoperations,'/',idMMXOps); }
  832. end;
  833. New(CompilerModeSwitches,InitSelect('M'));
  834. with CompilerModeSwitches^ do
  835. begin
  836. AddSelectItem(opt_mode_freepascal,'fpc',idNone);
  837. AddSelectItem(opt_mode_objectpascal,'objfpc',idNone);
  838. AddSelectItem(opt_mode_turbopascal,'tp',idNone);
  839. AddSelectItem(opt_mode_delphi,'delphi',idNone);
  840. AddSelectItem(opt_mode_macpascal,'macpascal',idNone);
  841. { GNU Pascal mode doesn't do much, better disable it
  842. AddSelectItem(opt_mode_gnupascal,'gpc',idNone);}
  843. end;
  844. New(VerboseSwitches,Init('v'));
  845. with VerboseSwitches^ do
  846. begin
  847. AddBooleanItem(opt_warnings,'w',idNone);
  848. AddBooleanItem(opt_notes,'n',idNone);
  849. AddBooleanItem(opt_hints,'h',idNone);
  850. AddBooleanItem(opt_generalinfo,'i',idNone);
  851. AddBooleanItem(opt_usedtriedinfo,'ut',idNone);
  852. AddBooleanItem(opt_all,'a',idNone);
  853. AddBooleanItem(opt_showallprocsonerror,'b',idNone);
  854. end;
  855. New(CodegenSwitches,Init('C'));
  856. with CodegenSwitches^ do
  857. begin
  858. AddBooleanItem(opt_rangechecking,'r',idRangeChecks);
  859. AddBooleanItem(opt_stackchecking,'t',idStackChecks);
  860. AddBooleanItem(opt_iochecking,'i',idIOChecks);
  861. AddBooleanItem(opt_overflowchecking,'o',idOverflowChecks);
  862. AddBooleanItem(opt_objmethcallvalid,'R',idObjMethCallChecks);
  863. AddBooleanItem(opt_pic,'g',idNone);
  864. AddBooleanItem(opt_smart,'X',idNone);
  865. end;
  866. New(OptimizingGoalSwitches,InitSelect('O'));
  867. with OptimizingGoalSwitches^ do
  868. begin
  869. AddSelectItem(opt_generatefastercode,'G',idNone);
  870. AddSelectItem(opt_generatesmallercode,'g',idNone);
  871. end;
  872. New(OptimizationSwitches,Init('O'));
  873. with OptimizationSwitches^ do
  874. begin
  875. {$ifdef I386}
  876. AddBooleanItem(opt_useregistervariables,'r',idNone);
  877. AddBooleanItem(opt_uncertainoptimizations,'u',idNone);
  878. AddBooleanItem(opt_level1optimizations,'1',idNone);
  879. AddBooleanItem(opt_level2optimizations,'2',idNone);
  880. {$else not I386}
  881. {$ifdef m68k}
  882. AddBooleanItem(opt_level1optimizations,'a',idNone);
  883. AddBooleanItem(opt_useregistervariables,'x',idNone);
  884. {$endif m68k}
  885. {$endif I386}
  886. end;
  887. New(ProcessorSwitches,InitSelect('O'));
  888. with ProcessorSwitches^ do
  889. begin
  890. {$ifdef I386}
  891. AddSelectItem(opt_i386486,'p1',idNone);
  892. AddSelectItem(opt_pentiumandmmx,'p2',idNone);
  893. AddSelectItem(opt_pentiumpro,'p3',idNone);
  894. AddSelectItem(opt_pentiumiv,'p4',idNone);
  895. {$else not I386}
  896. {$ifdef m68k}
  897. AddSelectItem(opt_m68000,'',idNone);
  898. AddSelectItem(opt_m68020,'2',idNone);
  899. {$endif m68k}
  900. {$endif not I386}
  901. end;
  902. New(TargetSwitches,InitSelect('T'));
  903. with TargetSwitches^ do
  904. begin
  905. { better, we've a correct target list without "tilded" names instead a wrong one }
  906. for t:=low(tsystem) to high(tsystem) do
  907. if assigned(targetinfos[t]) then
  908. AddSelectItem(targetinfos[t]^.name,targetinfos[t]^.shortname,idNone);
  909. end;
  910. New(AsmReaderSwitches,InitSelect('R'));
  911. with AsmReaderSwitches^ do
  912. begin
  913. {$ifdef I386}
  914. { AddSelectItem(opt_directassembler,'direct',idAsmDirect);}
  915. AddSelectItem(opt_attassembler,'att',idAsmATT);
  916. AddSelectItem(opt_intelassembler,'intel',idAsmIntel);
  917. {$endif I386}
  918. {$ifdef M68K}
  919. AddSelectItem(opt_motassembler,'mot',idAsmDirect);
  920. {$endif M68K}
  921. end;
  922. New(AsmInfoSwitches,Init('a'));
  923. with AsmInfoSwitches^ do
  924. begin
  925. AddBooleanItem(opt_listsource,'l',idNone);
  926. AddBooleanItem(opt_listregisterallocation,'r',idNone);
  927. AddBooleanItem(opt_listtempallocation,'t',idNone);
  928. end;
  929. New(AsmOutputSwitches,InitSelect('A'));
  930. with AsmOutputSwitches^ do
  931. begin
  932. AddDefaultSelect(opt_usedefaultas);
  933. {$ifdef I386}
  934. AddSelectItem(opt_usegnuas,'as',idNone);
  935. AddSelectItem(opt_usenasmcoff,'nasmcoff',idNone);
  936. AddSelectItem(opt_usenasmelf,'nasmelf',idNone);
  937. AddSelectItem(opt_usenasmobj,'nasmobj',idNone);
  938. AddSelectItem(opt_usemasm,'masm',idNone);
  939. AddSelectItem(opt_usetasm,'tasm',idNone);
  940. AddSelectItem(opt_usecoff,'coff',idNone);
  941. AddSelectItem(opt_usepecoff,'pecoff',idNone);
  942. {$endif I386}
  943. end;
  944. New(BrowserSwitches,InitSelect('b'));
  945. with BrowserSwitches^ do
  946. begin
  947. AddSelectItem(opt_nobrowser,'-',idSymInfNone);
  948. AddSelectItem(opt_globalonlybrowser,'+',idSymInfGlobalOnly);
  949. AddSelectItem(opt_localglobalbrowser,'l',idSymInfGlobalLocal);
  950. end;
  951. New(ConditionalSwitches,Init('d'));
  952. with ConditionalSwitches^ do
  953. begin
  954. AddStringItem(opt_conditionaldefines,'',idNone,true,false);
  955. end;
  956. New(MemorySwitches,Init('C'));
  957. with MemorySwitches^ do
  958. begin
  959. AddLongintItem(opt_stacksize,'s',idStackSize);
  960. AddLongintItem(opt_heapsize,'h',idHeapSize);
  961. end;
  962. New(DirectorySwitches,Init('F'));
  963. with DirectorySwitches^ do
  964. begin
  965. AddMultiStringItem(opt_unitdirectories,'u',idNone);
  966. AddMultiStringItem(opt_includedirectories,'i',idNone);
  967. AddMultiStringItem(opt_librarydirectories,'l',idNone);
  968. AddMultiStringItem(opt_objectdirectories,'o',idNone);
  969. AddStringItem(opt_exeppudirectories,'E',idNone,true,true);
  970. AddStringItem(opt_ppuoutputdirectory,'U',idNone,true,true);
  971. AddStringItem(opt_cross_tools_directory,'D',idNone,true,true);
  972. AddStringItem(opt_dynamic_linker,'L',idNone,false,false);
  973. end;
  974. New(LibLinkerSwitches,InitSelect('X'));
  975. with LibLinkerSwitches^ do
  976. begin
  977. AddDefaultSelect(opt_librariesdefault);
  978. AddSelectItem(opt_dynamiclibraries,'D',idNone);
  979. AddSelectItem(opt_staticlibraries,'S',idNone);
  980. AddSelectItem(opt_smartlibraries,'X',idNone);
  981. end;
  982. New(OtherLinkerSwitches,Init('X'));
  983. with OtherLinkerSwitches^ do
  984. begin
  985. AddBooleanItem(opt_stripalldebugsymbols,'s',idNone);
  986. AddBooleanItem(opt_forcestaticlibs,'t',idNone);
  987. end;
  988. New(DebugInfoSwitches,InitSelect('g'));
  989. with DebugInfoSwitches^ do
  990. begin
  991. AddSelectItem(opt_nogendebugsymbolinfo,'-',idNone);
  992. AddSelectItem(opt_gendebugsymbolinfo,'',idNone);
  993. AddSelectItem(opt_gensymbolandbacktraceinfo,'l',idNone);
  994. AddSelectItem(opt_valgrindinfo,'v',idNone);
  995. { AddSelectItem('Generate ~d~bx symbol information','d');
  996. does not work anyhow (PM) }
  997. end;
  998. New(LinkAfterSwitches,Init('s'));
  999. LinkAfterSwitches^.AddBooleanItem(opt_linkafter,'',idNone);
  1000. New(ProfileInfoSwitches,InitSelect('p'));
  1001. with ProfileInfoSwitches^ do
  1002. begin
  1003. AddSelectItem(opt_noprofileinfo,'-',idNone);
  1004. AddSelectItem(opt_gprofinfo,'g',idNone);
  1005. end;
  1006. {New(MemorySizeSwitches,Init('C'));
  1007. with MemorySizeSwitches^ do
  1008. begin
  1009. AddLongIntItem('~S~tack size','s');
  1010. AddLongIntItem('Local ~h~eap size','h');
  1011. end;}
  1012. SwitchesPath:=LocateFile(SwitchesName);
  1013. if SwitchesPath='' then
  1014. SwitchesPath:=SwitchesName;
  1015. SwitchesPath:=FExpand(SwitchesPath);
  1016. end;
  1017. procedure SetDefaultSwitches;
  1018. var
  1019. i,OldSwitchesMode : TSwitchMode;
  1020. begin
  1021. { setup some useful defaults }
  1022. OldSwitchesMode:=SwitchesMode;
  1023. for i:=low(TSwitchMode) to high(TSwitchMode) do
  1024. begin
  1025. SwitchesMode:=i;
  1026. {$ifdef i386}
  1027. { default is Pentium }
  1028. ProcessorSwitches^.SetCurrSel(1);
  1029. { AT&T reader }
  1030. AsmReaderSwitches^.SetCurrSel(1);
  1031. {$endif i386}
  1032. { FPC mode}
  1033. CompilerModeSwitches^.SetCurrSel(0);
  1034. { 128k stack }
  1035. MemorySwitches^.SetLongintItem(0,65536*2);
  1036. { 2 MB heap }
  1037. MemorySwitches^.SetLongintItem(1,1024*1024*2);
  1038. { goto/lable allowed }
  1039. SyntaxSwitches^.SetBooleanItem(1,true);
  1040. { inline allowed }
  1041. SyntaxSwitches^.SetBooleanItem(3,true);
  1042. { Exe size complaints are louder than speed complaints: Optimize for size by default. }
  1043. OptimizingGoalSwitches^.SetCurrSel(1);
  1044. case i of
  1045. om_debug:
  1046. begin
  1047. { debugging info on }
  1048. DebugInfoSwitches^.SetCurrSel(1);
  1049. { range checking }
  1050. CodegenSwitches^.SetBooleanItem(0,true);
  1051. { io checking }
  1052. CodegenSwitches^.SetBooleanItem(2,true);
  1053. { overflow checking }
  1054. CodegenSwitches^.SetBooleanItem(3,true);
  1055. { method call checking }
  1056. CodegenSwitches^.SetBooleanItem(4,true);
  1057. { assertions on }
  1058. SyntaxSwitches^.SetBooleanItem(4,true);
  1059. end;
  1060. om_normal:
  1061. begin
  1062. {Register variables.}
  1063. OptimizationSwitches^.SetBooleanItem(0,true);
  1064. {Level 1 optimizations.}
  1065. OptimizationSwitches^.SetBooleanItem(2,true);
  1066. end;
  1067. om_release:
  1068. begin
  1069. {Register variables.}
  1070. OptimizationSwitches^.SetBooleanItem(0,true);
  1071. {Level 2 optimizations.}
  1072. OptimizationSwitches^.SetBooleanItem(3,true);
  1073. {Smart linking.}
  1074. LibLinkerSwitches^.SetCurrSel(3);
  1075. CodegenSwitches^.SetBooleanItem(6,true);
  1076. {Strip debug info}
  1077. OtherLinkerSwitches^.SetBooleanItem(0,true);
  1078. end;
  1079. end;
  1080. { set appriopriate default target }
  1081. TargetSwitches^.SetCurrSelParam(target_info.shortname);
  1082. end;
  1083. SwitchesMode:=OldSwitchesMode;
  1084. end;
  1085. procedure DoneSwitches;
  1086. begin
  1087. dispose(SyntaxSwitches,Done);
  1088. dispose(CompilerModeSwitches,Done);
  1089. dispose(VerboseSwitches,Done);
  1090. dispose(CodegenSwitches,Done);
  1091. dispose(OptimizationSwitches,Done);
  1092. dispose(OptimizingGoalSwitches,Done);
  1093. dispose(ProcessorSwitches,Done);
  1094. dispose(BrowserSwitches,Done);
  1095. dispose(TargetSwitches,Done);
  1096. dispose(AsmReaderSwitches,Done);
  1097. dispose(AsmOutputSwitches,Done);
  1098. dispose(AsmInfoSwitches,Done);
  1099. dispose(ConditionalSwitches,Done);
  1100. dispose(MemorySwitches,Done);
  1101. {dispose(MemorySizeSwitches,Done);}
  1102. dispose(DirectorySwitches,Done);
  1103. dispose(DebugInfoSwitches,Done);
  1104. dispose(LibLinkerSwitches,Done);
  1105. dispose(LinkAfterSwitches,Done);
  1106. dispose(OtherLinkerSwitches,Done);
  1107. dispose(ProfileInfoSwitches,Done);
  1108. end;
  1109. procedure GetCompilerOptionLines(C: PUnsortedStringCollection);
  1110. procedure AddLine(const S: string);
  1111. begin
  1112. C^.Insert(NewStr(S));
  1113. end;
  1114. procedure ConstructSwitchModeDirectives(SM: TSwitchMode; const IfDefSym: string);
  1115. var SwitchParams: PStringCollection;
  1116. MiscParams : PStringCollection;
  1117. procedure AddSwitch(const S: string);
  1118. begin
  1119. SwitchParams^.Insert(NewStr(S));
  1120. end;
  1121. procedure AddParam(const S: string);
  1122. begin
  1123. MiscParams^.Insert(NewStr(S));
  1124. end;
  1125. procedure EnumSwitches(P: PSwitches);
  1126. procedure HandleSwitch(P: PSwitchItem); {$ifndef FPC}far;{$endif}
  1127. begin
  1128. case P^.ParamID of
  1129. { idAlign :}
  1130. idRangeChecks : AddSwitch('R'+P^.GetSwitchStr(SM));
  1131. idStackChecks : AddSwitch('S'+P^.GetSwitchStr(SM));
  1132. idIOChecks : AddSwitch('I'+P^.GetSwitchStr(SM));
  1133. idOverflowChecks : AddSwitch('Q'+P^.GetSwitchStr(SM));
  1134. idObjMethCallChecks: AddSwitch('OBJECTCHECKS'+P^.GetSwitchStr(SM));
  1135. { idAsmDirect : if P^.GetParamValueBool[SM] then AddParam('ASMMODE DIRECT');
  1136. idAsmATT : if P^.GetParamValueBool[SM] then AddParam('ASMMODE ATT');
  1137. idAsmIntel : if P^.GetParamValueBool[SM] then AddParam('ASMMODE INTEL');
  1138. idAsmMot : if P^.GetParamValueBool[SM] then AddParam('ASMMODE MOT');}
  1139. { idSymInfNone : ;
  1140. idSymInfGlobalOnly:;
  1141. idSymInfGlobalLocal:if P^.ParamValueBool(SM) then AddSwitch('L+');}
  1142. { idStackSize
  1143. idHeapSize}
  1144. idStrictVarStrings: AddSwitch('V'+P^.GetSwitchStr(SM));
  1145. idExtendedSyntax : AddSwitch('X'+P^.GetSwitchStr(SM));
  1146. idMMXOps : if P^.ParamValueBool(SM) then AddParam('MMX');
  1147. idTypedAddress : AddSwitch('T'+P^.GetSwitchStr(SM));
  1148. { idPackRecords
  1149. idPackEnum}
  1150. idStackFrames : AddSwitch('W'+P^.GetSwitchStr(SM));
  1151. idReferenceInfo : AddSwitch('Y'+P^.GetSwitchStr(SM));
  1152. idDebugInfo : AddSwitch('D'+P^.GetSwitchStr(SM));
  1153. idBoolEval : AddSwitch('B'+P^.GetSwitchStr(SM));
  1154. idLongString : AddSwitch('H'+P^.GetSwitchStr(SM));
  1155. idTypeInfo : AddSwitch('M'+P^.GetSwitchStr(SM));
  1156. end;
  1157. end;
  1158. begin
  1159. P^.Items^.ForEach(@HandleSwitch);
  1160. end;
  1161. var I: integer;
  1162. S: string;
  1163. begin
  1164. AddLine('{$IFDEF '+IfDefSym+'}');
  1165. New(SwitchParams, Init(10,10));
  1166. New(MiscParams, Init(10,10));
  1167. EnumSwitches(LibLinkerSwitches);
  1168. EnumSwitches(OtherLinkerSwitches);
  1169. EnumSwitches(DebugInfoSwitches);
  1170. EnumSwitches(ProfileInfoSwitches);
  1171. EnumSwitches(SyntaxSwitches);
  1172. EnumSwitches(CompilerModeSwitches);
  1173. EnumSwitches(VerboseSwitches);
  1174. EnumSwitches(CodegenSwitches);
  1175. EnumSwitches(OptimizationSwitches);
  1176. EnumSwitches(OptimizingGoalSwitches);
  1177. EnumSwitches(ProcessorSwitches);
  1178. EnumSwitches(AsmReaderSwitches);
  1179. EnumSwitches(AsmInfoSwitches);
  1180. EnumSwitches(AsmOutputSwitches);
  1181. EnumSwitches(TargetSwitches);
  1182. EnumSwitches(ConditionalSwitches);
  1183. EnumSwitches(MemorySwitches);
  1184. EnumSwitches(BrowserSwitches);
  1185. EnumSwitches(DirectorySwitches);
  1186. S:='';
  1187. for I:=0 to SwitchParams^.Count-1 do
  1188. begin
  1189. if I=0 then S:='{$' else S:=S+',';
  1190. S:=S+PString(SwitchParams^.At(I))^;
  1191. end;
  1192. if S<>'' then S:=S+'}';
  1193. if S<>'' then AddLine(' '+S);
  1194. for I:=0 to MiscParams^.Count-1 do
  1195. AddLine(' {$'+PString(MiscParams^.At(I))^+'}');
  1196. Dispose(SwitchParams, Done); Dispose(MiscParams, Done);
  1197. AddLine('{$ENDIF '+IfDefSym+'}');
  1198. end;
  1199. var SM: TSwitchMode;
  1200. begin
  1201. for SM:=Low(TSwitchMode) to High(TSwitchMode) do
  1202. ConstructSwitchModeDirectives(SM,SwitchesModeStr[SM]);
  1203. end;
  1204. end.