fpswitch.pas 47 KB

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