fpswitch.pas 45 KB

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