fpswitch.pas 49 KB

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