fpswitch.pas 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477
  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(nr:sw_integer):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. FPVars,FPUtils;
  175. var
  176. CfgFile : text;
  177. {$ifdef useresstrings}
  178. resourcestring
  179. {$else}
  180. const
  181. {$endif}
  182. msg_automaticallycreateddontedit = 'Automaticly created file, don''t edit.';
  183. { Compiler options }
  184. opt_objectpascal = 'Object pascal support';
  185. opt_clikeoperators = 'C-like operators';
  186. opt_stopafterfirsterror = 'Stop after first error';
  187. opt_allowlabelandgoto = 'Allow LABEL and GOTO';
  188. opt_cplusplusstyledinline = 'Allow inline';
  189. opt_globalcmacros = 'Enable macros';
  190. opt_allowstaticinobjects = 'Allow STATIC in objects';
  191. opt_assertions = 'Include assertion code';
  192. opt_kylix = 'Load Kylix compat. unit';
  193. opt_strictvarstrings = 'Strict var-strings';
  194. opt_extendedsyntax = 'Extended syntax';
  195. opt_allowmmxoperations = 'Allow MMX operations';
  196. opt_mode_freepascal = 'Free Pascal dialect';
  197. opt_mode_objectpascal = 'Object Pascal extension on';
  198. opt_mode_turbopascal = 'Turbo Pascal compatible';
  199. opt_mode_delphi = 'Delphi compatible';
  200. opt_mode_macpascal = 'Macintosh Pascal dialect';
  201. opt_mode_gnupascal = 'GNU Pascal';
  202. { Verbose options }
  203. opt_warnings = '~W~arnings';
  204. opt_notes = 'N~o~tes';
  205. opt_hints = '~H~ints';
  206. opt_generalinfo = 'General ~I~nfo';
  207. opt_usedtriedinfo = '~U~sed,tried info';
  208. opt_all = '~A~ll';
  209. opt_showallprocsonerror = 'Show all ~P~rocedures if error';
  210. { Checking options }
  211. opt_rangechecking = '~R~ange checking';
  212. opt_stackchecking = '~S~tack checking';
  213. opt_iochecking = '~I~/O checking';
  214. opt_overflowchecking = 'Integer ~o~verflow checking';
  215. opt_objmethcallvalid = 'Object ~m~ethod call checking';
  216. { Code generation }
  217. opt_pic = '~P~osition independend code';
  218. opt_smart = '~C~reate smartlinkable units';
  219. { Code options }
  220. opt_generatefastercode = 'Generate ~f~aster code';
  221. opt_generatesmallercode = 'Generate s~m~aller code';
  222. opt_useregistervariables = 'Use regis~t~er-variables';
  223. opt_uncertainoptimizations = '~U~ncertain optimizations';
  224. opt_level1optimizations = 'Level ~1~ optimizations';
  225. opt_level2optimizations = 'Level ~2~ optimizations';
  226. opt_i386486 = 'i~3~86/i486';
  227. opt_pentiumandmmx = 'Pentium/PentiumMM~X~ (tm)';
  228. opt_pentiumpro = '~P~entium2/PentiumM/AMD';
  229. opt_pentiumiv = 'Pentium~4~';
  230. opt_m68000 = 'm~6~8000';
  231. opt_m68020 = 'm680~2~0';
  232. { Assembler options }
  233. opt_directassembler = '~D~irect assembler';
  234. opt_attassembler = '~A~T&T style assembler';
  235. opt_intelassembler = '~I~ntel style assembler';
  236. opt_motassembler = '~M~otorola style assembler';
  237. opt_listsource = '~L~ist source';
  238. opt_listregisterallocation = 'list ~r~egister allocation';
  239. opt_listtempallocation = 'list ~t~emp allocation';
  240. opt_usedefaultas = 'Use ~d~efault output';
  241. opt_usegnuas = 'Use ~G~NU as';
  242. opt_usenasmcoff = 'Use ~N~ASM coff';
  243. opt_usenasmelf = 'Use NASM ~e~lf';
  244. opt_usenasmobj = 'Use NASM ~o~bj';
  245. opt_usemasm = 'Use ~M~ASM';
  246. opt_usetasm = 'Use ~T~ASM';
  247. opt_usecoff = 'Use ~c~off';
  248. opt_usepecoff = 'Use ~p~ecoff';
  249. { Browser options }
  250. opt_nobrowser = 'N~o~ browser';
  251. opt_globalonlybrowser = 'Only Glob~a~l browser';
  252. opt_localglobalbrowser = '~L~ocal and global browser';
  253. { Conditional defines }
  254. opt_conditionaldefines = 'Conditio~n~al defines';
  255. { Memory sizes }
  256. opt_stacksize = '~S~tack size';
  257. opt_heapsize = '~H~eap size';
  258. { Directory options }
  259. opt_unitdirectories = '~U~nit directories';
  260. opt_includedirectories = '~I~nclude directories';
  261. opt_librarydirectories = '~L~ibrary directories';
  262. opt_objectdirectories = '~O~bject directories';
  263. opt_exeppudirectories = '~E~XE output directory';
  264. opt_ppuoutputdirectory = '~P~PU output directory';
  265. opt_cross_tools_directory = '~C~ross tools directory';
  266. opt_dynamic_linker = '~D~ynamic linker path';
  267. { Library options }
  268. opt_librariesdefault = '~T~arget default';
  269. opt_dynamiclibraries = 'Link to ~D~ynamic libraries';
  270. opt_staticlibraries = 'Link to ~S~tatic libraries';
  271. opt_smartlibraries = 'Link to S~m~art libraries';
  272. opt_forcestaticlibs = 'Only link to st~a~tic libraries';
  273. { Symbol info options }
  274. opt_stripalldebugsymbols = '~S~trip all debug symbols from executable';
  275. opt_nogendebugsymbolinfo = 'Skip ~d~ebug information generation';
  276. opt_gendebugsymbolinfo = 'Generate ~d~ebug symbol information';
  277. opt_gensymbolandbacktraceinfo = 'Generate also backtrace ~l~ine information';
  278. opt_valgrindinfo = 'Generate ~v~algrind compatible debug info';
  279. { Link after options }
  280. opt_linkafter = 'Call ~l~inker after';
  281. { Profiling options }
  282. opt_noprofileinfo = '~N~o profile information';
  283. opt_gprofinfo = 'Generate profile code for g~p~rof';
  284. {*****************************************************************************
  285. TSwitchItem
  286. *****************************************************************************}
  287. constructor TSwitchItem.Init(const n,p:string; AID: TParamID);
  288. begin
  289. Inherited Init;
  290. Name:=n;
  291. Param:=p;
  292. ParamID:=AID;
  293. end;
  294. function TSwitchItem.NeedParam:boolean;
  295. begin
  296. NeedParam:=false;
  297. end;
  298. function TSwitchItem.ParamValue(nr:sw_integer):string;
  299. begin
  300. ParamValue:='';
  301. end;
  302. function TSwitchItem.ParamValueBool(SM: TSwitchMode):boolean;
  303. begin
  304. Abstract;
  305. ParamValueBool:=false;
  306. end;
  307. function TSwitchItem.ParamCount:sw_integer;
  308. begin
  309. ParamCount:=1;
  310. end;
  311. function TSwitchItem.GetSwitchStr(SM: TSwitchMode): string;
  312. begin
  313. Abstract;
  314. GetSwitchStr:='';
  315. end;
  316. function TSwitchItem.GetNumberStr(SM: TSwitchMode): string;
  317. begin
  318. Abstract;
  319. GetNumberStr:='';
  320. end;
  321. function TSwitchItem.GetOptionStr(SM: TSwitchMode): string;
  322. begin
  323. Abstract;
  324. GetOptionStr:='';
  325. end;
  326. procedure TSwitchItem.Reset;
  327. begin
  328. end;
  329. {*****************************************************************************
  330. TSelectItem
  331. *****************************************************************************}
  332. constructor TSelectItem.Init(const n,p:string; AID: TParamID);
  333. begin
  334. Inherited Init(n,p,AID);
  335. Typ:=ot_Select;
  336. IsDefault:=false;
  337. end;
  338. constructor TSelectItem.InitDefault(const n:string);
  339. begin
  340. Inherited Init(n,'',idNone);
  341. Typ:=ot_Select;
  342. IsDefault:=true;
  343. end;
  344. {*****************************************************************************
  345. TBooleanItem
  346. *****************************************************************************}
  347. constructor TBooleanItem.Init(const n,p:string; AID: TParamID);
  348. begin
  349. Inherited Init(n,p,AID);
  350. Typ:=ot_Boolean;
  351. Reset;
  352. end;
  353. function TBooleanItem.NeedParam:boolean;
  354. begin
  355. NeedParam:=IsSet[SwitchesMode];
  356. end;
  357. procedure TBooleanItem.Reset;
  358. begin
  359. FillChar(IsSet,sizeof(IsSet),0);
  360. end;
  361. function TBooleanItem.ParamValueBool(SM: TSwitchMode):boolean;
  362. begin
  363. ParamValueBool:=IsSet[SM];
  364. end;
  365. function TBooleanItem.GetSwitchStr(SM: TSwitchMode): string;
  366. begin
  367. GetSwitchStr:=BoolToStr(IsSet[SM],'+','-');
  368. end;
  369. {*****************************************************************************
  370. TStringItem
  371. *****************************************************************************}
  372. constructor TStringItem.Init(const n,p:string; AID: TParamID; mult,allowspaces:boolean);
  373. begin
  374. Inherited Init(n,p,AID);
  375. Typ:=ot_String;
  376. Multiple:=mult;
  377. SeparateSpaces:=not allowspaces;
  378. Reset;
  379. end;
  380. function TStringItem.NeedParam:boolean;
  381. begin
  382. NeedParam:=(Str[SwitchesMode]<>'');
  383. end;
  384. function TStringItem.ParamValue(nr:sw_integer):string;
  385. begin
  386. ParamValue:=Str[SwitchesMode];
  387. end;
  388. procedure TStringItem.Reset;
  389. begin
  390. FillChar(Str,sizeof(Str),0);
  391. end;
  392. {*****************************************************************************
  393. TMultiStringItem
  394. *****************************************************************************}
  395. constructor TMultiStringItem.Init(const n,p:string;AID:TParamID);
  396. var i:TSwitchMode;
  397. begin
  398. inherited Init(n,p,AID);
  399. typ:=ot_MultiString;
  400. for i:=low(MultiStr) to high(MultiStr) do
  401. new(MultiStr[i],init(5,5));
  402. { Reset;}
  403. end;
  404. function TMultiStringItem.NeedParam:boolean;
  405. begin
  406. NeedParam:=(multistr[SwitchesMode]^.count<>0);
  407. end;
  408. function TMultiStringItem.ParamValue(nr:sw_integer):string;
  409. begin
  410. ParamValue:=MultiStr[SwitchesMode]^.at(nr)^;
  411. end;
  412. function TMultiStringItem.ParamCount:sw_integer;
  413. begin
  414. ParamCount:=Multistr[SwitchesMode]^.count;
  415. end;
  416. procedure TMultiStringItem.Reset;
  417. var i:TSwitchMode;
  418. begin
  419. for i:=low(multiStr) to high(multiStr) do
  420. MultiStr[i]^.freeall;
  421. end;
  422. destructor TmultiStringItem.done;
  423. var i:TSwitchMode;
  424. begin
  425. for i:=low(MultiStr) to high(MultiStr) do
  426. dispose(MultiStr[i],done);
  427. inherited done;
  428. end;
  429. {*****************************************************************************
  430. TLongintItem
  431. *****************************************************************************}
  432. constructor TLongintItem.Init(const n,p:string; AID: TParamID);
  433. begin
  434. Inherited Init(n,p,AID);
  435. Typ:=ot_Longint;
  436. Reset;
  437. end;
  438. function TLongintItem.NeedParam:boolean;
  439. begin
  440. NeedParam:=(Val[SwitchesMode]<>0);
  441. end;
  442. function TLongintItem.ParamValue(nr:sw_integer):string;
  443. var
  444. s : string;
  445. begin
  446. Str(Val[SwitchesMode],s);
  447. ParamValue:=s;
  448. end;
  449. procedure TLongintItem.Reset;
  450. begin
  451. FillChar(Val,sizeof(Val),0);
  452. end;
  453. function TLongintItem.GetNumberStr(SM: TSwitchMode): string;
  454. begin
  455. GetNumberStr:=IntToStr(Val[SM]);
  456. end;
  457. {*****************************************************************************
  458. TSwitch
  459. *****************************************************************************}
  460. constructor TSwitches.Init(ch:char);
  461. begin
  462. new(Items,Init(10,5));
  463. Prefix:=ch;
  464. FillChar(SelNr,SizeOf(SelNr),#0);
  465. IsSel:=false;
  466. end;
  467. constructor TSwitches.InitSelect(ch:char);
  468. begin
  469. new(Items,Init(10,5));
  470. Prefix:=ch;
  471. FillChar(SelNr,SizeOf(SelNr),#0);
  472. IsSel:=true;
  473. end;
  474. destructor TSwitches.Done;
  475. begin
  476. dispose(Items,Done);
  477. end;
  478. procedure TSwitches.AddSelectItem(const name,param:string; AID: TParamID);
  479. begin
  480. Items^.Insert(New(PSelectItem,Init(name,Param,AID)));
  481. end;
  482. procedure TSwitches.AddDefaultSelect(const name:string);
  483. begin
  484. Items^.Insert(New(PSelectItem,InitDefault(name)));
  485. end;
  486. procedure TSwitches.AddBooleanItem(const name,param:string; AID: TParamID);
  487. begin
  488. Items^.Insert(New(PBooleanItem,Init(name,Param,AID)));
  489. end;
  490. procedure TSwitches.AddLongintItem(const name,param:string; AID: TParamID);
  491. begin
  492. Items^.Insert(New(PLongintItem,Init(name,Param,AID)));
  493. end;
  494. procedure TSwitches.AddStringItem(const name,param:string;AID:TParamID;mult,allowspaces:boolean);
  495. begin
  496. Items^.Insert(New(PStringItem,Init(name,Param,AID,mult,allowspaces)));
  497. end;
  498. procedure TSwitches.AddMultiStringItem(const name,param:string;AID:TParamID);
  499. begin
  500. Items^.Insert(New(PMultiStringItem,Init(name,Param,AID)));
  501. end;
  502. function TSwitches.ItemCount:integer;
  503. begin
  504. ItemCount:=Items^.Count;
  505. end;
  506. function TSwitches.ItemName(index:integer):string;
  507. var
  508. P : PSwitchItem;
  509. begin
  510. if index<ItemCount then
  511. P:=Items^.At(Index)
  512. else
  513. P:=nil;
  514. if assigned(P) then
  515. ItemName:=P^.Name
  516. else
  517. ItemName:='';
  518. end;
  519. function TSwitches.ItemParam(index:integer):string;
  520. var
  521. P : PSwitchItem;
  522. begin
  523. if index<ItemCount then
  524. P:=Items^.At(Index)
  525. else
  526. P:=nil;
  527. if assigned(P) then
  528. ItemParam:='-'+Prefix+P^.Param
  529. else
  530. ItemParam:='';
  531. end;
  532. function TSwitches.GetBooleanItem(index:integer):boolean;
  533. var
  534. P : PBooleanItem;
  535. begin
  536. if index<ItemCount then
  537. P:=Items^.At(Index)
  538. else
  539. P:=nil;
  540. if assigned(P) and (P^.Typ=ot_boolean) then
  541. GetBooleanItem:=P^.IsSet[SwitchesMode]
  542. else
  543. GetBooleanItem:=false;
  544. end;
  545. function TSwitches.GetLongintItem(index:integer):longint;
  546. var
  547. P : PLongintItem;
  548. begin
  549. if index<ItemCount then
  550. P:=Items^.At(Index)
  551. else
  552. P:=nil;
  553. if assigned(P) and (P^.Typ=ot_longint) then
  554. GetLongintItem:=P^.Val[SwitchesMode]
  555. else
  556. GetLongintItem:=0;
  557. end;
  558. function TSwitches.GetStringItem(index:integer):string;
  559. var
  560. P : PStringItem;
  561. begin
  562. if index<ItemCount then
  563. P:=Items^.At(Index)
  564. else
  565. P:=nil;
  566. if assigned(P) and (P^.Typ=ot_string) then
  567. GetStringItem:=P^.Str[SwitchesMode]
  568. else
  569. GetStringItem:='';
  570. end;
  571. function TSwitches.GetMultiStringItem(index:integer):PUnsortedStringCollection;
  572. var p:PMultiStringItem;
  573. begin
  574. if index<ItemCount then
  575. p:=Items^.at(Index)
  576. else
  577. p:=nil;
  578. if (p<>nil) and (p^.typ=ot_multistring) then
  579. GetMultiStringItem:=p^.MultiStr[SwitchesMode]
  580. else
  581. GetMultiStringItem:=nil;
  582. end;
  583. function TSwitches.GetItemTyp(index:integer):TSwitchItemTyp;
  584. var p:PSwitchItem;
  585. begin
  586. assert(index<itemcount);
  587. GetItemTyp:=PSwitchItem(items^.at(index))^.typ;
  588. end;
  589. procedure TSwitches.SetBooleanItem(index:integer;b:boolean);
  590. var
  591. P : PBooleanItem;
  592. begin
  593. if index<ItemCount then
  594. P:=Items^.At(Index)
  595. else
  596. P:=nil;
  597. if assigned(P) and (P^.Typ=ot_boolean) then
  598. P^.IsSet[SwitchesMode]:=b;
  599. end;
  600. procedure TSwitches.SetLongintItem(index:integer;l:longint);
  601. var
  602. P : PLongintItem;
  603. begin
  604. if index<ItemCount then
  605. P:=Items^.At(Index)
  606. else
  607. P:=nil;
  608. if assigned(P) and (P^.Typ=ot_longint) then
  609. P^.Val[SwitchesMode]:=l;
  610. end;
  611. procedure TSwitches.SetStringItem(index:integer;const s:string);
  612. var
  613. P : PStringItem;
  614. begin
  615. if index<ItemCount then
  616. P:=Items^.At(Index)
  617. else
  618. P:=nil;
  619. if assigned(P) and (P^.Typ=ot_string) then
  620. P^.Str[SwitchesMode]:=s;
  621. end;
  622. function TSwitches.GetCurrSel:integer;
  623. begin
  624. if IsSel then
  625. GetCurrSel:=SelNr[SwitchesMode]
  626. else
  627. GetCurrSel:=-1;
  628. end;
  629. function TSwitches.GetCurrSelParam : String;
  630. begin
  631. if IsSel then
  632. GetCurrSelParam:=PSwitchItem(Items^.At(SelNr[SwitchesMode]))^.Param
  633. else
  634. GetCurrSelParam:='';
  635. end;
  636. procedure TSwitches.SetCurrSel(index:integer);
  637. begin
  638. if IsSel then
  639. SelNr[SwitchesMode]:=index;
  640. end;
  641. function TSwitches.SetCurrSelParam(const s : String) : boolean;
  642. function checkitem(P:PSwitchItem):boolean;{$ifndef FPC}far;{$endif}
  643. begin
  644. { empty items are not equivalent to others !! }
  645. CheckItem:=((S='') and (P^.Param='')) or
  646. ((Length(S)>0) and (P^.Param=s));
  647. end;
  648. var
  649. FoundP : PSwitchItem;
  650. begin
  651. FoundP:=Items^.FirstThat(@CheckItem);
  652. if Assigned(FoundP) then
  653. begin
  654. SetCurrSelParam:=true;
  655. SelNr[SwitchesMode]:=Items^.IndexOf(FoundP);
  656. end
  657. else
  658. SetCurrSelParam:=false;
  659. end;
  660. procedure TSwitches.WriteItemsCfg;
  661. var
  662. Pref : char;
  663. procedure writeitem(P:PSwitchItem);{$ifndef FPC}far;{$endif}
  664. var
  665. s,s1 : string;
  666. i,j : integer;
  667. begin
  668. if P^.NeedParam then
  669. begin
  670. if (P^.Typ=ot_string) and (PStringItem(P)^.Multiple) then
  671. begin
  672. s:=PStringItem(P)^.Str[SwitchesMode];
  673. repeat
  674. i:=pos(';',s);
  675. if PStringItem(P)^.SeparateSpaces then
  676. j:=pos(' ',s)
  677. else
  678. j:=0;
  679. if i=0 then
  680. i:=256;
  681. if (j>0) and (j<i) then
  682. i:=j;
  683. s1:=Copy(s,1,i-1);
  684. if s1<>'' then
  685. writeln(CfgFile,' -'+Pref+P^.Param+s1);
  686. Delete(s,1,i);
  687. until s='';
  688. end
  689. else
  690. if P^.Param<>'/' then
  691. for i:=0 to p^.ParamCount-1 do
  692. Writeln(CfgFile,' -'+Pref+P^.Param+P^.ParamValue(i));
  693. end;
  694. end;
  695. var
  696. P : PSelectItem;
  697. begin
  698. Pref:=Prefix;
  699. if IsSel then
  700. begin
  701. { can be empty for some targets }
  702. If Items^.count>0 then
  703. begin
  704. P:=Items^.At(SelNr[SwitchesMode]);
  705. if not P^.IsDefault then
  706. writeln(CfgFile,' '+ItemParam(SelNr[SwitchesMode]));
  707. end;
  708. end
  709. else
  710. Items^.ForEach(@writeitem);
  711. end;
  712. procedure WriteCustom;
  713. var
  714. s : string;
  715. i : longint;
  716. begin
  717. s:=CustomArg[SwitchesMode];
  718. While s<>'' do
  719. begin
  720. i:=pos(' ',s);
  721. if i=0 then i:=256;
  722. writeln(CfgFile,' '+Copy(s,1,i-1));
  723. if i=256 then
  724. s:=''
  725. else
  726. s:=copy(s,i+1,255);
  727. end;
  728. end;
  729. function TSwitches.ReadItemsCfg(const s:string):boolean;
  730. function checkitem(P:PSwitchItem):boolean;{$ifndef FPC}far;{$endif}
  731. begin
  732. { empty items are not equivalent to others !! }
  733. { but -dGDB didn't work because of this PM }
  734. CheckItem:=((P^.Param='') and ((S='') or (P^.typ=ot_String))) or
  735. ((Length(P^.Param)>0) and (P^.Param=Copy(s,1,length(P^.Param))));
  736. end;
  737. var
  738. FoundP : PSwitchItem;
  739. code : integer;
  740. begin
  741. FoundP:=Items^.FirstThat(@checkitem);
  742. if assigned(FoundP) then
  743. begin
  744. case FoundP^.Typ of
  745. ot_Select : SelNr[SwitchesMode]:=Items^.IndexOf(FoundP);
  746. ot_Boolean : PBooleanItem(FoundP)^.IsSet[SwitchesMode]:=true;
  747. ot_String : begin
  748. if (PStringItem(FoundP)^.Multiple) and (PStringItem(FoundP)^.Str[SwitchesMode]<>'') then
  749. PStringItem(FoundP)^.Str[SwitchesMode]:=PStringItem(FoundP)^.Str[SwitchesMode]+';'+
  750. Copy(s,length(FoundP^.Param)+1,255)
  751. else
  752. PStringItem(FoundP)^.Str[SwitchesMode]:=Copy(s,length(FoundP^.Param)+1,255);
  753. end;
  754. ot_MultiString :
  755. PMultiStringItem(foundP)^.MultiStr[SwitchesMode]^.insert(newstr(copy(s,length(foundP^.param)+1,255)));
  756. ot_Longint : Val(Copy(s,length(FoundP^.Param)+1,255),PLongintItem(FoundP)^.Val[SwitchesMode],code);
  757. end;
  758. ReadItemsCfg:=true;
  759. end
  760. else
  761. ReadItemsCfg:=false;
  762. end;
  763. {*****************************************************************************
  764. Read / Write
  765. *****************************************************************************}
  766. procedure WriteSwitches(const fn:string);
  767. var
  768. OldSwitchesMode, SWM: TSwitchMode;
  769. begin
  770. { create the switches }
  771. assign(CfgFile,fn);
  772. {$I-}
  773. rewrite(CfgFile);
  774. {$I+}
  775. if ioresult<>0 then
  776. exit;
  777. writeln(CfgFile,'# '+msg_automaticallycreateddontedit);
  778. OldSwitchesMode:=SwitchesMode;
  779. for SWM:=low(TSwitchMode) to high(TSwitchMode) do
  780. begin
  781. SwitchesMode := SWM;
  782. Writeln(CfgFile,'#IFDEF '+SwitchesModeStr[SwitchesMode]);
  783. TargetSwitches^.WriteItemsCfg;
  784. VerboseSwitches^.WriteItemsCfg;
  785. SyntaxSwitches^.WriteItemsCfg;
  786. CompilerModeSwitches^.WriteItemsCfg;
  787. CodegenSwitches^.WriteItemsCfg;
  788. OptimizationSwitches^.WriteItemsCfg;
  789. OptimizingGoalSwitches^.WriteItemsCfg;
  790. ProcessorSwitches^.WriteItemsCfg;
  791. AsmReaderSwitches^.WriteItemsCfg;
  792. AsmInfoSwitches^.WriteItemsCfg;
  793. AsmOutputSwitches^.WriteItemsCfg;
  794. DirectorySwitches^.WriteItemsCfg;
  795. MemorySwitches^.WriteItemsCfg;
  796. ConditionalSwitches^.WriteItemsCfg;
  797. LibLinkerSwitches^.WriteItemsCfg;
  798. OtherLinkerSwitches^.WriteItemsCfg;
  799. DebugInfoSwitches^.WriteItemsCfg;
  800. ProfileInfoSwitches^.WriteItemsCfg;
  801. LinkAfterSwitches^.WriteItemsCfg;
  802. BrowserSwitches^.WriteItemsCfg;
  803. {MemorySizeSwitches^.WriteItemsCfg;}
  804. WriteCustom;
  805. Writeln(CfgFile,'#ENDIF');
  806. Writeln(CfgFile,'');
  807. end;
  808. close(CfgFile);
  809. SwitchesMode:=OldSwitchesMode;
  810. end;
  811. procedure ReadSwitches(const fn:string);
  812. var
  813. c : char;
  814. s : string;
  815. res : boolean;
  816. OldSwitchesMode,i : TSwitchMode;
  817. begin
  818. assign(CfgFile,fn);
  819. {$I-}
  820. reset(CfgFile);
  821. {$I+}
  822. if ioresult<>0 then
  823. begin
  824. SetDefaultSwitches;
  825. exit;
  826. end;
  827. OldSwitchesMode:=SwitchesMode;
  828. SwitchesMode:=om_Normal;
  829. while not eof(CfgFile) do
  830. begin
  831. readln(CfgFile,s);
  832. s:=LTrim(s);
  833. if (length(s)>=2) and (s[1]='-') then
  834. begin
  835. c:=s[2];
  836. res:=false;
  837. Delete(s,1,2);
  838. case c of
  839. 'a' : res:=AsmInfoSwitches^.ReadItemsCfg(s);
  840. 'A' : res:=AsmOutputSwitches^.ReadItemsCfg(s);
  841. 'b' : res:=BrowserSwitches^.ReadItemsCfg(s);
  842. 'C' : begin
  843. res:=CodegenSwitches^.ReadItemsCfg(s);
  844. if not res then
  845. res:=MemorySwitches^.ReadItemsCfg(s);
  846. end;
  847. 'd' : res:=ConditionalSwitches^.ReadItemsCfg(s);
  848. 'F' : res:=DirectorySwitches^.ReadItemsCfg(s);
  849. 'g' : res:=DebugInfoSwitches^.ReadItemsCfg(s);
  850. 'O' : begin
  851. res:=true;
  852. if not OptimizationSwitches^.ReadItemsCfg(s) then
  853. if not ProcessorSwitches^.ReadItemsCfg(s) then
  854. res:=OptimizingGoalSwitches^.ReadItemsCfg(s);
  855. end;
  856. 'M' : res:=CompilerModeSwitches^.ReadItemsCfg(s);
  857. 'p' : res:=ProfileInfoSwitches^.ReadItemsCfg(s);
  858. 's' : res:=LinkAfterSwitches^.ReadItemsCfg(s);
  859. 'R' : res:=AsmReaderSwitches^.ReadItemsCfg(s);
  860. 'S' : res:=SyntaxSwitches^.ReadItemsCfg(s);
  861. 'T' : res:=TargetSwitches^.ReadItemsCfg(s);
  862. 'v' : res:=VerboseSwitches^.ReadItemsCfg(s);
  863. 'X' : begin
  864. res:=LibLinkerSwitches^.ReadItemsCfg(s);
  865. if not res then
  866. res:=OtherLinkerSwitches^.ReadItemsCfg(s);
  867. end;
  868. end;
  869. { keep all others as a string }
  870. if not res then
  871. CustomArg[SwitchesMode]:=CustomArg[SwitchesMode]+' -'+c+s;
  872. end
  873. else
  874. if (Copy(s,1,7)='#IFDEF ') then
  875. begin
  876. Delete(s,1,7);
  877. for i:=low(TSwitchMode) to high(TSwitchMode) do
  878. if s=SwitchesModeStr[i] then
  879. begin
  880. SwitchesMode:=i;
  881. break;
  882. end;
  883. end
  884. else;
  885. end;
  886. close(CfgFile);
  887. SwitchesMode:=OldSwitchesMode;
  888. end;
  889. function GetSourceDirectories : string;
  890. var
  891. P : PStringItem;
  892. S : String;
  893. c : char;
  894. function checkitem(P:PSwitchItem):boolean;{$ifndef FPC}far;{$endif}
  895. begin
  896. CheckItem:=(P^.Typ=ot_string) and (P^.Param=c);
  897. end;
  898. begin
  899. GetSourceDirectories:='';
  900. c:='u';
  901. P:=DirectorySwitches^.Items^.FirstThat(@CheckItem);
  902. S:='';
  903. if assigned(P) then
  904. S:=P^.Str[SwitchesMode];
  905. c:='i';
  906. P:=DirectorySwitches^.Items^.FirstThat(@CheckItem);
  907. if assigned(P) then
  908. S:=P^.Str[SwitchesMode]+';'+S;
  909. if S='' then
  910. GetSourceDirectories:=SourceDirs+';'
  911. else
  912. GetSourceDirectories:=SourceDirs+';'+S+';';
  913. end;
  914. {*****************************************************************************
  915. Initialize
  916. *****************************************************************************}
  917. procedure InitSwitches;
  918. var
  919. t : tsystem;
  920. begin
  921. New(SyntaxSwitches,Init('S'));
  922. with SyntaxSwitches^ do
  923. begin
  924. // AddBooleanItem(opt_objectpascal,'2',idNone);
  925. AddBooleanItem(opt_stopafterfirsterror,'e',idNone);
  926. AddBooleanItem(opt_allowlabelandgoto,'g',idNone);
  927. AddBooleanItem(opt_globalcmacros,'m',idNone);
  928. AddBooleanItem(opt_cplusplusstyledinline,'i',idNone);
  929. // AddBooleanItem(opt_tp7compatibility,'o',idNone);
  930. // AddBooleanItem(opt_delphicompatibility,'d',idNone);
  931. AddBooleanItem(opt_assertions,'a',idNone);
  932. AddBooleanItem(opt_kylix,'k',idNone);
  933. AddBooleanItem(opt_allowstaticinobjects,'s',idNone);
  934. AddBooleanItem(opt_clikeoperators,'c',idNone);
  935. { Useless as they are not passed to the compiler PM
  936. AddBooleanItem(opt_strictvarstrings,'/',idStrictVarStrings);
  937. AddBooleanItem(opt_extendedsyntax,'/',idExtendedSyntax);
  938. AddBooleanItem(opt_allowmmxoperations,'/',idMMXOps); }
  939. end;
  940. New(CompilerModeSwitches,InitSelect('M'));
  941. with CompilerModeSwitches^ do
  942. begin
  943. AddSelectItem(opt_mode_freepascal,'fpc',idNone);
  944. AddSelectItem(opt_mode_objectpascal,'objfpc',idNone);
  945. AddSelectItem(opt_mode_turbopascal,'tp',idNone);
  946. AddSelectItem(opt_mode_delphi,'delphi',idNone);
  947. AddSelectItem(opt_mode_macpascal,'macpascal',idNone);
  948. { GNU Pascal mode doesn't do much, better disable it
  949. AddSelectItem(opt_mode_gnupascal,'gpc',idNone);}
  950. end;
  951. New(VerboseSwitches,Init('v'));
  952. with VerboseSwitches^ do
  953. begin
  954. AddBooleanItem(opt_warnings,'w',idNone);
  955. AddBooleanItem(opt_notes,'n',idNone);
  956. AddBooleanItem(opt_hints,'h',idNone);
  957. AddBooleanItem(opt_generalinfo,'i',idNone);
  958. AddBooleanItem(opt_usedtriedinfo,'ut',idNone);
  959. AddBooleanItem(opt_all,'a',idNone);
  960. AddBooleanItem(opt_showallprocsonerror,'b',idNone);
  961. end;
  962. New(CodegenSwitches,Init('C'));
  963. with CodegenSwitches^ do
  964. begin
  965. AddBooleanItem(opt_rangechecking,'r',idRangeChecks);
  966. AddBooleanItem(opt_stackchecking,'t',idStackChecks);
  967. AddBooleanItem(opt_iochecking,'i',idIOChecks);
  968. AddBooleanItem(opt_overflowchecking,'o',idOverflowChecks);
  969. AddBooleanItem(opt_objmethcallvalid,'R',idObjMethCallChecks);
  970. AddBooleanItem(opt_pic,'g',idNone);
  971. AddBooleanItem(opt_smart,'X',idNone);
  972. end;
  973. New(OptimizingGoalSwitches,InitSelect('O'));
  974. with OptimizingGoalSwitches^ do
  975. begin
  976. AddSelectItem(opt_generatefastercode,'G',idNone);
  977. AddSelectItem(opt_generatesmallercode,'g',idNone);
  978. end;
  979. New(OptimizationSwitches,Init('O'));
  980. with OptimizationSwitches^ do
  981. begin
  982. {$ifdef I386}
  983. AddBooleanItem(opt_useregistervariables,'r',idNone);
  984. AddBooleanItem(opt_uncertainoptimizations,'u',idNone);
  985. AddBooleanItem(opt_level1optimizations,'1',idNone);
  986. AddBooleanItem(opt_level2optimizations,'2',idNone);
  987. {$else not I386}
  988. {$ifdef m68k}
  989. AddBooleanItem(opt_level1optimizations,'a',idNone);
  990. AddBooleanItem(opt_useregistervariables,'x',idNone);
  991. {$endif m68k}
  992. {$endif I386}
  993. end;
  994. New(ProcessorSwitches,InitSelect('O'));
  995. with ProcessorSwitches^ do
  996. begin
  997. {$ifdef I386}
  998. AddSelectItem(opt_i386486,'p1',idNone);
  999. AddSelectItem(opt_pentiumandmmx,'p2',idNone);
  1000. AddSelectItem(opt_pentiumpro,'p3',idNone);
  1001. AddSelectItem(opt_pentiumiv,'p4',idNone);
  1002. {$else not I386}
  1003. {$ifdef m68k}
  1004. AddSelectItem(opt_m68000,'',idNone);
  1005. AddSelectItem(opt_m68020,'2',idNone);
  1006. {$endif m68k}
  1007. {$endif not I386}
  1008. end;
  1009. New(TargetSwitches,InitSelect('T'));
  1010. with TargetSwitches^ do
  1011. begin
  1012. { better, we've a correct target list without "tilded" names instead a wrong one }
  1013. for t:=low(tsystem) to high(tsystem) do
  1014. if assigned(targetinfos[t]) then
  1015. AddSelectItem(targetinfos[t]^.name,targetinfos[t]^.shortname,idNone);
  1016. end;
  1017. New(AsmReaderSwitches,InitSelect('R'));
  1018. with AsmReaderSwitches^ do
  1019. begin
  1020. {$ifdef I386}
  1021. { AddSelectItem(opt_directassembler,'direct',idAsmDirect);}
  1022. AddSelectItem(opt_attassembler,'att',idAsmATT);
  1023. AddSelectItem(opt_intelassembler,'intel',idAsmIntel);
  1024. {$endif I386}
  1025. {$ifdef M68K}
  1026. AddSelectItem(opt_motassembler,'mot',idAsmDirect);
  1027. {$endif M68K}
  1028. end;
  1029. New(AsmInfoSwitches,Init('a'));
  1030. with AsmInfoSwitches^ do
  1031. begin
  1032. AddBooleanItem(opt_listsource,'l',idNone);
  1033. AddBooleanItem(opt_listregisterallocation,'r',idNone);
  1034. AddBooleanItem(opt_listtempallocation,'t',idNone);
  1035. end;
  1036. New(AsmOutputSwitches,InitSelect('A'));
  1037. with AsmOutputSwitches^ do
  1038. begin
  1039. AddDefaultSelect(opt_usedefaultas);
  1040. {$ifdef I386}
  1041. AddSelectItem(opt_usegnuas,'as',idNone);
  1042. AddSelectItem(opt_usenasmcoff,'nasmcoff',idNone);
  1043. AddSelectItem(opt_usenasmelf,'nasmelf',idNone);
  1044. AddSelectItem(opt_usenasmobj,'nasmobj',idNone);
  1045. AddSelectItem(opt_usemasm,'masm',idNone);
  1046. AddSelectItem(opt_usetasm,'tasm',idNone);
  1047. AddSelectItem(opt_usecoff,'coff',idNone);
  1048. AddSelectItem(opt_usepecoff,'pecoff',idNone);
  1049. {$endif I386}
  1050. end;
  1051. New(BrowserSwitches,InitSelect('b'));
  1052. with BrowserSwitches^ do
  1053. begin
  1054. AddSelectItem(opt_nobrowser,'-',idSymInfNone);
  1055. AddSelectItem(opt_globalonlybrowser,'+',idSymInfGlobalOnly);
  1056. AddSelectItem(opt_localglobalbrowser,'l',idSymInfGlobalLocal);
  1057. end;
  1058. New(ConditionalSwitches,Init('d'));
  1059. with ConditionalSwitches^ do
  1060. begin
  1061. AddStringItem(opt_conditionaldefines,'',idNone,true,false);
  1062. end;
  1063. New(MemorySwitches,Init('C'));
  1064. with MemorySwitches^ do
  1065. begin
  1066. AddLongintItem(opt_stacksize,'s',idStackSize);
  1067. AddLongintItem(opt_heapsize,'h',idHeapSize);
  1068. end;
  1069. New(DirectorySwitches,Init('F'));
  1070. with DirectorySwitches^ do
  1071. begin
  1072. AddMultiStringItem(opt_unitdirectories,'u',idNone);
  1073. AddMultiStringItem(opt_includedirectories,'i',idNone);
  1074. AddMultiStringItem(opt_librarydirectories,'l',idNone);
  1075. AddMultiStringItem(opt_objectdirectories,'o',idNone);
  1076. AddStringItem(opt_exeppudirectories,'E',idNone,true,true);
  1077. AddStringItem(opt_ppuoutputdirectory,'U',idNone,true,true);
  1078. AddStringItem(opt_cross_tools_directory,'D',idNone,true,true);
  1079. AddStringItem(opt_dynamic_linker,'L',idNone,false,false);
  1080. end;
  1081. New(LibLinkerSwitches,InitSelect('X'));
  1082. with LibLinkerSwitches^ do
  1083. begin
  1084. AddDefaultSelect(opt_librariesdefault);
  1085. AddSelectItem(opt_dynamiclibraries,'D',idNone);
  1086. AddSelectItem(opt_staticlibraries,'S',idNone);
  1087. AddSelectItem(opt_smartlibraries,'X',idNone);
  1088. end;
  1089. New(OtherLinkerSwitches,Init('X'));
  1090. with OtherLinkerSwitches^ do
  1091. begin
  1092. AddBooleanItem(opt_stripalldebugsymbols,'s',idNone);
  1093. AddBooleanItem(opt_forcestaticlibs,'t',idNone);
  1094. end;
  1095. New(DebugInfoSwitches,InitSelect('g'));
  1096. with DebugInfoSwitches^ do
  1097. begin
  1098. AddSelectItem(opt_nogendebugsymbolinfo,'-',idNone);
  1099. AddSelectItem(opt_gendebugsymbolinfo,'',idNone);
  1100. AddSelectItem(opt_gensymbolandbacktraceinfo,'l',idNone);
  1101. AddSelectItem(opt_valgrindinfo,'v',idNone);
  1102. { AddSelectItem('Generate ~d~bx symbol information','d');
  1103. does not work anyhow (PM) }
  1104. end;
  1105. New(LinkAfterSwitches,Init('s'));
  1106. LinkAfterSwitches^.AddBooleanItem(opt_linkafter,'',idNone);
  1107. New(ProfileInfoSwitches,InitSelect('p'));
  1108. with ProfileInfoSwitches^ do
  1109. begin
  1110. AddSelectItem(opt_noprofileinfo,'-',idNone);
  1111. AddSelectItem(opt_gprofinfo,'g',idNone);
  1112. end;
  1113. {New(MemorySizeSwitches,Init('C'));
  1114. with MemorySizeSwitches^ do
  1115. begin
  1116. AddLongIntItem('~S~tack size','s');
  1117. AddLongIntItem('Local ~h~eap size','h');
  1118. end;}
  1119. SwitchesPath:=LocateFile(SwitchesName);
  1120. if SwitchesPath='' then
  1121. SwitchesPath:=SwitchesName;
  1122. SwitchesPath:=FExpand(SwitchesPath);
  1123. end;
  1124. procedure SetDefaultSwitches;
  1125. var
  1126. i,OldSwitchesMode : TSwitchMode;
  1127. begin
  1128. { setup some useful defaults }
  1129. OldSwitchesMode:=SwitchesMode;
  1130. for i:=low(TSwitchMode) to high(TSwitchMode) do
  1131. begin
  1132. SwitchesMode:=i;
  1133. {$ifdef i386}
  1134. { default is Pentium }
  1135. ProcessorSwitches^.SetCurrSel(1);
  1136. { AT&T reader }
  1137. AsmReaderSwitches^.SetCurrSel(1);
  1138. {$endif i386}
  1139. { FPC mode}
  1140. CompilerModeSwitches^.SetCurrSel(0);
  1141. (* Use platform defaults for memory switches. *)
  1142. { 128k stack }
  1143. { MemorySwitches^.SetLongintItem(0,65536*2);}
  1144. MemorySwitches^.SetLongintItem(0,0);
  1145. { 2 MB heap }
  1146. { MemorySwitches^.SetLongintItem(1,1024*1024*2);}
  1147. MemorySwitches^.SetLongintItem(1,0);
  1148. { goto/lable allowed }
  1149. SyntaxSwitches^.SetBooleanItem(1,true);
  1150. { inline allowed }
  1151. SyntaxSwitches^.SetBooleanItem(3,true);
  1152. { Exe size complaints are louder than speed complaints: Optimize for size by default. }
  1153. OptimizingGoalSwitches^.SetCurrSel(1);
  1154. case i of
  1155. om_debug:
  1156. begin
  1157. { debugging info on }
  1158. DebugInfoSwitches^.SetCurrSel(1);
  1159. { range checking }
  1160. CodegenSwitches^.SetBooleanItem(0,true);
  1161. { io checking }
  1162. CodegenSwitches^.SetBooleanItem(2,true);
  1163. { overflow checking }
  1164. CodegenSwitches^.SetBooleanItem(3,true);
  1165. { method call checking }
  1166. CodegenSwitches^.SetBooleanItem(4,true);
  1167. { assertions on }
  1168. SyntaxSwitches^.SetBooleanItem(4,true);
  1169. end;
  1170. om_normal:
  1171. begin
  1172. {Register variables.}
  1173. OptimizationSwitches^.SetBooleanItem(0,true);
  1174. {Level 1 optimizations.}
  1175. OptimizationSwitches^.SetBooleanItem(2,true);
  1176. end;
  1177. om_release:
  1178. begin
  1179. {Register variables.}
  1180. OptimizationSwitches^.SetBooleanItem(0,true);
  1181. {Level 2 optimizations.}
  1182. OptimizationSwitches^.SetBooleanItem(3,true);
  1183. {Smart linking.}
  1184. LibLinkerSwitches^.SetCurrSel(3);
  1185. CodegenSwitches^.SetBooleanItem(6,true);
  1186. {Strip debug info}
  1187. OtherLinkerSwitches^.SetBooleanItem(0,true);
  1188. end;
  1189. end;
  1190. { set appriopriate default target }
  1191. TargetSwitches^.SetCurrSelParam(target_info.shortname);
  1192. end;
  1193. SwitchesMode:=OldSwitchesMode;
  1194. end;
  1195. procedure DoneSwitches;
  1196. begin
  1197. dispose(SyntaxSwitches,Done);
  1198. dispose(CompilerModeSwitches,Done);
  1199. dispose(VerboseSwitches,Done);
  1200. dispose(CodegenSwitches,Done);
  1201. dispose(OptimizationSwitches,Done);
  1202. dispose(OptimizingGoalSwitches,Done);
  1203. dispose(ProcessorSwitches,Done);
  1204. dispose(BrowserSwitches,Done);
  1205. dispose(TargetSwitches,Done);
  1206. dispose(AsmReaderSwitches,Done);
  1207. dispose(AsmOutputSwitches,Done);
  1208. dispose(AsmInfoSwitches,Done);
  1209. dispose(ConditionalSwitches,Done);
  1210. dispose(MemorySwitches,Done);
  1211. {dispose(MemorySizeSwitches,Done);}
  1212. dispose(DirectorySwitches,Done);
  1213. dispose(DebugInfoSwitches,Done);
  1214. dispose(LibLinkerSwitches,Done);
  1215. dispose(LinkAfterSwitches,Done);
  1216. dispose(OtherLinkerSwitches,Done);
  1217. dispose(ProfileInfoSwitches,Done);
  1218. end;
  1219. procedure GetCompilerOptionLines(C: PUnsortedStringCollection);
  1220. procedure AddLine(const S: string);
  1221. begin
  1222. C^.Insert(NewStr(S));
  1223. end;
  1224. procedure ConstructSwitchModeDirectives(SM: TSwitchMode; const IfDefSym: string);
  1225. var SwitchParams: PStringCollection;
  1226. MiscParams : PStringCollection;
  1227. procedure AddSwitch(const S: string);
  1228. begin
  1229. SwitchParams^.Insert(NewStr(S));
  1230. end;
  1231. procedure AddParam(const S: string);
  1232. begin
  1233. MiscParams^.Insert(NewStr(S));
  1234. end;
  1235. procedure EnumSwitches(P: PSwitches);
  1236. procedure HandleSwitch(P: PSwitchItem); {$ifndef FPC}far;{$endif}
  1237. begin
  1238. case P^.ParamID of
  1239. { idAlign :}
  1240. idRangeChecks : AddSwitch('R'+P^.GetSwitchStr(SM));
  1241. idStackChecks : AddSwitch('S'+P^.GetSwitchStr(SM));
  1242. idIOChecks : AddSwitch('I'+P^.GetSwitchStr(SM));
  1243. idOverflowChecks : AddSwitch('Q'+P^.GetSwitchStr(SM));
  1244. idObjMethCallChecks: AddSwitch('OBJECTCHECKS'+P^.GetSwitchStr(SM));
  1245. { idAsmDirect : if P^.GetParamValueBool[SM] then AddParam('ASMMODE DIRECT');
  1246. idAsmATT : if P^.GetParamValueBool[SM] then AddParam('ASMMODE ATT');
  1247. idAsmIntel : if P^.GetParamValueBool[SM] then AddParam('ASMMODE INTEL');
  1248. idAsmMot : if P^.GetParamValueBool[SM] then AddParam('ASMMODE MOT');}
  1249. { idSymInfNone : ;
  1250. idSymInfGlobalOnly:;
  1251. idSymInfGlobalLocal:if P^.ParamValueBool(SM) then AddSwitch('L+');}
  1252. { idStackSize
  1253. idHeapSize}
  1254. idStrictVarStrings: AddSwitch('V'+P^.GetSwitchStr(SM));
  1255. idExtendedSyntax : AddSwitch('X'+P^.GetSwitchStr(SM));
  1256. idMMXOps : if P^.ParamValueBool(SM) then AddParam('MMX');
  1257. idTypedAddress : AddSwitch('T'+P^.GetSwitchStr(SM));
  1258. { idPackRecords
  1259. idPackEnum}
  1260. idStackFrames : AddSwitch('W'+P^.GetSwitchStr(SM));
  1261. idReferenceInfo : AddSwitch('Y'+P^.GetSwitchStr(SM));
  1262. idDebugInfo : AddSwitch('D'+P^.GetSwitchStr(SM));
  1263. idBoolEval : AddSwitch('B'+P^.GetSwitchStr(SM));
  1264. idLongString : AddSwitch('H'+P^.GetSwitchStr(SM));
  1265. idTypeInfo : AddSwitch('M'+P^.GetSwitchStr(SM));
  1266. end;
  1267. end;
  1268. begin
  1269. P^.Items^.ForEach(@HandleSwitch);
  1270. end;
  1271. var I: integer;
  1272. S: string;
  1273. begin
  1274. AddLine('{$IFDEF '+IfDefSym+'}');
  1275. New(SwitchParams, Init(10,10));
  1276. New(MiscParams, Init(10,10));
  1277. EnumSwitches(LibLinkerSwitches);
  1278. EnumSwitches(OtherLinkerSwitches);
  1279. EnumSwitches(DebugInfoSwitches);
  1280. EnumSwitches(ProfileInfoSwitches);
  1281. EnumSwitches(SyntaxSwitches);
  1282. EnumSwitches(CompilerModeSwitches);
  1283. EnumSwitches(VerboseSwitches);
  1284. EnumSwitches(CodegenSwitches);
  1285. EnumSwitches(OptimizationSwitches);
  1286. EnumSwitches(OptimizingGoalSwitches);
  1287. EnumSwitches(ProcessorSwitches);
  1288. EnumSwitches(AsmReaderSwitches);
  1289. EnumSwitches(AsmInfoSwitches);
  1290. EnumSwitches(AsmOutputSwitches);
  1291. EnumSwitches(TargetSwitches);
  1292. EnumSwitches(ConditionalSwitches);
  1293. EnumSwitches(MemorySwitches);
  1294. EnumSwitches(BrowserSwitches);
  1295. EnumSwitches(DirectorySwitches);
  1296. S:='';
  1297. for I:=0 to SwitchParams^.Count-1 do
  1298. begin
  1299. if I=0 then S:='{$' else S:=S+',';
  1300. S:=S+PString(SwitchParams^.At(I))^;
  1301. end;
  1302. if S<>'' then S:=S+'}';
  1303. if S<>'' then AddLine(' '+S);
  1304. for I:=0 to MiscParams^.Count-1 do
  1305. AddLine(' {$'+PString(MiscParams^.At(I))^+'}');
  1306. Dispose(SwitchParams, Done); Dispose(MiscParams, Done);
  1307. AddLine('{$ENDIF '+IfDefSym+'}');
  1308. end;
  1309. var SM: TSwitchMode;
  1310. begin
  1311. for SM:=Low(TSwitchMode) to High(TSwitchMode) do
  1312. ConstructSwitchModeDirectives(SM,SwitchesModeStr[SM]);
  1313. end;
  1314. end.