switches.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. {
  2. Copyright (c) 1998-2002 by Peter Vreman
  3. This unit implements the parsing of the switches like $I-
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit switches;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. globtype;
  22. procedure HandleSwitch(switch,state:char);
  23. function CheckSwitch(switch,state:char):boolean;
  24. procedure recordpendingverbosityswitch(sw: char; state: char);
  25. procedure recordpendinglocalswitch(sw: tlocalswitch; state: char);
  26. procedure recordpendinglocalfullswitch(const switches: tlocalswitches);
  27. procedure recordpendingverbosityfullswitch(verbosity: longint);
  28. procedure flushpendingswitchesstate;
  29. implementation
  30. uses
  31. systems,cpuinfo,
  32. globals,verbose,comphook,
  33. fmodule;
  34. {****************************************************************************
  35. Main Switches Parsing
  36. ****************************************************************************}
  37. type
  38. TSwitchType=(ignoredsw,localsw,modulesw,globalsw,illegalsw,unsupportedsw,alignsw,optimizersw,packenumsw,pentiumfdivsw);
  39. SwitchRec=record
  40. typesw : TSwitchType;
  41. setsw : byte;
  42. end;
  43. SwitchRecTable = array['A'..'Z'] of SwitchRec;
  44. const
  45. turboSwitchTable: SwitchRecTable =(
  46. {A} (typesw:alignsw; setsw:ord(cs_localnone)),
  47. {B} (typesw:localsw; setsw:ord(cs_full_boolean_eval)),
  48. {C} (typesw:localsw; setsw:ord(cs_do_assertion)),
  49. {D} (typesw:modulesw; setsw:ord(cs_debuginfo)),
  50. {E} (typesw:modulesw; setsw:ord(cs_fp_emulation)),
  51. {F} (typesw:ignoredsw; setsw:ord(cs_localnone)),
  52. {G} (typesw:ignoredsw; setsw:ord(cs_localnone)),
  53. {H} (typesw:localsw; setsw:ord(cs_ansistrings)),
  54. {I} (typesw:localsw; setsw:ord(cs_check_io)),
  55. {J} (typesw:localsw; setsw:ord(cs_typed_const_writable)),
  56. {K} (typesw:unsupportedsw; setsw:ord(cs_localnone)),
  57. {L} (typesw:unsupportedsw; setsw:ord(cs_localnone)),
  58. {M} (typesw:localsw; setsw:ord(cs_generate_rtti)),
  59. {N} (typesw:unsupportedsw; setsw:ord(cs_localnone)),
  60. {O} (typesw:optimizersw; setsw:ord(cs_opt_none)),
  61. {P} (typesw:modulesw; setsw:ord(cs_openstring)),
  62. {Q} (typesw:localsw; setsw:ord(cs_check_overflow)),
  63. {R} (typesw:localsw; setsw:ord(cs_check_range)),
  64. {S} (typesw:localsw; setsw:ord(cs_check_stack)),
  65. {T} (typesw:localsw; setsw:ord(cs_typed_addresses)),
  66. {U} (typesw:pentiumfdivsw; setsw:ord(cs_localnone)),
  67. {V} (typesw:localsw; setsw:ord(cs_strict_var_strings)),
  68. {W} (typesw:localsw; setsw:ord(cs_generate_stackframes)),
  69. {X} (typesw:modulesw; setsw:ord(cs_extsyntax)),
  70. {Y} (typesw:unsupportedsw; setsw:ord(cs_localnone)),
  71. {Z} (typesw:packenumsw; setsw:ord(cs_localnone))
  72. );
  73. macSwitchTable: SwitchRecTable =(
  74. {A} (typesw:unsupportedsw; setsw:ord(cs_localnone)),
  75. {B} (typesw:localsw; setsw:ord(cs_full_boolean_eval)),
  76. {C} (typesw:localsw; setsw:ord(cs_do_assertion)),
  77. {D} (typesw:modulesw; setsw:ord(cs_debuginfo)),
  78. {E} (typesw:modulesw; setsw:ord(cs_fp_emulation)),
  79. {F} (typesw:ignoredsw; setsw:ord(cs_localnone)),
  80. {G} (typesw:ignoredsw; setsw:ord(cs_localnone)),
  81. {H} (typesw:localsw; setsw:ord(cs_ansistrings)),
  82. {I} (typesw:localsw; setsw:ord(cs_check_io)),
  83. {J} (typesw:localsw; setsw:ord(cs_external_var)),
  84. {K} (typesw:unsupportedsw; setsw:ord(cs_localnone)),
  85. {L} (typesw:unsupportedsw; setsw:ord(cs_localnone)),
  86. {M} (typesw:localsw; setsw:ord(cs_generate_rtti)),
  87. {N} (typesw:unsupportedsw; setsw:ord(cs_localnone)),
  88. {O} (typesw:optimizersw; setsw:ord(cs_opt_none)),
  89. {P} (typesw:modulesw; setsw:ord(cs_openstring)),
  90. {Q} (typesw:localsw; setsw:ord(cs_check_overflow)),
  91. {R} (typesw:localsw; setsw:ord(cs_check_range)),
  92. {S} (typesw:localsw; setsw:ord(cs_check_stack)),
  93. {T} (typesw:localsw; setsw:ord(cs_typed_addresses)),
  94. {U} (typesw:illegalsw; setsw:ord(cs_localnone)),
  95. {V} (typesw:localsw; setsw:ord(cs_strict_var_strings)),
  96. {W} (typesw:localsw; setsw:ord(cs_generate_stackframes)),
  97. {X} (typesw:modulesw; setsw:ord(cs_extsyntax)),
  98. {Y} (typesw:unsupportedsw; setsw:ord(cs_localnone)),
  99. {Z} (typesw:localsw; setsw:ord(cs_externally_visible))
  100. );
  101. procedure HandleSwitch(switch,state:char);
  102. var
  103. switchTablePtr: ^SwitchRecTable;
  104. begin
  105. switch:=upcase(switch);
  106. { Is the Switch in the letters ? }
  107. if not ((switch in ['A'..'Z']) and (state in ['-','+'])) then
  108. begin
  109. Message(scan_w_illegal_switch);
  110. exit;
  111. end;
  112. { Select switch table }
  113. if m_mac in current_settings.modeswitches then
  114. switchTablePtr:= @macSwitchTable
  115. else
  116. switchTablePtr:= @turboSwitchTable;
  117. { Handle the switch }
  118. with switchTablePtr^[switch] do
  119. begin
  120. case typesw of
  121. alignsw:
  122. if state='+' then
  123. current_settings.packrecords:=4
  124. else
  125. current_settings.packrecords:=1;
  126. optimizersw :
  127. begin
  128. if state='+' then
  129. current_settings.optimizerswitches:=level2optimizerswitches
  130. else
  131. current_settings.optimizerswitches:=[];
  132. end;
  133. ignoredsw :
  134. Message1(scan_n_ignored_switch,'$'+switch);
  135. illegalsw :
  136. Message1(scan_w_illegal_switch,'$'+switch);
  137. unsupportedsw :
  138. Message1(scan_w_unsupported_switch,'$'+switch);
  139. localsw :
  140. recordpendinglocalswitch(tlocalswitch(setsw),state);
  141. modulesw :
  142. begin
  143. if current_module.in_global then
  144. begin
  145. {$ifndef cpufpemu}
  146. if tmoduleswitch(setsw)=cs_fp_emulation then
  147. begin
  148. Message1(scan_w_unsupported_switch_by_target,'$'+switch);
  149. end
  150. else
  151. {$endif cpufpemu}
  152. begin
  153. if state='+' then
  154. include(current_settings.moduleswitches,tmoduleswitch(setsw))
  155. else
  156. begin
  157. { Turning off debuginfo when lineinfo is requested
  158. is not possible }
  159. if not((cs_use_lineinfo in current_settings.globalswitches) and
  160. (tmoduleswitch(setsw)=cs_debuginfo)) then
  161. exclude(current_settings.moduleswitches,tmoduleswitch(setsw));
  162. end;
  163. end;
  164. end
  165. else
  166. Message(scan_w_switch_is_global);
  167. end;
  168. globalsw :
  169. begin
  170. if current_module.in_global and (current_module=main_module) then
  171. begin
  172. if state='+' then
  173. include(current_settings.globalswitches,tglobalswitch(setsw))
  174. else
  175. exclude(current_settings.globalswitches,tglobalswitch(setsw));
  176. end
  177. else
  178. Message(scan_w_switch_is_global);
  179. end;
  180. packenumsw:
  181. begin
  182. if state='-' then
  183. current_settings.packenum:=1
  184. else
  185. current_settings.packenum:=4;
  186. end;
  187. pentiumfdivsw:
  188. begin
  189. { Switch u- means pentium-safe fdiv off -> fpc default. We don't }
  190. { support u+ }
  191. if state='+' then
  192. Message1(scan_w_unsupported_switch,'$'+switch);
  193. end;
  194. end;
  195. end;
  196. end;
  197. function CheckSwitch(switch,state:char):boolean;
  198. var
  199. found : boolean;
  200. switchTablePtr: ^SwitchRecTable;
  201. begin
  202. switch:=upcase(switch);
  203. { Is the Switch in the letters ? }
  204. if not ((switch in ['A'..'Z']) and (state in ['-','+'])) then
  205. begin
  206. Message(scan_w_illegal_switch);
  207. CheckSwitch:=false;
  208. exit;
  209. end;
  210. { Select switch table }
  211. if m_mac in current_settings.modeswitches then
  212. switchTablePtr:= @macSwitchTable
  213. else
  214. switchTablePtr:= @turboSwitchTable;
  215. { Check the switch }
  216. with switchTablePtr^[switch] do
  217. begin
  218. case typesw of
  219. localsw : found:=(tlocalswitch(setsw) in current_settings.localswitches);
  220. modulesw : found:=(tmoduleswitch(setsw) in current_settings.moduleswitches);
  221. globalsw : found:=(tglobalswitch(setsw) in current_settings.globalswitches);
  222. packenumsw : found := (current_settings.packenum = 4);
  223. else
  224. found:=false;
  225. end;
  226. if state='-' then
  227. found:=not found;
  228. CheckSwitch:=found;
  229. end;
  230. end;
  231. procedure recordpendingverbosityswitch(sw: char; state: char);
  232. begin
  233. pendingstate.nextverbositystr:=pendingstate.nextverbositystr+sw+state;
  234. end;
  235. procedure recordpendinglocalswitch(sw: tlocalswitch; state: char);
  236. begin
  237. if not pendingstate.localswitcheschanged then
  238. pendingstate.nextlocalswitches:=current_settings.localswitches;
  239. if state='-' then
  240. exclude(pendingstate.nextlocalswitches,sw)
  241. else if state='+' then
  242. include(pendingstate.nextlocalswitches,sw)
  243. else { state = '*' }
  244. begin
  245. if sw in init_settings.localswitches then
  246. include(pendingstate.nextlocalswitches,sw)
  247. else
  248. exclude(pendingstate.nextlocalswitches,sw);
  249. end;
  250. pendingstate.localswitcheschanged:=true;
  251. end;
  252. procedure recordpendinglocalfullswitch(const switches: tlocalswitches);
  253. begin
  254. pendingstate.nextlocalswitches:=switches;
  255. pendingstate.localswitcheschanged:=true;
  256. end;
  257. procedure recordpendingverbosityfullswitch(verbosity: longint);
  258. begin
  259. pendingstate.nextverbositystr:='';
  260. pendingstate.nextverbosityfullswitch:=verbosity;
  261. pendingstate.verbosityfullswitched:=true;
  262. end;
  263. procedure flushpendingswitchesstate;
  264. begin
  265. if pendingstate.localswitcheschanged then
  266. begin
  267. current_settings.localswitches:=pendingstate.nextlocalswitches;
  268. pendingstate.localswitcheschanged:=false;
  269. end;
  270. if pendingstate.verbosityfullswitched then
  271. begin
  272. status.verbosity:=pendingstate.nextverbosityfullswitch;
  273. pendingstate.verbosityfullswitched:=false;
  274. end;
  275. if pendingstate.nextverbositystr<>'' then
  276. begin
  277. setverbosity(pendingstate.nextverbositystr);
  278. pendingstate.nextverbositystr:='';
  279. end;
  280. end;
  281. end.