scandir.inc 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Peter Vreman
  4. This unit implements directive parsing for the scanner
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. const
  19. directivelen=15;
  20. type
  21. directivestr=string[directivelen];
  22. tdirectivetoken=(
  23. _DIR_NONE,
  24. _DIR_ALIGN,_DIR_APPTYPE,_DIR_ASMMODE,_DIR_ASSERTIONS,
  25. _DIR_BOOLEVAL,
  26. _DIR_D,_DIR_DEBUGINFO,_DIR_DEFINE,_DIR_DESCRIPTION,
  27. _DIR_ELSE,_DIR_ENDIF,_DIR_ERROR,_DIR_EXTENDEDSYNTAX,
  28. _DIR_FATAL,
  29. _DIR_GOTO,
  30. _DIR_HINT,_DIR_HINTS,
  31. _DIR_I,_DIR_I386_ATT,_DIR_I386_DIRECT,_DIR_I386_INTEL,_DIR_IOCHECKS,
  32. _DIR_IF,_DIR_IFDEF,_DIR_IFNDEF,_DIR_IFOPT,_DIR_INCLUDE,_DIR_INCLUDEPATH,
  33. _DIR_INFO,_DIR_INLINE,
  34. _DIR_L,_DIR_LIBRARYPATH,_DIR_LINK,_DIR_LINKLIB,_DIR_LOCALSYMBOLS,
  35. _DIR_LONGSTRINGS,
  36. _DIR_M,_DIR_MACRO,_DIR_MAXFPUREGISTERS,_DIR_MEMORY,_DIR_MESSAGE,_DIR_MINENUMSIZE,_DIR_MMX,_DIR_MODE,
  37. _DIR_NOTE,_DIR_NOTES,
  38. _DIR_OBJECTPATH,_DIR_OPENSTRINGS,_DIR_OUTPUT_FORMAT,_DIR_OVERFLOWCHECKS,
  39. _DIR_PACKENUM,_DIR_PACKRECORDS,
  40. {$IFDEF Testvarsets}
  41. _DIR_PACKSET,
  42. {$ENDIF}
  43. _DIR_R,_DIR_RANGECHECKS,_DIR_REFERENCEINFO,
  44. _DIR_SATURATION,_DIR_SMARTLINK,_DIR_STACKFRAMES,_DIR_STATIC,_DIR_STOP,
  45. _DIR_TYPEDADDRESS,_DIR_TYPEINFO,
  46. _DIR_UNDEF,_DIR_UNITPATH,
  47. _DIR_VARSTRINGCHECKS,_DIR_VERSION,
  48. _DIR_WAIT,_DIR_WARNING,_DIR_WARNINGS,
  49. _DIR_Z1,_DIR_Z2,_DIR_Z4
  50. );
  51. const
  52. firstdirective=_DIR_NONE;
  53. lastdirective=_DIR_Z4;
  54. directive:array[tdirectivetoken] of directivestr=(
  55. {12345678901234567890 (To determine longest string.)}
  56. '',
  57. 'ALIGN',
  58. 'APPTYPE',
  59. 'ASMMODE',
  60. 'ASSERTIONS',
  61. 'BOOLEVAL',
  62. 'D',
  63. 'DEBUGINFO',
  64. 'DEFINE',
  65. 'DESCRIPTION',
  66. 'ELSE',
  67. 'ENDIF',
  68. 'ERROR',
  69. 'EXTENDEDSYNTAX',
  70. 'FATAL',
  71. 'GOTO',
  72. 'HINT',
  73. 'HINTS',
  74. 'I',
  75. {12345678901234567890 (To determine longest string.)}
  76. 'I386_ATT',
  77. 'I386_DIRECT',
  78. 'I386_INTEL',
  79. 'IOCHECKS',
  80. 'IF',
  81. 'IFDEF',
  82. 'IFNDEF',
  83. 'IFOPT',
  84. 'INCLUDE',
  85. 'INCLUDEPATH',
  86. 'INFO',
  87. 'INLINE',
  88. 'L',
  89. 'LIBRARYPATH',
  90. 'LINK',
  91. 'LINKLIB',
  92. 'LOCALSYMBOLS',
  93. 'LONGSTRINGS',
  94. 'M',
  95. {12345678901234567890 (To determine longest string.)}
  96. 'MACRO',
  97. 'MAXFPUREGISTERS',
  98. 'MEMORY',
  99. 'MESSAGE',
  100. 'MINENUMSIZE',
  101. 'MMX',
  102. 'MODE',
  103. 'NOTE',
  104. 'NOTES',
  105. 'OBJECTPATH',
  106. 'OPENSTRINGS',
  107. 'OUTPUT_FORMAT',
  108. 'OVERFLOWCHECKS',
  109. 'PACKENUM',
  110. 'PACKRECORDS',
  111. {$IFDEF testvarsets}
  112. 'PACKSET',
  113. {$ENDIF}
  114. 'R',
  115. 'RANGECHECKS',
  116. 'REFERENCEINFO',
  117. 'SATURATION',
  118. 'SMARTLINK',
  119. {12345678901234567890 (To determine longest string.)}
  120. 'STACKFRAMES',
  121. 'STATIC',
  122. 'STOP',
  123. 'TYPEDADDRESS',
  124. 'TYPEINFO',
  125. 'UNDEF',
  126. 'UNITPATH',
  127. 'VARSTRINGCHECKS',
  128. 'VERSION',
  129. 'WAIT',
  130. 'WARNING',
  131. 'WARNINGS',
  132. 'Z1',
  133. 'Z2',
  134. 'Z4'
  135. );
  136. function Get_Directive(const hs:string):tdirectivetoken;
  137. var
  138. i : tdirectivetoken;
  139. begin
  140. for i:=firstdirective to lastdirective do
  141. if directive[i]=hs then
  142. begin
  143. Get_Directive:=i;
  144. exit;
  145. end;
  146. Get_Directive:=_DIR_NONE;
  147. end;
  148. {-------------------------------------------
  149. IF Conditional Handling
  150. -------------------------------------------}
  151. var
  152. preprocpat : string;
  153. preproc_token : ttoken;
  154. procedure preproc_consume(t : ttoken);
  155. begin
  156. if t<>preproc_token then
  157. Message(scan_e_preproc_syntax_error);
  158. preproc_token:=current_scanner^.readpreproc;
  159. end;
  160. function read_expr : string;forward;
  161. function read_factor : string;
  162. var
  163. hs : string;
  164. mac : pmacrosym;
  165. len : byte;
  166. begin
  167. if preproc_token=_ID then
  168. begin
  169. if preprocpat='NOT' then
  170. begin
  171. preproc_consume(_ID);
  172. hs:=read_expr;
  173. if hs='0' then
  174. read_factor:='1'
  175. else
  176. read_factor:='0';
  177. end
  178. else
  179. begin
  180. mac:=pmacrosym(macros^.search(hs));
  181. hs:=preprocpat;
  182. preproc_consume(_ID);
  183. if assigned(mac) then
  184. begin
  185. if mac^.defined and assigned(mac^.buftext) then
  186. begin
  187. if mac^.buflen>255 then
  188. begin
  189. len:=255;
  190. Message(scan_w_macro_cut_after_255_chars);
  191. end
  192. else
  193. len:=mac^.buflen;
  194. {$ifndef TP}
  195. {$ifopt H+}
  196. setlength(hs,len);
  197. {$else}
  198. hs[0]:=char(len);
  199. {$endif}
  200. {$else}
  201. hs[0]:=char(len);
  202. {$endif}
  203. move(mac^.buftext^,hs[1],len);
  204. end
  205. else
  206. read_factor:='';
  207. end
  208. else
  209. read_factor:=hs;
  210. end
  211. end
  212. else if preproc_token=_LKLAMMER then
  213. begin
  214. preproc_consume(_LKLAMMER);
  215. read_factor:=read_expr;
  216. preproc_consume(_RKLAMMER);
  217. end
  218. else
  219. Message(scan_e_error_in_preproc_expr);
  220. end;
  221. function read_term : string;
  222. var
  223. hs1,hs2 : string;
  224. begin
  225. hs1:=read_factor;
  226. while true do
  227. begin
  228. if (preproc_token=_ID) then
  229. begin
  230. if preprocpat='AND' then
  231. begin
  232. preproc_consume(_ID);
  233. hs2:=read_factor;
  234. if (hs1<>'0') and (hs2<>'0') then
  235. hs1:='1';
  236. end
  237. else
  238. break;
  239. end
  240. else
  241. break;
  242. end;
  243. read_term:=hs1;
  244. end;
  245. function read_simple_expr : string;
  246. var
  247. hs1,hs2 : string;
  248. begin
  249. hs1:=read_term;
  250. while true do
  251. begin
  252. if (preproc_token=_ID) then
  253. begin
  254. if preprocpat='OR' then
  255. begin
  256. preproc_consume(_ID);
  257. hs2:=read_term;
  258. if (hs1<>'0') or (hs2<>'0') then
  259. hs1:='1';
  260. end
  261. else
  262. break;
  263. end
  264. else
  265. break;
  266. end;
  267. read_simple_expr:=hs1;
  268. end;
  269. function read_expr : string;
  270. var
  271. hs1,hs2 : string;
  272. b : boolean;
  273. t : ttoken;
  274. w : integer;
  275. l1,l2 : longint;
  276. begin
  277. hs1:=read_simple_expr;
  278. t:=preproc_token;
  279. if not(t in [_EQUAL,_UNEQUAL,_LT,_GT,_LTE,_GTE]) then
  280. begin
  281. read_expr:=hs1;
  282. exit;
  283. end;
  284. preproc_consume(t);
  285. hs2:=read_simple_expr;
  286. if is_number(hs1) and is_number(hs2) then
  287. begin
  288. valint(hs1,l1,w);
  289. valint(hs2,l2,w);
  290. case t of
  291. _EQUAL : b:=l1=l2;
  292. _UNEQUAL : b:=l1<>l2;
  293. _LT : b:=l1<l2;
  294. _GT : b:=l1>l2;
  295. _GTE : b:=l1>=l2;
  296. _LTE : b:=l1<=l2;
  297. end;
  298. end
  299. else
  300. begin
  301. case t of
  302. _EQUAL : b:=hs1=hs2;
  303. _UNEQUAL : b:=hs1<>hs2;
  304. _LT : b:=hs1<hs2;
  305. _GT : b:=hs1>hs2;
  306. _GTE : b:=hs1>=hs2;
  307. _LTE : b:=hs1<=hs2;
  308. end;
  309. end;
  310. if b then
  311. read_expr:='1'
  312. else
  313. read_expr:='0';
  314. end;
  315. {-------------------------------------------
  316. Directives
  317. -------------------------------------------}
  318. function is_conditional(t:tdirectivetoken):boolean;
  319. begin
  320. is_conditional:=(t in [_DIR_ENDIF,_DIR_IFDEF,_DIR_IFNDEF,_DIR_IFOPT,_DIR_IF,_DIR_ELSE]);
  321. end;
  322. procedure dir_conditional(t:tdirectivetoken);
  323. var
  324. hs : string;
  325. mac : pmacrosym;
  326. found : boolean;
  327. state : char;
  328. oldaktfilepos : tfileposinfo;
  329. begin
  330. oldaktfilepos:=aktfilepos;
  331. while true do
  332. begin
  333. current_scanner^.gettokenpos;
  334. case t of
  335. _DIR_ENDIF : begin
  336. current_scanner^.poppreprocstack;
  337. end;
  338. _DIR_ELSE : begin
  339. current_scanner^.elsepreprocstack;
  340. end;
  341. _DIR_IFDEF : begin
  342. current_scanner^.skipspace;
  343. hs:=current_scanner^.readid;
  344. mac:=pmacrosym(macros^.search(hs));
  345. if assigned(mac) then
  346. mac^.is_used:=true;
  347. current_scanner^.addpreprocstack(pp_ifdef,assigned(mac) and mac^.defined,hs,scan_c_ifdef_found);
  348. end;
  349. _DIR_IFOPT : begin
  350. current_scanner^.skipspace;
  351. hs:=current_scanner^.readid;
  352. if (length(hs)>1) then
  353. Message(scan_w_illegal_switch)
  354. else
  355. begin
  356. state:=current_scanner^.ReadState;
  357. if state in ['-','+'] then
  358. found:=CheckSwitch(hs[1],state);
  359. end;
  360. current_scanner^.addpreprocstack(pp_ifopt,found,hs,scan_c_ifopt_found);
  361. end;
  362. _DIR_IF : begin
  363. current_scanner^.skipspace;
  364. { start preproc expression scanner }
  365. preproc_token:=current_scanner^.readpreproc;
  366. hs:=read_expr;
  367. current_scanner^.addpreprocstack(pp_if,hs<>'0',hs,scan_c_if_found);
  368. end;
  369. _DIR_IFNDEF : begin
  370. current_scanner^.skipspace;
  371. hs:=current_scanner^.readid;
  372. mac:=pmacrosym(macros^.search(hs));
  373. if assigned(mac) then
  374. mac^.is_used:=true;
  375. current_scanner^.addpreprocstack(pp_ifndef,not(assigned(mac) and mac^.defined),hs,scan_c_ifndef_found);
  376. end;
  377. end;
  378. { accept the text ? }
  379. if (current_scanner^.preprocstack=nil) or current_scanner^.preprocstack^.accept then
  380. break
  381. else
  382. begin
  383. current_scanner^.gettokenpos;
  384. Message(scan_c_skipping_until);
  385. repeat
  386. current_scanner^.skipuntildirective;
  387. t:=Get_Directive(current_scanner^.readid);
  388. until is_conditional(t);
  389. current_scanner^.gettokenpos;
  390. Message1(scan_d_handling_switch,'$'+directive[t]);
  391. end;
  392. end;
  393. aktfilepos:=oldaktfilepos;
  394. end;
  395. procedure dir_define(t:tdirectivetoken);
  396. var
  397. hs : string;
  398. bracketcount : longint;
  399. mac : pmacrosym;
  400. macropos : longint;
  401. macrobuffer : pmacrobuffer;
  402. begin
  403. current_scanner^.skipspace;
  404. hs:=current_scanner^.readid;
  405. mac:=pmacrosym(macros^.search(hs));
  406. if not assigned(mac) then
  407. begin
  408. mac:=new(pmacrosym,init(hs));
  409. mac^.defined:=true;
  410. Message1(parser_m_macro_defined,mac^.name);
  411. macros^.insert(mac);
  412. end
  413. else
  414. begin
  415. Message1(parser_m_macro_defined,mac^.name);
  416. mac^.defined:=true;
  417. { delete old definition }
  418. if assigned(mac^.buftext) then
  419. begin
  420. freemem(mac^.buftext,mac^.buflen);
  421. mac^.buftext:=nil;
  422. end;
  423. end;
  424. mac^.is_used:=true;
  425. if (cs_support_macro in aktmoduleswitches) then
  426. begin
  427. { key words are never substituted }
  428. if is_keyword(hs) then
  429. Message(scan_e_keyword_cant_be_a_macro);
  430. { !!!!!! handle macro params, need we this? }
  431. current_scanner^.skipspace;
  432. { may be a macro? }
  433. if c=':' then
  434. begin
  435. current_scanner^.readchar;
  436. if c='=' then
  437. begin
  438. new(macrobuffer);
  439. macropos:=0;
  440. { parse macro, brackets are counted so it's possible
  441. to have a $ifdef etc. in the macro }
  442. bracketcount:=0;
  443. repeat
  444. current_scanner^.readchar;
  445. case c of
  446. '}' :
  447. if (bracketcount=0) then
  448. break
  449. else
  450. dec(bracketcount);
  451. '{' :
  452. inc(bracketcount);
  453. #26 :
  454. current_scanner^.end_of_file;
  455. end;
  456. macrobuffer^[macropos]:=c;
  457. inc(macropos);
  458. if macropos>maxmacrolen then
  459. Message(scan_f_macro_buffer_overflow);
  460. until false;
  461. { free buffer of macro ?}
  462. if assigned(mac^.buftext) then
  463. freemem(mac^.buftext,mac^.buflen);
  464. { get new mem }
  465. getmem(mac^.buftext,macropos);
  466. mac^.buflen:=macropos;
  467. { copy the text }
  468. move(macrobuffer^,mac^.buftext^,macropos);
  469. dispose(macrobuffer);
  470. end;
  471. end;
  472. end;
  473. end;
  474. procedure dir_undef(t:tdirectivetoken);
  475. var
  476. hs : string;
  477. mac : pmacrosym;
  478. begin
  479. current_scanner^.skipspace;
  480. hs:=current_scanner^.readid;
  481. mac:=pmacrosym(macros^.search(hs));
  482. if not assigned(mac) then
  483. begin
  484. mac:=new(pmacrosym,init(hs));
  485. Message1(parser_m_macro_undefined,mac^.name);
  486. mac^.defined:=false;
  487. macros^.insert(mac);
  488. end
  489. else
  490. begin
  491. Message1(parser_m_macro_undefined,mac^.name);
  492. mac^.defined:=false;
  493. { delete old definition }
  494. if assigned(mac^.buftext) then
  495. begin
  496. freemem(mac^.buftext,mac^.buflen);
  497. mac^.buftext:=nil;
  498. end;
  499. end;
  500. mac^.is_used:=true;
  501. end;
  502. procedure dir_message(t:tdirectivetoken);
  503. var
  504. w : longint;
  505. begin
  506. case t of
  507. _DIR_STOP,
  508. _DIR_FATAL : w:=scan_f_user_defined;
  509. _DIR_ERROR : w:=scan_e_user_defined;
  510. _DIR_WARNING : w:=scan_w_user_defined;
  511. _DIR_HINT : w:=scan_h_user_defined;
  512. _DIR_NOTE : w:=scan_n_user_defined;
  513. _DIR_MESSAGE,
  514. _DIR_INFO : w:=scan_i_user_defined;
  515. end;
  516. current_scanner^.skipspace;
  517. Message1(w,current_scanner^.readcomment);
  518. end;
  519. procedure dir_moduleswitch(t:tdirectivetoken);
  520. var
  521. sw : tmoduleswitch;
  522. state : char;
  523. begin
  524. sw:=cs_modulenone;
  525. case t of
  526. _DIR_GOTO : sw:=cs_support_goto;
  527. _DIR_MACRO : sw:=cs_support_macro;
  528. _DIR_INLINE : sw:=cs_support_inline;
  529. _DIR_SMARTLINK : sw:=cs_create_smart;
  530. _DIR_STATIC : sw:=cs_static_keyword;
  531. end;
  532. state:=current_scanner^.readstate;
  533. if (sw<>cs_modulenone) and (state in ['-','+']) then
  534. begin
  535. if state='-' then
  536. aktmoduleswitches:=aktmoduleswitches-[sw]
  537. else
  538. aktmoduleswitches:=aktmoduleswitches+[sw];
  539. end;
  540. end;
  541. procedure dir_localswitch(t:tdirectivetoken);
  542. var
  543. sw : tlocalswitch;
  544. state : char;
  545. begin
  546. sw:=cs_localnone;
  547. {$ifdef SUPPORT_MMX}
  548. case t of
  549. _DIR_MMX : sw:=cs_mmx;
  550. _DIR_SATURATION : sw:=cs_mmx_saturation;
  551. end;
  552. {$endif}
  553. state:=current_scanner^.readstate;
  554. if (sw<>cs_localnone) and (state in ['-','+']) then
  555. begin
  556. if not localswitcheschanged then
  557. nextaktlocalswitches:=aktlocalswitches;
  558. if state='-' then
  559. nextaktlocalswitches:=nextaktlocalswitches-[sw]
  560. else
  561. nextaktlocalswitches:=nextaktlocalswitches+[sw];
  562. localswitcheschanged:=true;
  563. end;
  564. end;
  565. procedure dir_include(t:tdirectivetoken);
  566. var
  567. hs : string;
  568. path : dirstr;
  569. name : namestr;
  570. ext : extstr;
  571. hp : pinputfile;
  572. i : longint;
  573. found : boolean;
  574. begin
  575. current_scanner^.skipspace;
  576. hs:=current_scanner^.readcomment;
  577. i:=length(hs);
  578. while (i>0) and (hs[i]=' ') do
  579. dec(i);
  580. Delete(hs,i+1,length(hs)-i);
  581. if hs='' then
  582. exit;
  583. if (hs[1]='%') then
  584. begin
  585. { case insensitive }
  586. hs:=upper(hs);
  587. { remove %'s }
  588. Delete(hs,1,1);
  589. if hs[length(hs)]='%' then
  590. Delete(hs,length(hs),1);
  591. { save old }
  592. path:=hs;
  593. { first check for internal macros }
  594. if hs='TIME' then
  595. hs:=gettimestr
  596. else
  597. if hs='DATE' then
  598. hs:=getdatestr
  599. else
  600. if hs='FILE' then
  601. hs:=current_module^.sourcefiles^.get_file_name(aktfilepos.fileindex)
  602. else
  603. if hs='LINE' then
  604. hs:=tostr(aktfilepos.line)
  605. else
  606. if hs='FPCVERSION' then
  607. hs:=version_string
  608. else
  609. if hs='FPCTARGET' then
  610. hs:=target_cpu_string
  611. else
  612. hs:=getenv(hs);
  613. if hs='' then
  614. Message1(scan_w_include_env_not_found,path);
  615. { make it a stringconst }
  616. hs:=''''+hs+'''';
  617. current_scanner^.insertmacro(path,@hs[1],length(hs));
  618. end
  619. else
  620. begin
  621. hs:=FixFileName(hs);
  622. fsplit(hs,path,name,ext);
  623. { look for the include file
  624. 1. specified path,path of current inputfile,current dir
  625. 2. local includepath
  626. 3. global includepath }
  627. found:=false;
  628. if path<>'' then
  629. path:=path+';';
  630. path:=FindFile(name+ext,path+current_scanner^.inputfile^.path^+';.'+DirSep,found);
  631. if (not found) then
  632. path:=current_module^.localincludesearchpath.FindFile(name+ext,found);
  633. if (not found) then
  634. path:=includesearchpath.FindFile(name+ext,found);
  635. { shutdown current file }
  636. current_scanner^.tempcloseinputfile;
  637. { load new file }
  638. hp:=new(pinputfile,init(path+name+ext));
  639. current_scanner^.addfile(hp);
  640. if not current_scanner^.openinputfile then
  641. Message1(scan_f_cannot_open_includefile,hs);
  642. Message1(scan_t_start_include_file,current_scanner^.inputfile^.path^+current_scanner^.inputfile^.name^);
  643. current_scanner^.reload;
  644. { process first read char }
  645. case c of
  646. #26 : current_scanner^.reload;
  647. #10,
  648. #13 : current_scanner^.linebreak;
  649. end;
  650. { register for refs }
  651. current_module^.sourcefiles^.register_file(hp);
  652. end;
  653. end;
  654. procedure dir_description(t:tdirectivetoken);
  655. begin
  656. if not (target_info.target in [target_i386_os2,target_i386_win32]) then
  657. Message(scan_w_decription_not_support);
  658. { change description global var in all cases }
  659. { it not used but in win32 and os2 }
  660. current_scanner^.skipspace;
  661. description:=current_scanner^.readcomment;
  662. end;
  663. procedure dir_version(t:tdirectivetoken);
  664. var
  665. major, minor : longint;
  666. error : integer;
  667. begin
  668. if not (target_info.target in [target_i386_os2,target_i386_win32]) then
  669. begin
  670. Message(scan_n_version_not_support);
  671. exit;
  672. end;
  673. if (compile_level<>1) then
  674. Message(scan_n_only_exe_version)
  675. else
  676. begin
  677. { change description global var in all cases }
  678. { it not used but in win32 and os2 }
  679. current_scanner^.skipspace;
  680. { we should only accept Major.Minor format }
  681. current_scanner^.readnumber;
  682. major:=0;
  683. minor:=0;
  684. valint(pattern,major,error);
  685. if error<>0 then
  686. begin
  687. Message1(scan_w_wrong_version_ignored,pattern);
  688. exit;
  689. end;
  690. if c='.' then
  691. begin
  692. current_scanner^.readchar;
  693. current_scanner^.readnumber;
  694. valint(pattern,minor,error);
  695. if error<>0 then
  696. begin
  697. Message1(scan_w_wrong_version_ignored,tostr(major)+'.'+pattern);
  698. exit;
  699. end;
  700. dllmajor:=major;
  701. dllminor:=minor;
  702. dllversion:=tostr(major)+'.'+tostr(minor);
  703. end
  704. else
  705. dllversion:=tostr(major);
  706. end;
  707. end;
  708. procedure dir_linkobject(t:tdirectivetoken);
  709. var
  710. s : string;
  711. begin
  712. current_scanner^.skipspace;
  713. s:=AddExtension(FixFileName(current_scanner^.readcomment),target_info.objext);
  714. {$IFDEF NEWST}
  715. current_module^.linkotherofiles.
  716. insert(new(Plinkitem,init(s,link_allways)));
  717. {$ELSE}
  718. current_module^.linkotherofiles.
  719. insert(s,link_allways);
  720. {$ENDIF NEWST}
  721. end;
  722. procedure dir_resource(t:tdirectivetoken);
  723. var
  724. s : string;
  725. begin
  726. current_scanner^.skipspace;
  727. s:=current_scanner^.readcomment;
  728. { replace * with current module name.
  729. This should always be defined. }
  730. if s[1]='*' then
  731. if Assigned(Current_Module) then
  732. begin
  733. delete(S,1,1);
  734. insert(lower(current_module^.modulename^),S,1);
  735. end;
  736. s:=AddExtension(FixFileName(s),target_info.resext);
  737. if target_info.res<>res_none then
  738. if (target_info.res = res_i386_emx) and
  739. not (Current_Module^.ResourceFiles.Empty) then
  740. Message(scan_w_only_one_resourcefile_supported)
  741. else
  742. current_module^.resourcefiles.insert(FixFileName(s))
  743. else
  744. Message(scan_e_resourcefiles_not_supported);
  745. end;
  746. {$ifndef PAVEL_LINKLIB}
  747. procedure dir_linklib(t:tdirectivetoken);
  748. var
  749. s : string;
  750. quote : char;
  751. begin
  752. current_scanner^.skipspace;
  753. { This way spaces are also allowed in library names
  754. if quoted PM }
  755. if (c='''') or (c='"') then
  756. begin
  757. quote:=c;
  758. current_scanner^.readchar;
  759. s:=current_scanner^.readcomment;
  760. if pos(quote,s)>0 then
  761. s:=copy(s,1,pos(quote,s)-1);
  762. end
  763. else
  764. begin
  765. current_scanner^.readstring;
  766. s:=orgpattern;
  767. if c='.' then
  768. begin
  769. s:=s+'.';
  770. current_scanner^.readchar;
  771. current_scanner^.readstring;
  772. s:=s+orgpattern;
  773. end;
  774. end;
  775. {$IFDEF NEWST}
  776. current_module^.linkOtherSharedLibs.
  777. insert(new(Plinkitem,init(s,link_allways)));
  778. {$ELSE}
  779. current_module^.linkOtherSharedLibs.
  780. insert(s,link_allways);
  781. {$ENDIF}
  782. end;
  783. {$else PAVEL_LINKLIB}
  784. procedure dir_linklib(t:tdirectivetoken);
  785. var
  786. s:string;
  787. libname,linkmodeStr:string;
  788. p:longint;
  789. type
  790. tLinkMode=(lm_dynamic,lm_static);
  791. var
  792. linkMode:tLinkMode;
  793. function ExtractLinkMode:tLinkMode;
  794. var
  795. p:longint;
  796. begin
  797. p:=pos(',',linkmodeStr);
  798. if p>0 then
  799. linkmodeStr:=copy(linkmodeStr,1,pred(p));
  800. for p:=1 to length(linkmodeStr)do
  801. linkmodeStr[p]:=upcase(linkmodeStr[p]);
  802. if linkmodeStr='STATIC' then
  803. ExtractLinkMode:=lm_static
  804. else
  805. ExtractLinkMode:=lm_dynamic
  806. end;
  807. procedure MangleLibName(mode:tLinkMode);
  808. begin
  809. if (libname[1]='''')and(libname[length(libname)]='''')then
  810. begin
  811. delete(libname,1,1);
  812. delete(libname,length(libname),1);
  813. end
  814. else
  815. begin
  816. libname:=target_os.libprefix+libname;
  817. case mode of
  818. lm_static:
  819. libname:=AddExtension(FixFileName(libname),target_os.staticlibext);
  820. lm_dynamic:
  821. libname:=AddExtension(FixFileName(libname),target_os.sharedlibext);
  822. end;
  823. end;
  824. end;
  825. begin
  826. current_scanner^.skipspace;
  827. s:=current_scanner^.readcomment;
  828. p:=pos(',',s);
  829. if p=0 then
  830. begin
  831. libname:=s;
  832. linkmodeStr:=''
  833. end
  834. else
  835. begin
  836. libname:=copy(s,1,pred(p));
  837. linkmodeStr:=copy(s,succ(p),255);
  838. end;
  839. if(libname='')or(libname='''''')then
  840. exit;
  841. linkMode:=ExtractLinkMode;
  842. MangleLibName(linkMode);
  843. if linkMode=lm_static then
  844. {$IFDEF NEWST}
  845. current_module^.linkOtherStaticLibs.
  846. insert(new(Plinkitem,init(FixFileName(libname),link_allways)))
  847. {$ELSE}
  848. current_module^.linkOtherStaticLibs.
  849. insert(FixFileName(libname),link_allways)
  850. {$ENDIF}
  851. else
  852. {$IFDEF NEWST}
  853. current_module^.linkOtherSharedLibs.
  854. insert(new(Plinkitem,init(FixFileName(libname),link_allways)));
  855. {$ELSE}
  856. current_module^.linkOtherSharedLibs.
  857. insert(FixFileName(libname),link_allways);
  858. {$ENDIF}
  859. end;
  860. {$endif PAVEL_LINKLIB}
  861. procedure dir_outputformat(t:tdirectivetoken);
  862. begin
  863. if not current_module^.in_global then
  864. Message(scan_w_switch_is_global)
  865. else
  866. begin
  867. current_scanner^.skipspace;
  868. if set_string_asm(current_scanner^.readid) then
  869. aktoutputformat:=target_asm.id
  870. else
  871. Message(scan_w_illegal_switch);
  872. end;
  873. end;
  874. procedure dir_unitpath(t:tdirectivetoken);
  875. begin
  876. if not current_module^.in_global then
  877. Message(scan_w_switch_is_global)
  878. else
  879. begin
  880. current_scanner^.skipspace;
  881. current_module^.localunitsearchpath.AddPath(current_scanner^.readcomment,false);
  882. end;
  883. end;
  884. procedure dir_includepath(t:tdirectivetoken);
  885. begin
  886. if not current_module^.in_global then
  887. Message(scan_w_switch_is_global)
  888. else
  889. begin
  890. current_scanner^.skipspace;
  891. current_module^.localincludesearchpath.AddPath(current_scanner^.readcomment,false);
  892. end;
  893. end;
  894. procedure dir_librarypath(t:tdirectivetoken);
  895. begin
  896. if not current_module^.in_global then
  897. Message(scan_w_switch_is_global)
  898. else
  899. begin
  900. current_scanner^.skipspace;
  901. current_module^.locallibrarysearchpath.AddPath(current_scanner^.readcomment,false);
  902. end;
  903. end;
  904. procedure dir_objectpath(t:tdirectivetoken);
  905. begin
  906. if not current_module^.in_global then
  907. Message(scan_w_switch_is_global)
  908. else
  909. begin
  910. current_scanner^.skipspace;
  911. current_module^.localobjectsearchpath.AddPath(current_scanner^.readcomment,false);
  912. end;
  913. end;
  914. procedure dir_mode(t:tdirectivetoken);
  915. begin
  916. if not current_module^.in_global then
  917. Message(scan_w_switch_is_global)
  918. else
  919. begin
  920. current_scanner^.skipspace;
  921. current_scanner^.readstring;
  922. if pattern='DEFAULT' then
  923. aktmodeswitches:=initmodeswitches
  924. else
  925. if pattern='DELPHI' then
  926. aktmodeswitches:=delphimodeswitches
  927. else
  928. if pattern='TP' then
  929. aktmodeswitches:=tpmodeswitches
  930. else
  931. if pattern='FPC' then
  932. aktmodeswitches:=fpcmodeswitches
  933. else
  934. if pattern='OBJFPC' then
  935. aktmodeswitches:=objfpcmodeswitches
  936. else
  937. if pattern='GPC' then
  938. aktmodeswitches:=gpcmodeswitches
  939. else
  940. Message(scan_w_illegal_switch);
  941. end;
  942. end;
  943. procedure dir_packrecords(t:tdirectivetoken);
  944. var
  945. hs : string;
  946. begin
  947. current_scanner^.skipspace;
  948. if not(c in ['0'..'9']) then
  949. begin
  950. hs:=current_scanner^.readid;
  951. if (hs='C') then
  952. aktpackrecords:=packrecord_C
  953. else
  954. if (hs='NORMAL') or (hs='DEFAULT') then
  955. aktpackrecords:=packrecord_2
  956. else
  957. Message(scan_w_only_pack_records);
  958. end
  959. else
  960. begin
  961. case current_scanner^.readval of
  962. 1 : aktpackrecords:=packrecord_1;
  963. 2 : aktpackrecords:=packrecord_2;
  964. 4 : aktpackrecords:=packrecord_4;
  965. 8 : aktpackrecords:=packrecord_8;
  966. 16 : aktpackrecords:=packrecord_16;
  967. 32 : aktpackrecords:=packrecord_32;
  968. else
  969. Message(scan_w_only_pack_records);
  970. end;
  971. end;
  972. end;
  973. procedure dir_maxfpuregisters(t:tdirectivetoken);
  974. var
  975. l : longint;
  976. hs : string;
  977. begin
  978. current_scanner^.skipspace;
  979. if not(c in ['0'..'9']) then
  980. begin
  981. hs:=current_scanner^.readid;
  982. if (hs='NORMAL') or (hs='DEFAULT') then
  983. aktmaxfpuregisters:=-1
  984. else
  985. Message(scan_e_invalid_maxfpureg_value);
  986. end
  987. else
  988. begin
  989. l:=current_scanner^.readval;
  990. case l of
  991. 0..8:
  992. aktmaxfpuregisters:=l;
  993. else
  994. Message(scan_e_invalid_maxfpureg_value);
  995. end;
  996. end;
  997. end;
  998. procedure dir_packenum(t:tdirectivetoken);
  999. var
  1000. hs : string;
  1001. begin
  1002. if t in [_DIR_Z1,_DIR_Z2,_DIR_Z4] then
  1003. begin
  1004. aktpackenum:=ord(pattern[2])-ord('0');
  1005. exit;
  1006. end;
  1007. current_scanner^.skipspace;
  1008. if not(c in ['0'..'9']) then
  1009. begin
  1010. hs:=current_scanner^.readid;
  1011. if (hs='NORMAL') or (hs='DEFAULT') then
  1012. aktpackenum:=4
  1013. else
  1014. Message(scan_w_only_pack_enum);
  1015. end
  1016. else
  1017. begin
  1018. case current_scanner^.readval of
  1019. 1 : aktpackenum:=1;
  1020. 2 : aktpackenum:=2;
  1021. 4 : aktpackenum:=4;
  1022. else
  1023. Message(scan_w_only_pack_enum);
  1024. end;
  1025. end;
  1026. end;
  1027. {$ifdef testvarsets}
  1028. procedure dir_setalloc(t:tdirectivetoken);
  1029. var
  1030. hs : string;
  1031. begin
  1032. current_scanner^.skipspace;
  1033. if not(c in ['1','2','4']) then
  1034. begin
  1035. hs:=current_scanner^.readid;
  1036. if (hs='FIXED') or ((hs='DEFAULT') OR (hs='NORMAL')) then
  1037. aktsetalloc:=0 {Fixed mode, sets are 4 or 32 bytes}
  1038. else
  1039. Message(scan_w_only_packset);
  1040. end
  1041. else
  1042. begin
  1043. case current_scanner^.readval of
  1044. 1 : aktpackenum:=1;
  1045. 2 : aktpackenum:=2;
  1046. 4 : aktpackenum:=4;
  1047. else
  1048. Message(scan_w_only_packset);
  1049. end;
  1050. end;
  1051. end;
  1052. {$ENDIF}
  1053. procedure dir_apptype(t:tdirectivetoken);
  1054. var
  1055. hs : string;
  1056. begin
  1057. if target_info.target<>target_i386_win32 then
  1058. Message(scan_w_app_type_not_support);
  1059. if not current_module^.in_global then
  1060. Message(scan_w_switch_is_global)
  1061. else
  1062. begin
  1063. current_scanner^.skipspace;
  1064. hs:=current_scanner^.readid;
  1065. if hs='GUI' then
  1066. apptype:=at_gui
  1067. else if hs='CONSOLE' then
  1068. apptype:=at_cui
  1069. else
  1070. Message1(scan_w_unsupported_app_type,hs);
  1071. end;
  1072. end;
  1073. procedure dir_wait(t:tdirectivetoken);
  1074. var had_info : boolean;
  1075. begin
  1076. had_info:=(status.verbosity and V_Info)<>0;
  1077. { this message should allways appear !! }
  1078. status.verbosity:=status.verbosity or V_Info;
  1079. Message(scan_i_press_enter);
  1080. readln;
  1081. If not(had_info) then
  1082. status.verbosity:=status.verbosity and (not V_Info);
  1083. end;
  1084. procedure dir_asmmode(t:tdirectivetoken);
  1085. var
  1086. s : string;
  1087. begin
  1088. current_scanner^.skipspace;
  1089. s:=current_scanner^.readid;
  1090. If Inside_asm_statement then
  1091. Message1(scan_w_no_asm_reader_switch_inside_asm,s);
  1092. if s='DEFAULT' then
  1093. aktasmmode:=initasmmode
  1094. else
  1095. if not set_string_asmmode(s,aktasmmode) then
  1096. Message1(scan_w_unsupported_asmmode_specifier,s);
  1097. end;
  1098. procedure dir_oldasmmode(t:tdirectivetoken);
  1099. begin
  1100. If Inside_asm_statement then
  1101. Message1(scan_w_no_asm_reader_switch_inside_asm,directive[t]);
  1102. {$ifdef i386}
  1103. case t of
  1104. _DIR_I386_ATT : aktasmmode:=asmmode_i386_att;
  1105. _DIR_I386_DIRECT : aktasmmode:=asmmode_i386_direct;
  1106. _DIR_I386_INTEL : aktasmmode:=asmmode_i386_intel;
  1107. end;
  1108. {$endif i386}
  1109. end;
  1110. procedure dir_delphiswitch(t:tdirectivetoken);
  1111. var
  1112. sw,state : char;
  1113. begin
  1114. case t of
  1115. _DIR_ALIGN : sw:='A';
  1116. _DIR_ASSERTIONS : sw:='C';
  1117. _DIR_BOOLEVAL : sw:='B';
  1118. _DIR_DEBUGINFO : sw:='D';
  1119. _DIR_IOCHECKS : sw:='I';
  1120. _DIR_LOCALSYMBOLS : sw:='L';
  1121. _DIR_LONGSTRINGS : sw:='H';
  1122. _DIR_OPENSTRINGS : sw:='P';
  1123. _DIR_OVERFLOWCHECKS : sw:='Q';
  1124. _DIR_RANGECHECKS : sw:='R';
  1125. _DIR_REFERENCEINFO : sw:='Y';
  1126. _DIR_STACKFRAMES : sw:='W';
  1127. _DIR_TYPEDADDRESS : sw:='T';
  1128. _DIR_TYPEINFO : sw:='M';
  1129. _DIR_VARSTRINGCHECKS : sw:='V';
  1130. else
  1131. exit;
  1132. end;
  1133. { c contains the next char, a + or - would be fine }
  1134. state:=current_scanner^.readstate;
  1135. if state in ['-','+'] then
  1136. HandleSwitch(sw,state);
  1137. end;
  1138. procedure dir_memory(t:tdirectivetoken);
  1139. var
  1140. l : longint;
  1141. begin
  1142. current_scanner^.skipspace;
  1143. l:=current_scanner^.readval;
  1144. if l>1024 then
  1145. stacksize:=l;
  1146. current_scanner^.skipspace;
  1147. if c=',' then
  1148. begin
  1149. current_scanner^.readchar;
  1150. current_scanner^.skipspace;
  1151. l:=current_scanner^.readval;
  1152. if l>1024 then
  1153. heapsize:=l;
  1154. end;
  1155. if c=',' then
  1156. begin
  1157. current_scanner^.readchar;
  1158. current_scanner^.skipspace;
  1159. l:=current_scanner^.readval;
  1160. { Ignore this value, because the limit is set by the OS
  1161. info and shouldn't be changed by the user (PFV) }
  1162. end;
  1163. end;
  1164. procedure dir_setverbose(t:tdirectivetoken);
  1165. var
  1166. flag,
  1167. state : char;
  1168. begin
  1169. case t of
  1170. _DIR_HINTS : flag:='H';
  1171. _DIR_WARNINGS : flag:='W';
  1172. _DIR_NOTES : flag:='N';
  1173. else
  1174. exit;
  1175. end;
  1176. { support ON/OFF }
  1177. state:=current_scanner^.ReadState;
  1178. SetVerbosity(flag+state);
  1179. end;
  1180. type
  1181. tdirectiveproc=procedure(t:tdirectivetoken);
  1182. const
  1183. directiveproc:array[tdirectivetoken] of tdirectiveproc=(
  1184. {_DIR_NONE} nil,
  1185. {_DIR_ALIGN} dir_delphiswitch,
  1186. {_DIR_APPTYPE} dir_apptype,
  1187. {_DIR_ASMMODE} dir_asmmode,
  1188. {_DIR_ASSERTION} dir_delphiswitch,
  1189. {_DIR_BOOLEVAL} dir_delphiswitch,
  1190. {_DIR_D} dir_description,
  1191. {_DIR_DEBUGINFO} dir_delphiswitch,
  1192. {_DIR_DEFINE} dir_define,
  1193. {_DIR_DESCRIPTION} dir_description,
  1194. {_DIR_ELSE} dir_conditional,
  1195. {_DIR_ENDIF} dir_conditional,
  1196. {_DIR_ERROR} dir_message,
  1197. {_DIR_EXTENDEDSYNTAX} dir_delphiswitch,
  1198. {_DIR_FATAL} dir_message,
  1199. {_DIR_GOTO} dir_moduleswitch,
  1200. {_DIR_HINT} dir_message,
  1201. {_DIR_HINTS} dir_setverbose,
  1202. {_DIR_I} dir_include,
  1203. {_DIR_I386_ATT} dir_oldasmmode,
  1204. {_DIR_I386_DIRECT} dir_oldasmmode,
  1205. {_DIR_I386_INTEL} dir_oldasmmode,
  1206. {_DIR_IOCHECKS} dir_delphiswitch,
  1207. {_DIR_IF} dir_conditional,
  1208. {_DIR_IFDEF} dir_conditional,
  1209. {_DIR_IFNDEF} dir_conditional,
  1210. {_DIR_IFOPT} dir_conditional,
  1211. {_DIR_INCLUDE} dir_include,
  1212. {_DIR_INCLUDEPATH} dir_includepath,
  1213. {_DIR_INFO} dir_message,
  1214. {_DIR_INLINE} dir_moduleswitch,
  1215. {_DIR_L} dir_linkobject,
  1216. {_DIR_LIBRARYPATH} dir_librarypath,
  1217. {_DIR_LINK} dir_linkobject,
  1218. {_DIR_LINKLIB} dir_linklib,
  1219. {_DIR_LOCALSYMBOLS} dir_delphiswitch,
  1220. {_DIR_LONGSTRINGS} dir_delphiswitch,
  1221. {_DIR_M} dir_memory,
  1222. {_DIR_MACRO} dir_moduleswitch,
  1223. {_DIR_MAXFPUREGISTERS} dir_maxfpuregisters,
  1224. {_DIR_MEMORY} dir_memory,
  1225. {_DIR_MESSAGE} dir_message,
  1226. {_DIR_MINENUMSIZE} dir_packenum,
  1227. {_DIR_MMX} dir_localswitch,
  1228. {_DIR_MODE} dir_mode,
  1229. {_DIR_NOTE} dir_message,
  1230. {_DIR_NOTES} dir_setverbose,
  1231. {_DIR_OBJECTPATH} dir_objectpath,
  1232. {_DIR_OPENSTRINGS} dir_delphiswitch,
  1233. {_DIR_OUTPUT_FORMAT} dir_outputformat,
  1234. {_DIR_OVERFLOWCHECKS} dir_delphiswitch,
  1235. {_DIR_PACKENUM} dir_packenum,
  1236. {_DIR_PACKRECORDS} dir_packrecords,
  1237. {$IFDEF TestVarsets}
  1238. {_DIR_PACKSET} dir_packset,
  1239. {$ENDIF}
  1240. {_DIR_R} dir_resource,
  1241. {_DIR_RANGECHECKS} dir_delphiswitch,
  1242. {_DIR_REFERENCEINFO} dir_delphiswitch,
  1243. {_DIR_SATURATION} dir_localswitch,
  1244. {_DIR_SMARTLINK} dir_moduleswitch,
  1245. {_DIR_STACKFRAMES} dir_delphiswitch,
  1246. {_DIR_STATIC} dir_moduleswitch,
  1247. {_DIR_STOP} dir_message,
  1248. {_DIR_TYPEDADDRESS} dir_delphiswitch,
  1249. {_DIR_TYPEINFO} dir_delphiswitch,
  1250. {_DIR_UNDEF} dir_undef,
  1251. {_DIR_UNITPATH} dir_unitpath,
  1252. {_DIR_VARSTRINGCHECKS} dir_delphiswitch,
  1253. {_DIR_VERSION} dir_version,
  1254. {_DIR_WAIT} dir_wait,
  1255. {_DIR_WARNING} dir_message,
  1256. {_DIR_WARNINGS} dir_setverbose,
  1257. {_DIR_Z1} dir_packenum,
  1258. {_DIR_Z2} dir_packenum,
  1259. {_DIR_Z4} dir_packenum
  1260. );
  1261. {-------------------------------------------
  1262. Main switches handling
  1263. -------------------------------------------}
  1264. procedure handledirectives;
  1265. var
  1266. t : tdirectivetoken;
  1267. p : tdirectiveproc;
  1268. hs : string;
  1269. begin
  1270. current_scanner^.gettokenpos;
  1271. current_scanner^.readchar; {Remove the $}
  1272. hs:=current_scanner^.readid;
  1273. if parapreprocess then
  1274. begin
  1275. t:=Get_Directive(hs);
  1276. if not(is_conditional(t) or (t=_DIR_DEFINE) or (t=_DIR_UNDEF)) then
  1277. begin
  1278. preprocfile^.AddSpace;
  1279. preprocfile^.Add('{$'+hs+current_scanner^.readcomment+'}');
  1280. exit;
  1281. end;
  1282. end;
  1283. Message1(scan_d_handling_switch,'$'+hs);
  1284. if hs='' then
  1285. Message1(scan_w_illegal_switch,'$'+hs);
  1286. { Check for compiler switches }
  1287. while (length(hs)=1) and (c in ['-','+']) do
  1288. begin
  1289. HandleSwitch(hs[1],c);
  1290. current_scanner^.readchar; {Remove + or -}
  1291. if c=',' then
  1292. begin
  1293. current_scanner^.readchar; {Remove , }
  1294. { read next switch, support $v+,$+}
  1295. hs:=current_scanner^.readid;
  1296. if (hs='') then
  1297. begin
  1298. if (c='$') and (m_fpc in aktmodeswitches) then
  1299. begin
  1300. current_scanner^.readchar; { skip $ }
  1301. hs:=current_scanner^.readid;
  1302. end;
  1303. if (hs='') then
  1304. Message1(scan_w_illegal_directive,'$'+c);
  1305. end
  1306. else
  1307. Message1(scan_d_handling_switch,'$'+hs);
  1308. end
  1309. else
  1310. hs:='';
  1311. end;
  1312. { directives may follow switches after a , }
  1313. if hs<>'' then
  1314. begin
  1315. t:=Get_Directive(hs);
  1316. if t<>_DIR_NONE then
  1317. begin
  1318. p:=directiveproc[t];
  1319. {$ifndef TP}
  1320. if assigned(p) then
  1321. {$else}
  1322. if @p<>nil then
  1323. {$endif}
  1324. p(t);
  1325. end
  1326. else
  1327. Message1(scan_w_illegal_directive,'$'+hs);
  1328. { conditionals already read the comment }
  1329. if (current_scanner^.comment_level>0) then
  1330. current_scanner^.readcomment;
  1331. { we've read the whole comment }
  1332. aktcommentstyle:=comment_none;
  1333. end;
  1334. end;
  1335. {
  1336. $Log$
  1337. Revision 1.83 2000-06-30 20:23:38 peter
  1338. * new message files layout with msg numbers (but still no code to
  1339. show the number on the screen)
  1340. Revision 1.82 2000/06/25 19:08:27 hajny
  1341. + $R support for OS/2 (EMX) added
  1342. Revision 1.81 2000/05/23 20:18:25 pierre
  1343. + pavel's code integrated, but onyl inside
  1344. ifdef pavel_linklib !
  1345. Revision 1.80 2000/05/09 21:31:50 pierre
  1346. * fix problem when modifying several local switches in a row
  1347. Revision 1.79 2000/05/03 14:36:58 pierre
  1348. * fix for tests/test/testrang.pp bug
  1349. Revision 1.78 2000/04/14 11:16:10 pierre
  1350. * partial linklib change
  1351. I could not use Pavel's code because it broke the current way
  1352. linklib is used, which is messy :(
  1353. + add postw32 call if external linking on win32
  1354. Revision 1.77 2000/04/08 20:18:53 michael
  1355. * Fixed bug in readcomment that was dropping * characters
  1356. Revision 1.76 2000/02/28 17:23:57 daniel
  1357. * Current work of symtable integration committed. The symtable can be
  1358. activated by defining 'newst', but doesn't compile yet. Changes in type
  1359. checking and oop are completed. What is left is to write a new
  1360. symtablestack and adapt the parser to use it.
  1361. Revision 1.75 2000/02/14 20:58:43 marco
  1362. * Basic structures for new sethandling implemented.
  1363. Revision 1.74 2000/02/09 13:23:03 peter
  1364. * log truncated
  1365. Revision 1.73 2000/01/14 14:28:40 pierre
  1366. * avoid searching of include file in start dir first
  1367. Revision 1.72 2000/01/07 01:14:37 peter
  1368. * updated copyright to 2000
  1369. Revision 1.71 2000/01/04 15:15:53 florian
  1370. + added compiler switch $maxfpuregisters
  1371. + fixed a small problem in secondvecn
  1372. Revision 1.70 1999/12/20 23:23:30 pierre
  1373. + $description $version
  1374. Revision 1.69 1999/12/02 17:34:34 peter
  1375. * preprocessor support. But it fails on the caret in type blocks
  1376. Revision 1.68 1999/11/24 11:39:53 pierre
  1377. * asmmode message was placed too early
  1378. Revision 1.67 1999/11/12 11:03:50 peter
  1379. * searchpaths changed to stringqueue object
  1380. Revision 1.66 1999/11/06 14:34:26 peter
  1381. * truncated log to 20 revs
  1382. Revision 1.65 1999/10/30 12:32:30 peter
  1383. * fixed line counter when the first line had #10 only. This was buggy
  1384. for both the main file as for include files
  1385. Revision 1.64 1999/09/27 23:38:17 peter
  1386. * bracket support for macro define
  1387. Revision 1.63 1999/09/20 16:39:02 peter
  1388. * cs_create_smart instead of cs_smartlink
  1389. * -CX is create smartlink
  1390. * -CD is create dynamic, but does nothing atm.
  1391. Revision 1.62 1999/09/03 10:00:49 peter
  1392. * included the 1.60 version of Pierre which was lost !
  1393. Revision 1.61 1999/09/02 18:47:46 daniel
  1394. * Could not compile with TP, some arrays moved to heap
  1395. * NOAG386BIN default for TP
  1396. * AG386* files were not compatible with TP, fixed.
  1397. Revision 1.60 1999/08/31 15:55:45 pierre
  1398. + tmacrosym.is_used set
  1399. Revision 1.59 1999/08/05 16:53:10 peter
  1400. * V_Fatal=1, all other V_ are also increased
  1401. * Check for local procedure when assigning procvar
  1402. * fixed comment parsing because directives
  1403. * oldtp mode directives better supported
  1404. * added some messages to errore.msg
  1405. Revision 1.58 1999/08/04 13:03:03 jonas
  1406. * all tokens now start with an underscore
  1407. * PowerPC compiles!!
  1408. Revision 1.57 1999/07/26 14:55:36 florian
  1409. * $mode gives now a warning if an unknown mode keyword follows
  1410. Revision 1.56 1999/07/23 16:05:27 peter
  1411. * alignment is now saved in the symtable
  1412. * C alignment added for records
  1413. * PPU version increased to solve .12 <-> .13 probs
  1414. }