fpswitch.pas 47 KB

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