fpswitch.pas 49 KB

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