fpswitch.pas 47 KB

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