fpswitch.pas 44 KB

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