fpswitch.pas 47 KB

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