fpswitch.pas 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633
  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. {$ifdef cpullvm}
  13. {$modeswitch nestedprocvars}
  14. {$endif}
  15. {$H-}
  16. interface
  17. uses
  18. Objects,
  19. Systems,
  20. WUtils,
  21. FPConst;
  22. const
  23. MinMemSize = 1024; { min. local heap and stack size }
  24. MaxMemSize = 67107840; { max. local heap and stack size }
  25. type
  26. TParamID =
  27. (idNone,idAlign,idRangeChecks,idStackChecks,idIOChecks,
  28. idOverflowChecks,idObjMethCallChecks,
  29. idAsmDirect,idAsmATT,idAsmIntel,idAsmMot,idAsmStandard,
  30. idSymInfNone,idSymInfGlobalOnly,idSymInfGlobalLocal,
  31. idStackSize,idHeapSize,idStrictVarStrings,idExtendedSyntax,
  32. idMMXOps,idTypedAddress,idPackRecords,idPackEnum,idStackFrames,
  33. idReferenceInfo,idDebugInfo,idBoolEval,
  34. idAnsiString,idTypeInfo);
  35. TSwitchMode = (om_Normal,om_Debug,om_Release);
  36. TSwitchItemTyp = (ot_Select,ot_Boolean,ot_String,ot_MultiString,ot_Longint);
  37. PSwitchItem = ^TSwitchItem;
  38. TSwitchItem = object(TObject)
  39. Typ : TSwitchItemTyp;
  40. Name : string[50];
  41. Param : string[30];
  42. ParamID : TParamID;
  43. constructor Init(const n,p:string; AID: TParamID);
  44. function NeedParam:boolean;virtual;
  45. function ParamValue(nr:sw_integer):string;virtual;
  46. function ParamValueBool(SM: TSwitchMode):boolean;virtual;
  47. function ParamCount:sw_integer;virtual;
  48. function GetSwitchStr(SM: TSwitchMode): string; virtual;
  49. function GetNumberStr(SM: TSwitchMode): string; virtual;
  50. function GetOptionStr(SM: TSwitchMode): string; virtual;
  51. procedure Reset;virtual;
  52. end;
  53. PSelectItem = ^TSelectItem;
  54. TSelectItem = object(TSwitchItem)
  55. IsDefault : boolean;
  56. constructor Init(const n,p:string; AID: TParamID);
  57. { Select to avoid anything in config file }
  58. constructor InitDefault(const n:string);
  59. end;
  60. PBooleanItem = ^TBooleanItem;
  61. TBooleanItem = object(TSwitchItem)
  62. IsSet : array[TSwitchMode] of boolean;
  63. constructor Init(const n,p:string; AID: TParamID);
  64. function NeedParam:boolean;virtual;
  65. procedure Reset;virtual;
  66. function GetSwitchStr(SM: TSwitchMode): string; virtual;
  67. function ParamValueBool(SM: TSwitchMode):boolean;virtual;
  68. end;
  69. PStringItem = ^TStringItem;
  70. TStringItem = object(TSwitchItem)
  71. Str : array[TSwitchMode] of string;
  72. multiple : boolean;
  73. SeparateSpaces : boolean;
  74. constructor Init(const n,p:string;AID: TParamID; mult,allowspaces:boolean);
  75. function NeedParam:boolean;virtual;
  76. function ParamValue(nr:sw_integer):string;virtual;
  77. procedure Reset;virtual;
  78. end;
  79. PMultiStringItem = ^TMultiStringItem;
  80. TMultiStringItem = object(TSwitchItem)
  81. MultiStr : array[TSwitchMode] of PunsortedStringCollection;
  82. constructor Init(const n,p:string;AID: TParamID);
  83. function NeedParam:boolean;virtual;
  84. function ParamValue(nr:sw_integer):string;virtual;
  85. function ParamCount:sw_integer;virtual;
  86. procedure Reset;virtual;
  87. destructor done;virtual;
  88. end;
  89. PLongintItem = ^TLongintItem;
  90. TLongintItem = object(TSwitchItem)
  91. Val : array[TSwitchMode] of longint;
  92. constructor Init(const n,p:string; AID: TParamID);
  93. function NeedParam:boolean;virtual;
  94. function ParamValue(nr:sw_integer):string;virtual;
  95. function GetNumberStr(SM: TSwitchMode): string; virtual;
  96. procedure Reset;virtual;
  97. end;
  98. PSwitches = ^TSwitches;
  99. TSwitches = object
  100. constructor Init(ch:AnsiChar);
  101. constructor InitSelect(ch:AnsiChar);
  102. destructor Done;
  103. { general items }
  104. function ItemCount:integer;
  105. function ItemName(index:integer):string;
  106. function ItemParam(index:integer):string;
  107. { type specific }
  108. procedure AddSelectItem(const name,param:string; AID: TParamID);
  109. procedure AddDefaultSelect(const name:string);
  110. procedure AddBooleanItem(const name,param:string; AID: TParamID);
  111. procedure AddLongintItem(const name,param:string; AID: TParamID);
  112. procedure AddStringItem(const name,param:string;AID: TParamID;mult,allowspaces:boolean);
  113. procedure AddMultiStringItem(const name,param:string;AID: TParamID);
  114. function GetCurrSel:integer;
  115. function GetCurrSelParam : String;
  116. function GetBooleanItem(index:integer):boolean;
  117. function GetLongintItem(index:integer):longint;
  118. function GetStringItem(index:integer):string;
  119. function GetMultiStringItem(index:integer):PunsortedStringCollection;
  120. function GetItemTyp(index:integer):TSwitchItemTyp;
  121. procedure SetCurrSel(index:integer);
  122. function SetCurrSelParam(const s:string) : boolean;
  123. procedure SetBooleanItem(index:integer;b:boolean);
  124. procedure SetLongintItem(index:integer;l:longint);
  125. procedure SetStringItem(index:integer;const s:string);
  126. { read / write to cfgfile which must be open }
  127. procedure WriteItemsCfg;
  128. function ReadItemsCfg(const s:string):boolean;
  129. private
  130. IsSel : boolean;
  131. Prefix : AnsiChar;
  132. SelNr : array[TSwitchMode] of integer;
  133. Items : PCollection;
  134. end;
  135. const
  136. SwitchesMode : TSwitchMode = om_Normal;
  137. SwitchesModeName : array[TSwitchMode] of string[10]=
  138. ('~N~ormal','~D~ebug','~R~elease');
  139. SwitchesModeStr : array[TSwitchMode] of string[8]=
  140. ('NORMAL','DEBUG','RELEASE');
  141. CustomArg : array[TSwitchMode] of string{$ifndef FPC}[128]{$endif}=
  142. ('','','');
  143. var
  144. LibLinkerSwitches,
  145. OtherLinkerSwitches,
  146. DebugInfoSwitches,
  147. LinkAfterSwitches,
  148. ProfileInfoSwitches,
  149. {MemorySizeSwitches, doubled !! }
  150. SyntaxSwitches,
  151. CompilerModeSwitches,
  152. VerboseSwitches,
  153. CodegenSwitches,
  154. OptimizationSwitches,
  155. ProcessorCodeGenerationSwitches,
  156. ProcessorOptimizationSwitches,
  157. AsmReaderSwitches,
  158. AsmInfoSwitches,
  159. TargetSwitches,
  160. ConditionalSwitches,
  161. MemorySwitches,
  162. BrowserSwitches,
  163. DirectorySwitches : PSwitches;
  164. {Every mode can have different target, thus have its own AsmOutput}
  165. AsmOutputSwitches: array [TSwitchMode] of PSwitches;
  166. { write/read the Switches to fpc.cfg file }
  167. procedure WriteSwitches(const fn:string);
  168. procedure ReadSwitches(const fn:string);
  169. procedure UpdateAsmOutputSwitches;
  170. { initialize }
  171. procedure InitSwitches;
  172. procedure SetDefaultSwitches;
  173. procedure DoneSwitches;
  174. function GetSourceDirectories : string;
  175. procedure GetCompilerOptionLines(C: PUnsortedStringCollection);
  176. implementation
  177. uses
  178. Dos,
  179. GlobType,
  180. CpuInfo,
  181. FPVars,FPUtils;
  182. var
  183. CfgFile : text;
  184. {$ifdef useresstrings}
  185. resourcestring
  186. {$else}
  187. const
  188. {$endif}
  189. msg_automaticallycreateddontedit = 'Automatically created file, don''t edit.';
  190. { Compiler options }
  191. opt_objectpascal = 'Object pascal support';
  192. opt_clikeoperators = 'C-like operators';
  193. opt_stopafterfirsterror = 'Stop after first error';
  194. opt_allowlabelandgoto = 'Allow LABEL and GOTO';
  195. opt_cplusplusstyledinline = 'Allow inline';
  196. opt_globalcmacros = 'Enable macros';
  197. opt_allowstaticinobjects = 'Allow STATIC in objects';
  198. opt_assertions = 'Include assertion code';
  199. opt_kylix = 'Load Kylix compat. unit';
  200. opt_ansistring = 'Use Ansi Strings';
  201. opt_strictvarstrings = 'Strict var-strings';
  202. opt_extendedsyntax = 'Extended syntax';
  203. opt_allowmmxoperations = 'Allow MMX operations';
  204. opt_mode_freepascal = 'Free Pascal dialect';
  205. opt_mode_objectpascal = 'Object Pascal extension on';
  206. opt_mode_turbopascal = 'Turbo Pascal compatible';
  207. opt_mode_delphi = 'Delphi compatible';
  208. opt_mode_macpascal = 'Macintosh Pascal dialect';
  209. opt_mode_gnupascal = 'GNU Pascal';
  210. { Verbose options }
  211. opt_warnings = '~W~arnings';
  212. opt_notes = 'N~o~tes';
  213. opt_hints = '~H~ints';
  214. opt_generalinfo = 'General ~I~nfo';
  215. opt_usedtriedinfo = '~U~sed,tried info';
  216. opt_all = '~A~ll';
  217. opt_showallprocsonerror = 'Show all ~P~rocedures if error';
  218. { Checking options }
  219. opt_rangechecking = '~R~ange checking';
  220. opt_stackchecking = '~S~tack checking';
  221. opt_iochecking = '~I~/O checking';
  222. opt_overflowchecking = 'Integer ~o~verflow checking';
  223. opt_objmethcallvalid = 'Object ~m~ethod call checking';
  224. { Code generation }
  225. opt_pic = '~P~osition independent code';
  226. opt_smart = 'Create smart~l~inkable units';
  227. { Code options }
  228. //opt_generatefastercode = 'Generate ~f~aster code';
  229. opt_generatesmallercode = 'G~e~nerate smaller code';
  230. opt_useregistervariables = 'Use regis~t~er-variables';
  231. opt_uncertainoptimizations = '~U~ncertain optimizations';
  232. opt_level1optimizations = 'Level ~1~ optimizations';
  233. opt_level2optimizations = 'Level ~2~ optimizations';
  234. opt_level3optimizations = 'Level ~3~ optimizations';
  235. { optimization processor target }
  236. opt_i386486 = 'i~3~86/i486';
  237. opt_pentium = 'P~e~ntium (tm)';
  238. opt_pentiummmx = 'PentiumMM~X~ (tm)';
  239. opt_pentiumpro = '~P~entium2/PentiumM/AMD';
  240. opt_pentiumiv = 'Pentium~4~';
  241. opt_pentiumm = 'Pentium~M~';
  242. opt_m68000 = 'm~6~8000';
  243. opt_m68020 = 'm680~2~0';
  244. { Assembler options }
  245. opt_directassembler = '~D~irect assembler';
  246. opt_defaultassembler = '~D~efault style assembler';
  247. opt_attassembler = '~A~T&T style assembler';
  248. opt_intelassembler = '~I~ntel style assembler';
  249. opt_motassembler = '~M~otorola style assembler';
  250. opt_standardassembler = '~S~tandard style assembler';
  251. opt_listsource = '~L~ist source';
  252. opt_listregisterallocation = 'list ~r~egister allocation';
  253. opt_listtempallocation = 'list ~t~emp allocation';
  254. opt_listnodeallocation = 'list ~n~ode allocation';
  255. opt_useasmpipe = 'use ~p~ipe with assembler';
  256. { Assembler output selection }
  257. opt_usedefaultas = 'Use ~d~efault output';
  258. opt_usegnuas = 'Use ~G~NU as';
  259. { I386 assembler output selection }
  260. opt_usenasmcoff = 'Use ~N~ASM coff';
  261. opt_usenasmwin32 = 'Use NASM ~w~in32';
  262. opt_usenasmwdosx= 'Use ~N~ASM w~d~osx';
  263. opt_usenasmelf = 'Use NASM el~f~';
  264. opt_usenasmbeos = 'Use NASM ~b~eos';
  265. opt_usenasmobj = 'Use NASM ~o~bj';
  266. opt_usemasm = 'Use ~M~ASM';
  267. opt_usetasm = 'Use ~T~ASM';
  268. opt_usewasm = 'Use ~W~ASM';
  269. opt_usecoff = 'Use internal ~c~off';
  270. opt_usepecoff = 'Use internal ~p~ecoff';
  271. opt_usepecoffwdosx = 'Use internal pewdos~x~';
  272. opt_useelf= 'Use internal ~e~lf';
  273. { Browser options }
  274. opt_nobrowser = 'N~o~ browser';
  275. opt_globalonlybrowser = 'Only Glob~a~l browser';
  276. opt_localglobalbrowser = '~L~ocal and global browser';
  277. { Conditional defines }
  278. opt_conditionaldefines = 'Conditio~n~al defines';
  279. { Memory sizes }
  280. opt_stacksize = '~S~tack size';
  281. opt_heapsize = '~H~eap size';
  282. { Directory options }
  283. opt_unitdirectories = '~U~nit directories';
  284. opt_includedirectories = '~I~nclude directories';
  285. opt_librarydirectories = '~L~ibrary directories';
  286. opt_objectdirectories = '~O~bject directories';
  287. opt_exeppudirectories = '~E~XE output directory';
  288. opt_ppuoutputdirectory = '~P~PU output directory';
  289. opt_cross_tools_directory = '~C~ross tools directory';
  290. opt_dynamic_linker = '~D~ynamic linker path';
  291. { Library options }
  292. opt_librariesdefault = '~T~arget default';
  293. opt_dynamiclibraries = 'Link to ~D~ynamic libraries';
  294. opt_staticlibraries = 'Link to ~S~tatic libraries';
  295. opt_smartlibraries = 'Link to S~m~art libraries';
  296. opt_forcestaticlibs = 'Only link to st~a~tic libraries';
  297. { Symbol info options }
  298. opt_stripalldebugsymbols = '~S~trip all debug symbols from executable';
  299. opt_nogendebugsymbolinfo = 'Skip ~d~ebug information generation';
  300. opt_gendebugsymbolinfo = 'Generate ~d~ebug symbol information';
  301. opt_gensymbolandbacktraceinfo = 'Generate also backtrace ~l~ine information';
  302. opt_valgrindinfo = 'Generate ~v~algrind compatible debug info';
  303. { Link after options }
  304. opt_linkafter = 'Call ~l~inker after';
  305. { Profiling options }
  306. opt_noprofileinfo = '~N~o profile information';
  307. opt_gprofinfo = 'Generate profile code for g~p~rof';
  308. {*****************************************************************************
  309. TSwitchItem
  310. *****************************************************************************}
  311. constructor TSwitchItem.Init(const n,p:string; AID: TParamID);
  312. begin
  313. Inherited Init;
  314. Name:=n;
  315. Param:=p;
  316. ParamID:=AID;
  317. end;
  318. function TSwitchItem.NeedParam:boolean;
  319. begin
  320. NeedParam:=false;
  321. end;
  322. function TSwitchItem.ParamValue(nr:sw_integer):string;
  323. begin
  324. ParamValue:='';
  325. end;
  326. function TSwitchItem.ParamValueBool(SM: TSwitchMode):boolean;
  327. begin
  328. Abstract;
  329. ParamValueBool:=false;
  330. end;
  331. function TSwitchItem.ParamCount:sw_integer;
  332. begin
  333. ParamCount:=1;
  334. end;
  335. function TSwitchItem.GetSwitchStr(SM: TSwitchMode): string;
  336. begin
  337. Abstract;
  338. GetSwitchStr:='';
  339. end;
  340. function TSwitchItem.GetNumberStr(SM: TSwitchMode): string;
  341. begin
  342. Abstract;
  343. GetNumberStr:='';
  344. end;
  345. function TSwitchItem.GetOptionStr(SM: TSwitchMode): string;
  346. begin
  347. Abstract;
  348. GetOptionStr:='';
  349. end;
  350. procedure TSwitchItem.Reset;
  351. begin
  352. end;
  353. {*****************************************************************************
  354. TSelectItem
  355. *****************************************************************************}
  356. constructor TSelectItem.Init(const n,p:string; AID: TParamID);
  357. begin
  358. Inherited Init(n,p,AID);
  359. Typ:=ot_Select;
  360. IsDefault:=false;
  361. end;
  362. constructor TSelectItem.InitDefault(const n:string);
  363. begin
  364. Inherited Init(n,'',idNone);
  365. Typ:=ot_Select;
  366. IsDefault:=true;
  367. end;
  368. {*****************************************************************************
  369. TBooleanItem
  370. *****************************************************************************}
  371. constructor TBooleanItem.Init(const n,p:string; AID: TParamID);
  372. begin
  373. Inherited Init(n,p,AID);
  374. Typ:=ot_Boolean;
  375. Reset;
  376. end;
  377. function TBooleanItem.NeedParam:boolean;
  378. begin
  379. NeedParam:=IsSet[SwitchesMode];
  380. end;
  381. procedure TBooleanItem.Reset;
  382. begin
  383. FillChar(IsSet,sizeof(IsSet),0);
  384. end;
  385. function TBooleanItem.ParamValueBool(SM: TSwitchMode):boolean;
  386. begin
  387. ParamValueBool:=IsSet[SM];
  388. end;
  389. function TBooleanItem.GetSwitchStr(SM: TSwitchMode): string;
  390. begin
  391. GetSwitchStr:=BoolToStr(IsSet[SM],'+','-');
  392. end;
  393. {*****************************************************************************
  394. TStringItem
  395. *****************************************************************************}
  396. constructor TStringItem.Init(const n,p:string; AID: TParamID; mult,allowspaces:boolean);
  397. begin
  398. Inherited Init(n,p,AID);
  399. Typ:=ot_String;
  400. Multiple:=mult;
  401. SeparateSpaces:=not allowspaces;
  402. Reset;
  403. end;
  404. function TStringItem.NeedParam:boolean;
  405. begin
  406. NeedParam:=(Str[SwitchesMode]<>'');
  407. end;
  408. function TStringItem.ParamValue(nr:sw_integer):string;
  409. begin
  410. ParamValue:=Str[SwitchesMode];
  411. end;
  412. procedure TStringItem.Reset;
  413. begin
  414. FillChar(Str,sizeof(Str),0);
  415. end;
  416. {*****************************************************************************
  417. TMultiStringItem
  418. *****************************************************************************}
  419. constructor TMultiStringItem.Init(const n,p:string;AID:TParamID);
  420. var i:TSwitchMode;
  421. begin
  422. inherited Init(n,p,AID);
  423. typ:=ot_MultiString;
  424. for i:=low(MultiStr) to high(MultiStr) do
  425. new(MultiStr[i],init(5,5));
  426. { Reset;}
  427. end;
  428. function TMultiStringItem.NeedParam:boolean;
  429. begin
  430. NeedParam:=(multistr[SwitchesMode]^.count<>0);
  431. end;
  432. function TMultiStringItem.ParamValue(nr:sw_integer):string;
  433. begin
  434. ParamValue:=MultiStr[SwitchesMode]^.at(nr)^;
  435. end;
  436. function TMultiStringItem.ParamCount:sw_integer;
  437. begin
  438. ParamCount:=Multistr[SwitchesMode]^.count;
  439. end;
  440. procedure TMultiStringItem.Reset;
  441. var i:TSwitchMode;
  442. begin
  443. for i:=low(multiStr) to high(multiStr) do
  444. MultiStr[i]^.freeall;
  445. end;
  446. destructor TmultiStringItem.done;
  447. var i:TSwitchMode;
  448. begin
  449. for i:=low(MultiStr) to high(MultiStr) do
  450. dispose(MultiStr[i],done);
  451. inherited done;
  452. end;
  453. {*****************************************************************************
  454. TLongintItem
  455. *****************************************************************************}
  456. constructor TLongintItem.Init(const n,p:string; AID: TParamID);
  457. begin
  458. Inherited Init(n,p,AID);
  459. Typ:=ot_Longint;
  460. Reset;
  461. end;
  462. function TLongintItem.NeedParam:boolean;
  463. begin
  464. NeedParam:=(Val[SwitchesMode]<>0);
  465. end;
  466. function TLongintItem.ParamValue(nr:sw_integer):string;
  467. var
  468. s : string;
  469. begin
  470. Str(Val[SwitchesMode],s);
  471. ParamValue:=s;
  472. end;
  473. procedure TLongintItem.Reset;
  474. begin
  475. FillChar(Val,sizeof(Val),0);
  476. end;
  477. function TLongintItem.GetNumberStr(SM: TSwitchMode): string;
  478. begin
  479. GetNumberStr:=IntToStr(Val[SM]);
  480. end;
  481. {*****************************************************************************
  482. TSwitch
  483. *****************************************************************************}
  484. constructor TSwitches.Init(ch:AnsiChar);
  485. begin
  486. new(Items,Init(10,5));
  487. Prefix:=ch;
  488. FillChar(SelNr,SizeOf(SelNr),#0);
  489. IsSel:=false;
  490. end;
  491. constructor TSwitches.InitSelect(ch:AnsiChar);
  492. begin
  493. new(Items,Init(10,5));
  494. Prefix:=ch;
  495. FillChar(SelNr,SizeOf(SelNr),#0);
  496. IsSel:=true;
  497. end;
  498. destructor TSwitches.Done;
  499. begin
  500. dispose(Items,Done);
  501. end;
  502. procedure TSwitches.AddSelectItem(const name,param:string; AID: TParamID);
  503. begin
  504. Items^.Insert(New(PSelectItem,Init(name,Param,AID)));
  505. end;
  506. procedure TSwitches.AddDefaultSelect(const name:string);
  507. begin
  508. Items^.Insert(New(PSelectItem,InitDefault(name)));
  509. end;
  510. procedure TSwitches.AddBooleanItem(const name,param:string; AID: TParamID);
  511. begin
  512. Items^.Insert(New(PBooleanItem,Init(name,Param,AID)));
  513. end;
  514. procedure TSwitches.AddLongintItem(const name,param:string; AID: TParamID);
  515. begin
  516. Items^.Insert(New(PLongintItem,Init(name,Param,AID)));
  517. end;
  518. procedure TSwitches.AddStringItem(const name,param:string;AID:TParamID;mult,allowspaces:boolean);
  519. begin
  520. Items^.Insert(New(PStringItem,Init(name,Param,AID,mult,allowspaces)));
  521. end;
  522. procedure TSwitches.AddMultiStringItem(const name,param:string;AID:TParamID);
  523. begin
  524. Items^.Insert(New(PMultiStringItem,Init(name,Param,AID)));
  525. end;
  526. function TSwitches.ItemCount:integer;
  527. begin
  528. ItemCount:=Items^.Count;
  529. end;
  530. function TSwitches.ItemName(index:integer):string;
  531. var
  532. P : PSwitchItem;
  533. begin
  534. if index<ItemCount then
  535. P:=Items^.At(Index)
  536. else
  537. P:=nil;
  538. if assigned(P) then
  539. ItemName:=P^.Name
  540. else
  541. ItemName:='';
  542. end;
  543. function TSwitches.ItemParam(index:integer):string;
  544. var
  545. P : PSwitchItem;
  546. begin
  547. if index<ItemCount then
  548. P:=Items^.At(Index)
  549. else
  550. P:=nil;
  551. if assigned(P) then
  552. ItemParam:='-'+Prefix+P^.Param
  553. else
  554. ItemParam:='';
  555. end;
  556. function TSwitches.GetBooleanItem(index:integer):boolean;
  557. var
  558. P : PBooleanItem;
  559. begin
  560. if index<ItemCount then
  561. P:=Items^.At(Index)
  562. else
  563. P:=nil;
  564. if assigned(P) and (P^.Typ=ot_boolean) then
  565. GetBooleanItem:=P^.IsSet[SwitchesMode]
  566. else
  567. GetBooleanItem:=false;
  568. end;
  569. function TSwitches.GetLongintItem(index:integer):longint;
  570. var
  571. P : PLongintItem;
  572. begin
  573. if index<ItemCount then
  574. P:=Items^.At(Index)
  575. else
  576. P:=nil;
  577. if assigned(P) and (P^.Typ=ot_longint) then
  578. GetLongintItem:=P^.Val[SwitchesMode]
  579. else
  580. GetLongintItem:=0;
  581. end;
  582. function TSwitches.GetStringItem(index:integer):string;
  583. var
  584. P : PStringItem;
  585. begin
  586. if index<ItemCount then
  587. P:=Items^.At(Index)
  588. else
  589. P:=nil;
  590. if assigned(P) and (P^.Typ=ot_string) then
  591. GetStringItem:=P^.Str[SwitchesMode]
  592. else
  593. GetStringItem:='';
  594. end;
  595. function TSwitches.GetMultiStringItem(index:integer):PUnsortedStringCollection;
  596. var p:PMultiStringItem;
  597. begin
  598. if index<ItemCount then
  599. p:=Items^.at(Index)
  600. else
  601. p:=nil;
  602. if (p<>nil) and (p^.typ=ot_multistring) then
  603. GetMultiStringItem:=p^.MultiStr[SwitchesMode]
  604. else
  605. GetMultiStringItem:=nil;
  606. end;
  607. function TSwitches.GetItemTyp(index:integer):TSwitchItemTyp;
  608. var p:PSwitchItem;
  609. begin
  610. assert(index<itemcount);
  611. GetItemTyp:=PSwitchItem(items^.at(index))^.typ;
  612. end;
  613. procedure TSwitches.SetBooleanItem(index:integer;b:boolean);
  614. var
  615. P : PBooleanItem;
  616. begin
  617. if index<ItemCount then
  618. P:=Items^.At(Index)
  619. else
  620. P:=nil;
  621. if assigned(P) and (P^.Typ=ot_boolean) then
  622. P^.IsSet[SwitchesMode]:=b;
  623. end;
  624. procedure TSwitches.SetLongintItem(index:integer;l:longint);
  625. var
  626. P : PLongintItem;
  627. begin
  628. if index<ItemCount then
  629. P:=Items^.At(Index)
  630. else
  631. P:=nil;
  632. if assigned(P) and (P^.Typ=ot_longint) then
  633. P^.Val[SwitchesMode]:=l;
  634. end;
  635. procedure TSwitches.SetStringItem(index:integer;const s:string);
  636. var
  637. P : PStringItem;
  638. begin
  639. if index<ItemCount then
  640. P:=Items^.At(Index)
  641. else
  642. P:=nil;
  643. if assigned(P) and (P^.Typ=ot_string) then
  644. P^.Str[SwitchesMode]:=s;
  645. end;
  646. function TSwitches.GetCurrSel:integer;
  647. begin
  648. if IsSel then
  649. GetCurrSel:=SelNr[SwitchesMode]
  650. else
  651. GetCurrSel:=-1;
  652. end;
  653. function TSwitches.GetCurrSelParam : String;
  654. begin
  655. if IsSel then
  656. GetCurrSelParam:=PSwitchItem(Items^.At(SelNr[SwitchesMode]))^.Param
  657. else
  658. GetCurrSelParam:='';
  659. end;
  660. procedure TSwitches.SetCurrSel(index:integer);
  661. begin
  662. if index<ItemCount then
  663. SelNr[SwitchesMode]:=index;
  664. end;
  665. function TSwitches.SetCurrSelParam(const s : String) : boolean;
  666. function checkitem(P:PSwitchItem):boolean;
  667. begin
  668. { empty items are not equivalent to others !! }
  669. CheckItem:=((S='') and (P^.Param='')) or
  670. ((Length(S)>0) and (P^.Param=s));
  671. end;
  672. var
  673. FoundP : PSwitchItem;
  674. begin
  675. FoundP:=Items^.FirstThat(TCallbackFunBoolParam(@CheckItem));
  676. if Assigned(FoundP) then
  677. begin
  678. SetCurrSelParam:=true;
  679. SelNr[SwitchesMode]:=Items^.IndexOf(FoundP);
  680. end
  681. else
  682. SetCurrSelParam:=false;
  683. end;
  684. procedure TSwitches.WriteItemsCfg;
  685. var
  686. Pref : AnsiChar;
  687. procedure writeitem(P:PSwitchItem);
  688. var
  689. s,s1 : string;
  690. i,j : integer;
  691. begin
  692. if P^.NeedParam then
  693. begin
  694. if (P^.Typ=ot_string) and (PStringItem(P)^.Multiple) then
  695. begin
  696. s:=PStringItem(P)^.Str[SwitchesMode];
  697. repeat
  698. i:=pos(';',s);
  699. if PStringItem(P)^.SeparateSpaces then
  700. j:=pos(' ',s)
  701. else
  702. j:=0;
  703. if i=0 then
  704. i:=256;
  705. if (j>0) and (j<i) then
  706. i:=j;
  707. s1:=Copy(s,1,i-1);
  708. if s1<>'' then
  709. writeln(CfgFile,' -'+Pref+P^.Param+s1);
  710. Delete(s,1,i);
  711. until s='';
  712. end
  713. else
  714. if P^.Param<>'/' then
  715. for i:=0 to p^.ParamCount-1 do
  716. Writeln(CfgFile,' -'+Pref+P^.Param+P^.ParamValue(i));
  717. end;
  718. end;
  719. var
  720. P : PSelectItem;
  721. begin
  722. Pref:=Prefix;
  723. if IsSel then
  724. begin
  725. { can be empty for some targets }
  726. If Items^.count>0 then
  727. begin
  728. P:=Items^.At(SelNr[SwitchesMode]);
  729. if not P^.IsDefault then
  730. writeln(CfgFile,' '+ItemParam(SelNr[SwitchesMode]));
  731. end;
  732. end
  733. else
  734. Items^.ForEach(TCallbackProcParam(@writeitem));
  735. end;
  736. procedure WriteCustom;
  737. var
  738. s : string;
  739. i : longint;
  740. begin
  741. s:=CustomArg[SwitchesMode];
  742. While s<>'' do
  743. begin
  744. i:=pos(' ',s);
  745. if i=0 then i:=256;
  746. writeln(CfgFile,' '+Copy(s,1,i-1));
  747. if i=256 then
  748. s:=''
  749. else
  750. s:=copy(s,i+1,255);
  751. end;
  752. end;
  753. function TSwitches.ReadItemsCfg(const s:string):boolean;
  754. function checkitem(P:PSwitchItem):boolean;
  755. begin
  756. { empty items are not equivalent to others !! }
  757. { but -dGDB didn't work because of this PM }
  758. CheckItem:=((P^.Param='') and ((S='') or (P^.typ in [ot_Boolean,ot_String]))) or
  759. ((Length(P^.Param)>0) and (upcase(P^.Param)=upcase(S)) and
  760. not (P^.typ in [ot_Boolean,ot_String])) or
  761. ((Length(P^.Param)>0) and (P^.typ<>ot_Select) and
  762. (P^.Param=Copy(s,1,length(P^.Param))));
  763. end;
  764. var
  765. FoundP : PSwitchItem;
  766. code : integer;
  767. begin
  768. FoundP:=Items^.FirstThat(TCallbackFunBoolParam(@checkitem));
  769. if assigned(FoundP) then
  770. begin
  771. case FoundP^.Typ of
  772. ot_Select : SelNr[SwitchesMode]:=Items^.IndexOf(FoundP);
  773. ot_Boolean : PBooleanItem(FoundP)^.IsSet[SwitchesMode]:=true;
  774. ot_String : begin
  775. if (PStringItem(FoundP)^.Multiple) and (PStringItem(FoundP)^.Str[SwitchesMode]<>'') then
  776. PStringItem(FoundP)^.Str[SwitchesMode]:=PStringItem(FoundP)^.Str[SwitchesMode]+';'+
  777. Copy(s,length(FoundP^.Param)+1,255)
  778. else
  779. PStringItem(FoundP)^.Str[SwitchesMode]:=Copy(s,length(FoundP^.Param)+1,255);
  780. end;
  781. ot_MultiString :
  782. PMultiStringItem(foundP)^.MultiStr[SwitchesMode]^.insert(newstr(copy(s,length(foundP^.param)+1,255)));
  783. ot_Longint : Val(Copy(s,length(FoundP^.Param)+1,255),PLongintItem(FoundP)^.Val[SwitchesMode],code);
  784. end;
  785. ReadItemsCfg:=true;
  786. end
  787. else
  788. ReadItemsCfg:=false;
  789. end;
  790. {*****************************************************************************
  791. Read / Write
  792. *****************************************************************************}
  793. procedure WriteSwitches(const fn:string);
  794. var
  795. OldSwitchesMode, SWM: TSwitchMode;
  796. begin
  797. { create the switches }
  798. assign(CfgFile,fn);
  799. {$I-}
  800. rewrite(CfgFile);
  801. {$I+}
  802. if ioresult<>0 then
  803. exit;
  804. writeln(CfgFile,'# '+msg_automaticallycreateddontedit);
  805. OldSwitchesMode:=SwitchesMode;
  806. for SWM:=low(TSwitchMode) to high(TSwitchMode) do
  807. begin
  808. SwitchesMode := SWM;
  809. Writeln(CfgFile,'#IFDEF '+SwitchesModeStr[SwitchesMode]);
  810. TargetSwitches^.WriteItemsCfg;
  811. CompilerModeSwitches^.WriteItemsCfg;
  812. VerboseSwitches^.WriteItemsCfg;
  813. SyntaxSwitches^.WriteItemsCfg;
  814. CodegenSwitches^.WriteItemsCfg;
  815. OptimizationSwitches^.WriteItemsCfg;
  816. ProcessorCodeGenerationSwitches^.WriteItemsCfg;
  817. ProcessorOptimizationSwitches^.WriteItemsCfg;
  818. AsmReaderSwitches^.WriteItemsCfg;
  819. AsmInfoSwitches^.WriteItemsCfg;
  820. if assigned(AsmOutputSwitches[SwitchesMode]) then
  821. AsmOutputSwitches[SwitchesMode]^.WriteItemsCfg;
  822. DirectorySwitches^.WriteItemsCfg;
  823. MemorySwitches^.WriteItemsCfg;
  824. ConditionalSwitches^.WriteItemsCfg;
  825. LibLinkerSwitches^.WriteItemsCfg;
  826. OtherLinkerSwitches^.WriteItemsCfg;
  827. DebugInfoSwitches^.WriteItemsCfg;
  828. ProfileInfoSwitches^.WriteItemsCfg;
  829. LinkAfterSwitches^.WriteItemsCfg;
  830. BrowserSwitches^.WriteItemsCfg;
  831. {MemorySizeSwitches^.WriteItemsCfg;}
  832. WriteCustom;
  833. Writeln(CfgFile,'#ENDIF');
  834. Writeln(CfgFile,'');
  835. end;
  836. close(CfgFile);
  837. SwitchesMode:=OldSwitchesMode;
  838. end;
  839. procedure ReadSwitches(const fn:string);
  840. var
  841. c : AnsiChar;
  842. s : string;
  843. res : boolean;
  844. OldSwitchesMode,i : TSwitchMode;
  845. begin
  846. assign(CfgFile,fn);
  847. {$I-}
  848. reset(CfgFile);
  849. {$I+}
  850. if ioresult<>0 then
  851. begin
  852. SetDefaultSwitches;
  853. exit;
  854. end;
  855. OldSwitchesMode:=SwitchesMode;
  856. SwitchesMode:=om_Normal;
  857. while not eof(CfgFile) do
  858. begin
  859. readln(CfgFile,s);
  860. s:=LTrim(s);
  861. if (length(s)>=2) and (s[1]='-') then
  862. begin
  863. c:=s[2];
  864. res:=false;
  865. Delete(s,1,2);
  866. case c of
  867. 'a' : res:=AsmInfoSwitches^.ReadItemsCfg(s);
  868. 'A' : begin
  869. UpdateAsmOutputSwitches;
  870. res:=AsmOutputSwitches[SwitchesMode]^.ReadItemsCfg(s);
  871. end;
  872. 'b' : res:=BrowserSwitches^.ReadItemsCfg(s);
  873. 'C' : begin
  874. res:=CodegenSwitches^.ReadItemsCfg(s);
  875. if not res then
  876. res:=MemorySwitches^.ReadItemsCfg(s);
  877. if not res then
  878. res:=ProcessorCodeGenerationSwitches^.ReadItemsCfg(s);
  879. end;
  880. 'd' : res:=ConditionalSwitches^.ReadItemsCfg(s);
  881. 'F' : res:=DirectorySwitches^.ReadItemsCfg(s);
  882. 'g' : res:=DebugInfoSwitches^.ReadItemsCfg(s);
  883. 'O' : begin
  884. res:=OptimizationSwitches^.ReadItemsCfg(s);
  885. if not res then
  886. res:=ProcessorOptimizationSwitches^.ReadItemsCfg(s);
  887. end;
  888. 'M' : res:=CompilerModeSwitches^.ReadItemsCfg(s);
  889. 'p' : res:=ProfileInfoSwitches^.ReadItemsCfg(s);
  890. 's' : res:=LinkAfterSwitches^.ReadItemsCfg(s);
  891. 'R' : res:=AsmReaderSwitches^.ReadItemsCfg(s);
  892. 'S' : res:=SyntaxSwitches^.ReadItemsCfg(s);
  893. 'T' : res:=TargetSwitches^.ReadItemsCfg(s);
  894. 'v' : res:=VerboseSwitches^.ReadItemsCfg(s);
  895. 'X' : begin
  896. res:=LibLinkerSwitches^.ReadItemsCfg(s);
  897. if not res then
  898. res:=OtherLinkerSwitches^.ReadItemsCfg(s);
  899. end;
  900. end;
  901. { keep all others as a string }
  902. if not res then
  903. CustomArg[SwitchesMode]:=CustomArg[SwitchesMode]+' -'+c+s;
  904. end
  905. else
  906. if (Copy(s,1,7)='#IFDEF ') then
  907. begin
  908. Delete(s,1,7);
  909. for i:=low(TSwitchMode) to high(TSwitchMode) do
  910. if s=SwitchesModeStr[i] then
  911. begin
  912. SwitchesMode:=i;
  913. break;
  914. end;
  915. end
  916. else;
  917. end;
  918. close(CfgFile);
  919. SwitchesMode:=OldSwitchesMode;
  920. end;
  921. function GetSourceDirectories : string;
  922. var
  923. P : PStringItem;
  924. S : String;
  925. c : AnsiChar;
  926. function checkitem(P:PSwitchItem):boolean;
  927. begin
  928. CheckItem:=(P^.Typ=ot_string) and (P^.Param=c);
  929. end;
  930. begin
  931. GetSourceDirectories:='';
  932. c:='u';
  933. P:=DirectorySwitches^.Items^.FirstThat(TCallbackFunBoolParam(@CheckItem));
  934. S:='';
  935. if assigned(P) then
  936. S:=P^.Str[SwitchesMode];
  937. c:='i';
  938. P:=DirectorySwitches^.Items^.FirstThat(TCallbackFunBoolParam(@CheckItem));
  939. if assigned(P) then
  940. S:=P^.Str[SwitchesMode]+';'+S;
  941. if S='' then
  942. GetSourceDirectories:=SourceDirs+';'
  943. else
  944. GetSourceDirectories:=SourceDirs+';'+S+';';
  945. end;
  946. {*****************************************************************************
  947. AsmOutputInitialize
  948. *****************************************************************************}
  949. procedure UpdateAsmOutputSwitches;
  950. var
  951. ta : tasm;
  952. zt : tsystem;
  953. sy : tsystem;
  954. sw : TSwitchMode;
  955. st : string;
  956. L : String;
  957. t : string;
  958. begin
  959. sw:=SwitchesMode;
  960. t:='';
  961. if assigned(TargetSwitches) then
  962. t:=TargetSwitches^.ItemName(TargetSwitches^.GetCurrSel);
  963. sy:=target_info.system;
  964. for zt:=low(tsystem) to high(tsystem) do
  965. if assigned(targetinfos[zt]) then
  966. begin
  967. if targetinfos[zt]^.name = t then
  968. begin
  969. sy:=zt;
  970. break;
  971. end;
  972. end;
  973. L:='';
  974. if assigned(AsmOutputSwitches[sw]) then
  975. begin
  976. L:=AsmOutputSwitches[sw]^.GetCurrSelParam;
  977. dispose(AsmOutputSwitches[sw],Done);
  978. end;
  979. New(AsmOutputSwitches[sw],InitSelect('A'));
  980. with AsmOutputSwitches[sw]^ do
  981. begin
  982. AddDefaultSelect(opt_usedefaultas);
  983. for ta:=low(tasm) to high(tasm) do
  984. if assigned(asminfos[ta]) and
  985. ((sy in asminfos[ta]^.supported_targets) or
  986. (system_any in asminfos[ta]^.supported_targets)) then
  987. begin
  988. st:='Asm '+asminfos[ta]^.idtxt;
  989. if asminfos[ta]^.idtxt='AS' then
  990. st:=opt_usegnuas;
  991. {$if defined(I386) or defined(x86_64)}
  992. if asminfos[ta]^.idtxt='NASMCOFF' then
  993. st:=opt_usenasmcoff;
  994. if asminfos[ta]^.idtxt='NASMOBJ' then
  995. st:=opt_usenasmobj;
  996. if asminfos[ta]^.idtxt='NASMWIN32' then
  997. st:=opt_usenasmwin32;
  998. if asminfos[ta]^.idtxt='NASMWDOSX' then
  999. st:=opt_usenasmwdosx;
  1000. if asminfos[ta]^.idtxt='NASMELF' then
  1001. st:=opt_usenasmelf;
  1002. if asminfos[ta]^.idtxt='NASMBEOS' then
  1003. st:=opt_usenasmbeos;
  1004. if asminfos[ta]^.idtxt='MASM' then
  1005. st:=opt_usemasm;
  1006. if asminfos[ta]^.idtxt='TASM' then
  1007. st:=opt_usetasm;
  1008. if asminfos[ta]^.idtxt='WASM' then
  1009. st:=opt_usewasm;
  1010. if asminfos[ta]^.idtxt='COFF' then
  1011. st:=opt_usecoff;
  1012. if asminfos[ta]^.idtxt='PECOFF' then
  1013. st:=opt_usepecoff;
  1014. if asminfos[ta]^.idtxt='PEWDOSX' then
  1015. st:=opt_usepecoffwdosx;
  1016. if asminfos[ta]^.idtxt='ELF' then
  1017. st:=opt_useelf;
  1018. {$endif I386}
  1019. AddSelectItem(st,asminfos[ta]^.idtxt,idNone);
  1020. end;
  1021. end;
  1022. AsmOutputSwitches[sw]^.SetCurrSelParam(L);
  1023. end;
  1024. {*****************************************************************************
  1025. Initialize
  1026. *****************************************************************************}
  1027. procedure InitSwitches;
  1028. var
  1029. t : tsystem;
  1030. cpu : tcputype;
  1031. st : string;
  1032. begin
  1033. New(SyntaxSwitches,Init('S'));
  1034. with SyntaxSwitches^ do
  1035. begin
  1036. // AddBooleanItem(opt_objectpascal,'2',idNone);
  1037. AddBooleanItem(opt_stopafterfirsterror,'e',idNone);
  1038. AddBooleanItem(opt_allowlabelandgoto,'g',idNone);
  1039. AddBooleanItem(opt_globalcmacros,'m',idNone);
  1040. AddBooleanItem(opt_cplusplusstyledinline,'i',idNone);
  1041. // AddBooleanItem(opt_tp7compatibility,'o',idNone);
  1042. // AddBooleanItem(opt_delphicompatibility,'d',idNone);
  1043. AddBooleanItem(opt_assertions,'a',idNone);
  1044. AddBooleanItem(opt_ansistring,'h',idAnsiString);
  1045. AddBooleanItem(opt_kylix,'k',idNone);
  1046. AddBooleanItem(opt_allowstaticinobjects,'s',idNone);
  1047. AddBooleanItem(opt_clikeoperators,'c',idNone);
  1048. { Useless as they are not passed to the compiler PM
  1049. AddBooleanItem(opt_strictvarstrings,'/',idStrictVarStrings);
  1050. AddBooleanItem(opt_extendedsyntax,'/',idExtendedSyntax);
  1051. AddBooleanItem(opt_allowmmxoperations,'/',idMMXOps); }
  1052. end;
  1053. New(CompilerModeSwitches,InitSelect('M'));
  1054. with CompilerModeSwitches^ do
  1055. begin
  1056. AddSelectItem(opt_mode_freepascal,'fpc',idNone);
  1057. AddSelectItem(opt_mode_objectpascal,'objfpc',idNone);
  1058. AddSelectItem(opt_mode_turbopascal,'tp',idNone);
  1059. AddSelectItem(opt_mode_delphi,'delphi',idNone);
  1060. AddSelectItem(opt_mode_macpascal,'macpas',idNone);
  1061. { GNU Pascal mode doesn't do much, better disable it
  1062. AddSelectItem(opt_mode_gnupascal,'gpc',idNone);}
  1063. end;
  1064. New(VerboseSwitches,Init('v'));
  1065. with VerboseSwitches^ do
  1066. begin
  1067. AddBooleanItem(opt_warnings,'w',idNone);
  1068. AddBooleanItem(opt_notes,'n',idNone);
  1069. AddBooleanItem(opt_hints,'h',idNone);
  1070. AddBooleanItem(opt_generalinfo,'i',idNone);
  1071. AddBooleanItem(opt_usedtriedinfo,'ut',idNone);
  1072. AddBooleanItem(opt_all,'a',idNone);
  1073. AddBooleanItem(opt_showallprocsonerror,'b',idNone);
  1074. end;
  1075. New(CodegenSwitches,Init('C'));
  1076. with CodegenSwitches^ do
  1077. begin
  1078. AddBooleanItem(opt_rangechecking,'r',idRangeChecks);
  1079. AddBooleanItem(opt_stackchecking,'t',idStackChecks);
  1080. AddBooleanItem(opt_iochecking,'i',idIOChecks);
  1081. AddBooleanItem(opt_overflowchecking,'o',idOverflowChecks);
  1082. AddBooleanItem(opt_objmethcallvalid,'R',idObjMethCallChecks);
  1083. AddBooleanItem(opt_pic,'g',idNone);
  1084. AddBooleanItem(opt_smart,'X',idNone);
  1085. end;
  1086. New(OptimizationSwitches,Init('O'));
  1087. with OptimizationSwitches^ do
  1088. begin
  1089. AddBooleanItem(opt_generatesmallercode,'s',idNone);
  1090. {$ifdef I386}
  1091. AddBooleanItem(opt_useregistervariables,'oregvar',idNone);
  1092. AddBooleanItem(opt_uncertainoptimizations,'ouncertain',idNone);
  1093. AddBooleanItem(opt_level1optimizations,'1',idNone);
  1094. AddBooleanItem(opt_level2optimizations,'2',idNone);
  1095. AddBooleanItem(opt_level3optimizations,'3',idNone);
  1096. {$else not I386}
  1097. {$ifdef m68k}
  1098. AddBooleanItem(opt_level1optimizations,'a',idNone);
  1099. AddBooleanItem(opt_useregistervariables,'x',idNone);
  1100. {$endif m68k}
  1101. {$endif I386}
  1102. end;
  1103. New(ProcessorOptimizationSwitches,InitSelect('O'));
  1104. with ProcessorOptimizationSwitches^ do
  1105. begin
  1106. for cpu:=low(tcputype) to high(tcputype) do
  1107. begin
  1108. st:=cputypestr[cpu];
  1109. {$ifdef I386}
  1110. if st='386' then
  1111. st:=opt_i386486;
  1112. if st='PENTIUM' then
  1113. st:=opt_pentium;
  1114. if st='PENTIUM2' then
  1115. st:=opt_pentiummmx;
  1116. if st='PENTIUM3' then
  1117. st:=opt_pentiumpro;
  1118. if st='PENTIUM4' then
  1119. st:=opt_pentiumiv;
  1120. if st='PENTIUMM' then
  1121. st:=opt_pentiumM;
  1122. {$endif not I386}
  1123. {$ifdef m68k}
  1124. if st='68000' then
  1125. st:=opt_m68000;
  1126. if st='68020' then
  1127. st:=opt_m68020;
  1128. {$endif m68k}
  1129. if st<>'' then
  1130. AddSelectItem(st,'p'+cputypestr[cpu],idNone);
  1131. end;
  1132. end;
  1133. New(ProcessorCodeGenerationSwitches,InitSelect('C'));
  1134. with ProcessorCodeGenerationSwitches^ do
  1135. begin
  1136. for cpu:=low(tcputype) to high(tcputype) do
  1137. begin
  1138. st:=cputypestr[cpu];
  1139. {$ifdef I386}
  1140. if st='386' then
  1141. st:=opt_i386486;
  1142. if st='PENTIUM' then
  1143. st:=opt_pentium;
  1144. if st='PENTIUM2' then
  1145. st:=opt_pentiummmx;
  1146. if st='PENTIUM3' then
  1147. st:=opt_pentiumpro;
  1148. if st='PENTIUM4' then
  1149. st:=opt_pentiumiv;
  1150. if st='PENTIUMM' then
  1151. st:=opt_pentiumM;
  1152. {$endif not I386}
  1153. {$ifdef m68k}
  1154. if st='68000' then
  1155. st:=opt_m68000;
  1156. if st='68020' then
  1157. st:=opt_m68020;
  1158. {$endif m68k}
  1159. { we use the string twice so kill duplicate highlights }
  1160. while pos('~',st)<>0 do
  1161. delete(st,pos('~',st),1);
  1162. if st<>'' then
  1163. AddSelectItem(st,'p'+cputypestr[cpu],idNone);
  1164. end;
  1165. end;
  1166. New(TargetSwitches,InitSelect('T'));
  1167. with TargetSwitches^ do
  1168. begin
  1169. { better, we've a correct target list without "tilded" names instead a wrong one }
  1170. for t:=low(tsystem) to high(tsystem) do
  1171. if assigned(targetinfos[t]) then
  1172. AddSelectItem(targetinfos[t]^.name,targetinfos[t]^.shortname,idNone);
  1173. end;
  1174. New(AsmReaderSwitches,InitSelect('R'));
  1175. with AsmReaderSwitches^ do
  1176. begin
  1177. AddSelectItem(opt_defaultassembler,'default',idNone);
  1178. {$if defined(I386) or defined(x86_64)}
  1179. AddSelectItem(opt_attassembler,'att',idAsmATT);
  1180. AddSelectItem(opt_intelassembler,'intel',idAsmIntel);
  1181. {$endif I386}
  1182. {$ifdef M68K}
  1183. //AddSelectItem(opt_standardassembler,'standard',idAsmStandard);
  1184. AddSelectItem(opt_motassembler,'motorola',idAsmMot);
  1185. {$endif M68K}
  1186. end;
  1187. New(AsmInfoSwitches,Init('a'));
  1188. with AsmInfoSwitches^ do
  1189. begin
  1190. AddBooleanItem(opt_listsource,'l',idNone);
  1191. AddBooleanItem(opt_listregisterallocation,'r',idNone);
  1192. AddBooleanItem(opt_listtempallocation,'t',idNone);
  1193. AddBooleanItem(opt_listnodeallocation,'n',idNone);
  1194. AddBooleanItem(opt_useasmpipe,'p',idNone);
  1195. end;
  1196. UpdateAsmOutputSwitches;
  1197. New(BrowserSwitches,InitSelect('b'));
  1198. with BrowserSwitches^ do
  1199. begin
  1200. AddSelectItem(opt_nobrowser,'-',idSymInfNone);
  1201. AddSelectItem(opt_globalonlybrowser,'+',idSymInfGlobalOnly);
  1202. AddSelectItem(opt_localglobalbrowser,'l',idSymInfGlobalLocal);
  1203. end;
  1204. New(ConditionalSwitches,Init('d'));
  1205. with ConditionalSwitches^ do
  1206. begin
  1207. AddStringItem(opt_conditionaldefines,'',idNone,true,false);
  1208. end;
  1209. New(MemorySwitches,Init('C'));
  1210. with MemorySwitches^ do
  1211. begin
  1212. AddLongintItem(opt_stacksize,'s',idStackSize);
  1213. AddLongintItem(opt_heapsize,'h',idHeapSize);
  1214. end;
  1215. New(DirectorySwitches,Init('F'));
  1216. with DirectorySwitches^ do
  1217. begin
  1218. AddMultiStringItem(opt_unitdirectories,'u',idNone);
  1219. AddMultiStringItem(opt_includedirectories,'i',idNone);
  1220. AddMultiStringItem(opt_librarydirectories,'l',idNone);
  1221. AddMultiStringItem(opt_objectdirectories,'o',idNone);
  1222. AddStringItem(opt_exeppudirectories,'E',idNone,true,true);
  1223. AddStringItem(opt_ppuoutputdirectory,'U',idNone,true,true);
  1224. AddStringItem(opt_cross_tools_directory,'D',idNone,true,true);
  1225. AddStringItem(opt_dynamic_linker,'L',idNone,false,false);
  1226. end;
  1227. New(LibLinkerSwitches,InitSelect('X'));
  1228. with LibLinkerSwitches^ do
  1229. begin
  1230. AddDefaultSelect(opt_librariesdefault);
  1231. AddSelectItem(opt_dynamiclibraries,'D',idNone);
  1232. AddSelectItem(opt_staticlibraries,'S',idNone);
  1233. AddSelectItem(opt_smartlibraries,'X',idNone);
  1234. end;
  1235. New(OtherLinkerSwitches,Init('X'));
  1236. with OtherLinkerSwitches^ do
  1237. begin
  1238. AddBooleanItem(opt_stripalldebugsymbols,'s',idNone);
  1239. AddBooleanItem(opt_forcestaticlibs,'t',idNone);
  1240. end;
  1241. New(DebugInfoSwitches,InitSelect('g'));
  1242. with DebugInfoSwitches^ do
  1243. begin
  1244. AddSelectItem(opt_nogendebugsymbolinfo,'-',idNone);
  1245. AddSelectItem(opt_gendebugsymbolinfo,'',idNone);
  1246. AddSelectItem(opt_gensymbolandbacktraceinfo,'l',idNone);
  1247. AddSelectItem(opt_valgrindinfo,'v',idNone);
  1248. { AddSelectItem('Generate ~d~bx symbol information','d');
  1249. does not work anyhow (PM) }
  1250. end;
  1251. New(LinkAfterSwitches,Init('s'));
  1252. LinkAfterSwitches^.AddBooleanItem(opt_linkafter,'',idNone);
  1253. New(ProfileInfoSwitches,InitSelect('p'));
  1254. with ProfileInfoSwitches^ do
  1255. begin
  1256. AddSelectItem(opt_noprofileinfo,'-',idNone);
  1257. AddSelectItem(opt_gprofinfo,'g',idNone);
  1258. end;
  1259. {New(MemorySizeSwitches,Init('C'));
  1260. with MemorySizeSwitches^ do
  1261. begin
  1262. AddLongIntItem('~S~tack size','s');
  1263. AddLongIntItem('Local ~h~eap size','h');
  1264. end;}
  1265. SwitchesPath:=LocateFile(SwitchesName);
  1266. if SwitchesPath='' then
  1267. SwitchesPath:=SwitchesName;
  1268. SwitchesPath:=FExpand(SwitchesPath);
  1269. end;
  1270. procedure SetDefaultSwitches;
  1271. var
  1272. i,OldSwitchesMode : TSwitchMode;
  1273. begin
  1274. { setup some useful defaults }
  1275. OldSwitchesMode:=SwitchesMode;
  1276. for i:=low(TSwitchMode) to high(TSwitchMode) do
  1277. begin
  1278. SwitchesMode:=i;
  1279. { default is Pentium }
  1280. ProcessorOptimizationSwitches^.SetCurrSel(1);
  1281. { AT&T reader }
  1282. AsmReaderSwitches^.SetCurrSel(1);
  1283. { FPC mode}
  1284. CompilerModeSwitches^.SetCurrSel(0);
  1285. (* Use platform defaults for memory switches. *)
  1286. { 128k stack }
  1287. { MemorySwitches^.SetLongintItem(0,65536*2);}
  1288. MemorySwitches^.SetLongintItem(0,0);
  1289. { 2 MB heap }
  1290. { MemorySwitches^.SetLongintItem(1,1024*1024*2);}
  1291. MemorySwitches^.SetLongintItem(1,0);
  1292. { goto/lable allowed }
  1293. SyntaxSwitches^.SetBooleanItem(1,true);
  1294. { inline allowed }
  1295. SyntaxSwitches^.SetBooleanItem(3,true);
  1296. { Exe size complaints are louder than speed complaints: Optimize for size by default. }
  1297. OptimizationSwitches^.SetBooleanItem(0,true);
  1298. case i of
  1299. om_debug:
  1300. begin
  1301. { debugging info on }
  1302. DebugInfoSwitches^.SetCurrSel(1);
  1303. { range checking }
  1304. CodegenSwitches^.SetBooleanItem(0,true);
  1305. { io checking }
  1306. CodegenSwitches^.SetBooleanItem(2,true);
  1307. { overflow checking }
  1308. CodegenSwitches^.SetBooleanItem(3,true);
  1309. { method call checking }
  1310. CodegenSwitches^.SetBooleanItem(4,true);
  1311. { assertions on }
  1312. SyntaxSwitches^.SetBooleanItem(4,true);
  1313. end;
  1314. om_normal:
  1315. begin
  1316. {Register variables.}
  1317. OptimizationSwitches^.SetBooleanItem(1,true);
  1318. {Level 1 optimizations.}
  1319. OptimizationSwitches^.SetBooleanItem(3,true);
  1320. end;
  1321. om_release:
  1322. begin
  1323. {Register variables.}
  1324. OptimizationSwitches^.SetBooleanItem(1,true);
  1325. {Level 2 optimizations.}
  1326. OptimizationSwitches^.SetBooleanItem(4,true);
  1327. {Smart linking.}
  1328. LibLinkerSwitches^.SetCurrSel(3);
  1329. CodegenSwitches^.SetBooleanItem(6,true);
  1330. {Strip debug info}
  1331. OtherLinkerSwitches^.SetBooleanItem(0,true);
  1332. end;
  1333. end;
  1334. { set appriopriate default target }
  1335. TargetSwitches^.SetCurrSelParam(target_info.shortname);
  1336. end;
  1337. SwitchesMode:=OldSwitchesMode;
  1338. end;
  1339. procedure DoneSwitches;
  1340. var sw : TSwitchMode;
  1341. begin
  1342. dispose(SyntaxSwitches,Done);
  1343. dispose(CompilerModeSwitches,Done);
  1344. dispose(VerboseSwitches,Done);
  1345. dispose(CodegenSwitches,Done);
  1346. dispose(OptimizationSwitches,Done);
  1347. dispose(ProcessorOptimizationSwitches,Done);
  1348. dispose(ProcessorCodeGenerationSwitches,Done);
  1349. dispose(BrowserSwitches,Done);
  1350. dispose(TargetSwitches,Done);
  1351. dispose(AsmReaderSwitches,Done);
  1352. dispose(AsmInfoSwitches,Done);
  1353. dispose(ConditionalSwitches,Done);
  1354. dispose(MemorySwitches,Done);
  1355. {dispose(MemorySizeSwitches,Done);}
  1356. dispose(DirectorySwitches,Done);
  1357. dispose(DebugInfoSwitches,Done);
  1358. dispose(LibLinkerSwitches,Done);
  1359. dispose(LinkAfterSwitches,Done);
  1360. dispose(OtherLinkerSwitches,Done);
  1361. dispose(ProfileInfoSwitches,Done);
  1362. for sw:=low(TSwitchMode) to high(TSwitchMode) do
  1363. if assigned(AsmOutputSwitches[sw]) then
  1364. dispose(AsmOutputSwitches[sw],Done);
  1365. end;
  1366. procedure GetCompilerOptionLines(C: PUnsortedStringCollection);
  1367. procedure AddLine(const S: string);
  1368. begin
  1369. C^.Insert(NewStr(S));
  1370. end;
  1371. procedure ConstructSwitchModeDirectives(SM: TSwitchMode; const IfDefSym: string);
  1372. var SwitchParams: PStringCollection;
  1373. MiscParams : PStringCollection;
  1374. procedure AddSwitch(const S: string);
  1375. begin
  1376. SwitchParams^.Insert(NewStr(S));
  1377. end;
  1378. procedure AddParam(const S: string);
  1379. begin
  1380. MiscParams^.Insert(NewStr(S));
  1381. end;
  1382. procedure EnumSwitches(P: PSwitches);
  1383. procedure HandleSwitch(P: PSwitchItem);
  1384. begin
  1385. case P^.ParamID of
  1386. { idAlign :}
  1387. idRangeChecks : AddSwitch('R'+P^.GetSwitchStr(SM));
  1388. idStackChecks : AddSwitch('S'+P^.GetSwitchStr(SM));
  1389. idIOChecks : AddSwitch('I'+P^.GetSwitchStr(SM));
  1390. idOverflowChecks : AddSwitch('Q'+P^.GetSwitchStr(SM));
  1391. idObjMethCallChecks: AddSwitch('OBJECTCHECKS'+P^.GetSwitchStr(SM));
  1392. { idAsmDirect : if P^.GetParamValueBool[SM] then AddParam('ASMMODE DIRECT');
  1393. idAsmATT : if P^.GetParamValueBool[SM] then AddParam('ASMMODE ATT');
  1394. idAsmIntel : if P^.GetParamValueBool[SM] then AddParam('ASMMODE INTEL');
  1395. idAsmMot : if P^.GetParamValueBool[SM] then AddParam('ASMMODE MOTOROLA');
  1396. idAsmStandard : if P^.GetParamValueBool[SM] then AddParam('ASMMODE STANDARD');}
  1397. { idSymInfNone : ;
  1398. idSymInfGlobalOnly:;
  1399. idSymInfGlobalLocal:if P^.ParamValueBool(SM) then AddSwitch('L+');}
  1400. { idStackSize
  1401. idHeapSize}
  1402. idStrictVarStrings: AddSwitch('V'+P^.GetSwitchStr(SM));
  1403. idExtendedSyntax : AddSwitch('X'+P^.GetSwitchStr(SM));
  1404. idMMXOps : if P^.ParamValueBool(SM) then AddParam('MMX');
  1405. idTypedAddress : AddSwitch('T'+P^.GetSwitchStr(SM));
  1406. { idPackRecords
  1407. idPackEnum}
  1408. idStackFrames : AddSwitch('W'+P^.GetSwitchStr(SM));
  1409. idReferenceInfo : AddSwitch('Y'+P^.GetSwitchStr(SM));
  1410. idDebugInfo : AddSwitch('D'+P^.GetSwitchStr(SM));
  1411. idBoolEval : AddSwitch('B'+P^.GetSwitchStr(SM));
  1412. idAnsiString : AddSwitch('H'+P^.GetSwitchStr(SM));
  1413. idTypeInfo : AddSwitch('M'+P^.GetSwitchStr(SM));
  1414. end;
  1415. end;
  1416. begin
  1417. P^.Items^.ForEach(TCallbackProcParam(@HandleSwitch));
  1418. end;
  1419. var I: integer;
  1420. S: string;
  1421. begin
  1422. AddLine('{$IFDEF '+IfDefSym+'}');
  1423. New(SwitchParams, Init(10,10));
  1424. New(MiscParams, Init(10,10));
  1425. EnumSwitches(LibLinkerSwitches);
  1426. EnumSwitches(OtherLinkerSwitches);
  1427. EnumSwitches(DebugInfoSwitches);
  1428. EnumSwitches(ProfileInfoSwitches);
  1429. EnumSwitches(SyntaxSwitches);
  1430. EnumSwitches(CompilerModeSwitches);
  1431. EnumSwitches(VerboseSwitches);
  1432. EnumSwitches(CodegenSwitches);
  1433. EnumSwitches(OptimizationSwitches);
  1434. EnumSwitches(ProcessorOptimizationSwitches);
  1435. EnumSwitches(ProcessorCodeGenerationSwitches);
  1436. EnumSwitches(AsmReaderSwitches);
  1437. EnumSwitches(AsmInfoSwitches);
  1438. EnumSwitches(AsmOutputSwitches[SM]);
  1439. EnumSwitches(TargetSwitches);
  1440. EnumSwitches(ConditionalSwitches);
  1441. EnumSwitches(MemorySwitches);
  1442. EnumSwitches(BrowserSwitches);
  1443. EnumSwitches(DirectorySwitches);
  1444. S:='';
  1445. for I:=0 to SwitchParams^.Count-1 do
  1446. begin
  1447. if I=0 then S:='{$' else S:=S+',';
  1448. S:=S+PString(SwitchParams^.At(I))^;
  1449. end;
  1450. if S<>'' then S:=S+'}';
  1451. if S<>'' then AddLine(' '+S);
  1452. for I:=0 to MiscParams^.Count-1 do
  1453. AddLine(' {$'+PString(MiscParams^.At(I))^+'}');
  1454. Dispose(SwitchParams, Done); Dispose(MiscParams, Done);
  1455. AddLine('{$ENDIF '+IfDefSym+'}');
  1456. end;
  1457. var SM: TSwitchMode;
  1458. begin
  1459. for SM:=Low(TSwitchMode) to High(TSwitchMode) do
  1460. ConstructSwitchModeDirectives(SM,SwitchesModeStr[SM]);
  1461. end;
  1462. end.