/usr.bin/xlint/lint1/scan.l

https://bitbucket.org/freebsd/freebsd-head/ · LEX · 1475 lines · 1049 code · 139 blank · 287 comment · 0 complexity · 96a6366d9419c4b2ccf27bc789942a0e MD5 · raw file

  1. %{
  2. /* $NetBSD: scan.l,v 1.26 2002/01/31 22:30:21 tv Exp $ */
  3. /*
  4. * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
  5. * Copyright (c) 1994, 1995 Jochen Pohl
  6. * All Rights Reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 3. All advertising materials mentioning features or use of this software
  17. * must display the following acknowledgement:
  18. * This product includes software developed by Jochen Pohl for
  19. * The NetBSD Project.
  20. * 4. The name of the author may not be used to endorse or promote products
  21. * derived from this software without specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  24. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  25. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  26. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  27. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  28. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  29. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  30. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  32. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include <sys/cdefs.h>
  35. #if defined(__RCSID) && !defined(lint)
  36. __RCSID("$NetBSD: scan.l,v 1.26 2002/01/31 22:30:21 tv Exp $");
  37. #endif
  38. __FBSDID("$FreeBSD$");
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <limits.h>
  42. #include <float.h>
  43. #include <ctype.h>
  44. #include <errno.h>
  45. #include <err.h>
  46. #include <math.h>
  47. #include "lint1.h"
  48. #include "cgram.h"
  49. #define CHAR_MASK (~(~0 << CHAR_BIT))
  50. #define YY_NO_UNPUT
  51. /* Current position (its also updated when an included file is parsed) */
  52. pos_t curr_pos = { 1, "", 0 };
  53. /*
  54. * Current position in C source (not updated when an included file is
  55. * parsed).
  56. */
  57. pos_t csrc_pos = { 1, "", 0 };
  58. static void incline(void);
  59. static void badchar(int);
  60. static sbuf_t *allocsb(void);
  61. static void freesb(sbuf_t *);
  62. static int inpc(void);
  63. static int hash(const char *);
  64. static sym_t *search(sbuf_t *);
  65. static int name(void);
  66. static int keyw(sym_t *);
  67. static int icon(int);
  68. static int fcon(void);
  69. static int operator(int, op_t);
  70. static int ccon(void);
  71. static int wccon(void);
  72. static int getescc(int);
  73. static void directive(void);
  74. static void comment(void);
  75. static void slashslashcomment(void);
  76. static int string(void);
  77. static int wcstrg(void);
  78. %}
  79. L [_A-Za-z]
  80. D [0-9]
  81. NZD [1-9]
  82. OD [0-7]
  83. HD [0-9A-Fa-f]
  84. EX ([eE][+-]?[0-9]+)
  85. %%
  86. {L}({L}|{D})* return (name());
  87. 0{OD}*[lLuU]* return (icon(8));
  88. {NZD}{D}*[lLuU]* return (icon(10));
  89. 0[xX]{HD}+[lLuU]* return (icon(16));
  90. {D}+\.{D}*{EX}?[fFlL]? |
  91. {D}+{EX}[fFlL]? |
  92. \.{D}+{EX}?[fFlL]? return (fcon());
  93. "=" return (operator(T_ASSIGN, ASSIGN));
  94. "*=" return (operator(T_OPASS, MULASS));
  95. "/=" return (operator(T_OPASS, DIVASS));
  96. "%=" return (operator(T_OPASS, MODASS));
  97. "+=" return (operator(T_OPASS, ADDASS));
  98. "-=" return (operator(T_OPASS, SUBASS));
  99. "<<=" return (operator(T_OPASS, SHLASS));
  100. ">>=" return (operator(T_OPASS, SHRASS));
  101. "&=" return (operator(T_OPASS, ANDASS));
  102. "^=" return (operator(T_OPASS, XORASS));
  103. "|=" return (operator(T_OPASS, ORASS));
  104. "||" return (operator(T_LOGOR, LOGOR));
  105. "&&" return (operator(T_LOGAND, LOGAND));
  106. "|" return (operator(T_OR, OR));
  107. "&" return (operator(T_AND, AND));
  108. "^" return (operator(T_XOR, XOR));
  109. "==" return (operator(T_EQOP, EQ));
  110. "!=" return (operator(T_EQOP, NE));
  111. "<" return (operator(T_RELOP, LT));
  112. ">" return (operator(T_RELOP, GT));
  113. "<=" return (operator(T_RELOP, LE));
  114. ">=" return (operator(T_RELOP, GE));
  115. "<<" return (operator(T_SHFTOP, SHL));
  116. ">>" return (operator(T_SHFTOP, SHR));
  117. "++" return (operator(T_INCDEC, INC));
  118. "--" return (operator(T_INCDEC, DEC));
  119. "->" return (operator(T_STROP, ARROW));
  120. "." return (operator(T_STROP, POINT));
  121. "+" return (operator(T_ADDOP, PLUS));
  122. "-" return (operator(T_ADDOP, MINUS));
  123. "*" return (operator(T_MULT, MULT));
  124. "/" return (operator(T_DIVOP, DIV));
  125. "%" return (operator(T_DIVOP, MOD));
  126. "!" return (operator(T_UNOP, NOT));
  127. "~" return (operator(T_UNOP, COMPL));
  128. "\"" return (string());
  129. "L\"" return (wcstrg());
  130. ";" return (T_SEMI);
  131. "{" return (T_LBRACE);
  132. "}" return (T_RBRACE);
  133. "," return (T_COMMA);
  134. ":" return (T_COLON);
  135. "?" return (T_QUEST);
  136. "[" return (T_LBRACK);
  137. "]" return (T_RBRACK);
  138. "(" return (T_LPARN);
  139. ")" return (T_RPARN);
  140. "..." return (T_ELLIPSE);
  141. "'" return (ccon());
  142. "L'" return (wccon());
  143. ^#.*$ directive();
  144. \n incline();
  145. \t|" "|\f|\v ;
  146. "/*" comment();
  147. "//" slashslashcomment();
  148. . badchar(yytext[0]);
  149. %%
  150. static void
  151. incline(void)
  152. {
  153. curr_pos.p_line++;
  154. curr_pos.p_uniq = 0;
  155. if (curr_pos.p_file == csrc_pos.p_file) {
  156. csrc_pos.p_line++;
  157. csrc_pos.p_uniq = 0;
  158. }
  159. }
  160. static void
  161. badchar(int c)
  162. {
  163. /* unknown character \%o */
  164. error(250, c);
  165. }
  166. /*
  167. * Keywords.
  168. * During initialisation they are written to the symbol table.
  169. */
  170. static struct kwtab {
  171. const char *kw_name; /* keyword */
  172. int kw_token; /* token returned by yylex() */
  173. scl_t kw_scl; /* storage class if kw_token T_SCLASS */
  174. tspec_t kw_tspec; /* type spec. if kw_token T_TYPE or T_SOU */
  175. tqual_t kw_tqual; /* type qual. fi kw_token T_QUAL */
  176. u_int kw_stdc : 1; /* STDC keyword */
  177. u_int kw_gcc : 1; /* GCC keyword */
  178. } kwtab[] = {
  179. { "asm", T_ASM, 0, 0, 0, 0, 1 },
  180. { "__asm", T_ASM, 0, 0, 0, 0, 0 },
  181. { "__asm__", T_ASM, 0, 0, 0, 0, 0 },
  182. { "auto", T_SCLASS, AUTO, 0, 0, 0, 0 },
  183. { "break", T_BREAK, 0, 0, 0, 0, 0 },
  184. { "case", T_CASE, 0, 0, 0, 0, 0 },
  185. { "char", T_TYPE, 0, CHAR, 0, 0, 0 },
  186. { "const", T_QUAL, 0, 0, CONST, 1, 0 },
  187. { "__const__", T_QUAL, 0, 0, CONST, 0, 0 },
  188. { "__const", T_QUAL, 0, 0, CONST, 0, 0 },
  189. { "continue", T_CONTINUE, 0, 0, 0, 0, 0 },
  190. { "default", T_DEFAULT, 0, 0, 0, 0, 0 },
  191. { "do", T_DO, 0, 0, 0, 0, 0 },
  192. { "double", T_TYPE, 0, DOUBLE, 0, 0, 0 },
  193. { "else", T_ELSE, 0, 0, 0, 0, 0 },
  194. { "enum", T_ENUM, 0, 0, 0, 0, 0 },
  195. { "extern", T_SCLASS, EXTERN, 0, 0, 0, 0 },
  196. { "float", T_TYPE, 0, FLOAT, 0, 0, 0 },
  197. { "for", T_FOR, 0, 0, 0, 0, 0 },
  198. { "goto", T_GOTO, 0, 0, 0, 0, 0 },
  199. { "if", T_IF, 0, 0, 0, 0, 0 },
  200. { "inline", T_SCLASS, INLINE, 0, 0, 0, 1 },
  201. { "__inline__", T_SCLASS, INLINE, 0, 0, 0, 0 },
  202. { "__inline", T_SCLASS, INLINE, 0, 0, 0, 0 },
  203. { "int", T_TYPE, 0, INT, 0, 0, 0 },
  204. { "__symbolrename", T_SYMBOLRENAME, 0, 0, 0, 0, 0 },
  205. { "long", T_TYPE, 0, LONG, 0, 0, 0 },
  206. { "register", T_SCLASS, REG, 0, 0, 0, 0 },
  207. { "return", T_RETURN, 0, 0, 0, 0, 0 },
  208. { "short", T_TYPE, 0, SHORT, 0, 0, 0 },
  209. { "signed", T_TYPE, 0, SIGNED, 0, 1, 0 },
  210. { "__signed__", T_TYPE, 0, SIGNED, 0, 0, 0 },
  211. { "__signed", T_TYPE, 0, SIGNED, 0, 0, 0 },
  212. { "sizeof", T_SIZEOF, 0, 0, 0, 0, 0 },
  213. { "static", T_SCLASS, STATIC, 0, 0, 0, 0 },
  214. { "struct", T_SOU, 0, STRUCT, 0, 0, 0 },
  215. { "switch", T_SWITCH, 0, 0, 0, 0, 0 },
  216. { "typedef", T_SCLASS, TYPEDEF, 0, 0, 0, 0 },
  217. { "union", T_SOU, 0, UNION, 0, 0, 0 },
  218. { "unsigned", T_TYPE, 0, UNSIGN, 0, 0, 0 },
  219. { "void", T_TYPE, 0, VOID, 0, 0, 0 },
  220. { "volatile", T_QUAL, 0, 0, VOLATILE, 1, 0 },
  221. { "__volatile__", T_QUAL, 0, 0, VOLATILE, 0, 0 },
  222. { "__volatile", T_QUAL, 0, 0, VOLATILE, 0, 0 },
  223. { "while", T_WHILE, 0, 0, 0, 0, 0 },
  224. { NULL, 0, 0, 0, 0, 0, 0 }
  225. };
  226. /* Symbol table */
  227. static sym_t *symtab[HSHSIZ1];
  228. /* bit i of the entry with index i is set */
  229. uint64_t qbmasks[sizeof(uint64_t) * CHAR_BIT];
  230. /* least significant i bits are set in the entry with index i */
  231. uint64_t qlmasks[sizeof(uint64_t) * CHAR_BIT + 1];
  232. /* least significant i bits are not set in the entry with index i */
  233. uint64_t qumasks[sizeof(uint64_t) * CHAR_BIT + 1];
  234. /* free list for sbuf structures */
  235. static sbuf_t *sbfrlst;
  236. /* Typ of next expected symbol */
  237. symt_t symtyp;
  238. /*
  239. * All keywords are written to the symbol table. This saves us looking
  240. * in an extra table for each name we found.
  241. */
  242. void
  243. initscan(void)
  244. {
  245. struct kwtab *kw;
  246. sym_t *sym;
  247. int h, i;
  248. uint64_t uq;
  249. for (kw = kwtab; kw->kw_name != NULL; kw++) {
  250. if (kw->kw_stdc && tflag)
  251. continue;
  252. if (kw->kw_gcc && !gflag)
  253. continue;
  254. sym = getblk(sizeof (sym_t));
  255. sym->s_name = kw->kw_name;
  256. sym->s_keyw = 1;
  257. sym->s_value.v_quad = kw->kw_token;
  258. if (kw->kw_token == T_TYPE || kw->kw_token == T_SOU) {
  259. sym->s_tspec = kw->kw_tspec;
  260. } else if (kw->kw_token == T_SCLASS) {
  261. sym->s_scl = kw->kw_scl;
  262. } else if (kw->kw_token == T_QUAL) {
  263. sym->s_tqual = kw->kw_tqual;
  264. }
  265. h = hash(sym->s_name);
  266. if ((sym->s_link = symtab[h]) != NULL)
  267. symtab[h]->s_rlink = &sym->s_link;
  268. (symtab[h] = sym)->s_rlink = &symtab[h];
  269. }
  270. /* initialize bit-masks for quads */
  271. for (i = 0; i < sizeof (uint64_t) * CHAR_BIT; i++) {
  272. qbmasks[i] = (uint64_t)1 << i;
  273. uq = ~(uint64_t)0 << i;
  274. qumasks[i] = uq;
  275. qlmasks[i] = ~uq;
  276. }
  277. qumasks[i] = 0;
  278. qlmasks[i] = ~(uint64_t)0;
  279. }
  280. /*
  281. * Get a free sbuf structure, if possible from the free list
  282. */
  283. static sbuf_t *
  284. allocsb(void)
  285. {
  286. sbuf_t *sb;
  287. if ((sb = sbfrlst) != NULL) {
  288. sbfrlst = sb->sb_nxt;
  289. } else {
  290. if ((sb = malloc(sizeof (sbuf_t))) == NULL)
  291. nomem();
  292. }
  293. (void)memset(sb, 0, sizeof (*sb));
  294. return (sb);
  295. }
  296. /*
  297. * Put a sbuf structure to the free list
  298. */
  299. static void
  300. freesb(sbuf_t *sb)
  301. {
  302. sb->sb_nxt = sbfrlst;
  303. sbfrlst = sb;
  304. }
  305. /*
  306. * Read a character and ensure that it is positive (except EOF).
  307. * Increment line count(s) if necessary.
  308. */
  309. static int
  310. inpc(void)
  311. {
  312. int c;
  313. if ((c = input()) != EOF && (c &= CHAR_MASK) == '\n')
  314. incline();
  315. return (c);
  316. }
  317. static int
  318. hash(const char *s)
  319. {
  320. u_int v;
  321. const u_char *us;
  322. v = 0;
  323. for (us = (const u_char *)s; *us != '\0'; us++) {
  324. v = (v << sizeof (v)) + *us;
  325. v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v));
  326. }
  327. return (v % HSHSIZ1);
  328. }
  329. /*
  330. * Lex has found a letter followed by zero or more letters or digits.
  331. * It looks for a symbol in the symbol table with the same name. This
  332. * symbol must either be a keyword or a symbol of the type required by
  333. * symtyp (label, member, tag, ...).
  334. *
  335. * If it is a keyword, the token is returned. In some cases it is described
  336. * more deeply by data written to yylval.
  337. *
  338. * If it is a symbol, T_NAME is returned and the pointer to a sbuf struct
  339. * is stored in yylval. This struct contains the name of the symbol, it's
  340. * length and hash value. If there is already a symbol of the same name
  341. * and type in the symbol table, the sbuf struct also contains a pointer
  342. * to the symbol table entry.
  343. */
  344. static int
  345. name(void)
  346. {
  347. char *s;
  348. sbuf_t *sb;
  349. sym_t *sym;
  350. int tok;
  351. sb = allocsb();
  352. sb->sb_name = yytext;
  353. sb->sb_len = yyleng;
  354. sb->sb_hash = hash(yytext);
  355. if ((sym = search(sb)) != NULL && sym->s_keyw) {
  356. freesb(sb);
  357. return (keyw(sym));
  358. }
  359. sb->sb_sym = sym;
  360. if (sym != NULL) {
  361. if (blklev < sym->s_blklev)
  362. lerror("name() 1");
  363. sb->sb_name = sym->s_name;
  364. sb->sb_len = strlen(sym->s_name);
  365. tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME;
  366. } else {
  367. s = getblk(yyleng + 1);
  368. (void)memcpy(s, yytext, yyleng + 1);
  369. sb->sb_name = s;
  370. sb->sb_len = yyleng;
  371. tok = T_NAME;
  372. }
  373. yylval.y_sb = sb;
  374. return (tok);
  375. }
  376. static sym_t *
  377. search(sbuf_t *sb)
  378. {
  379. sym_t *sym;
  380. for (sym = symtab[sb->sb_hash]; sym != NULL; sym = sym->s_link) {
  381. if (strcmp(sym->s_name, sb->sb_name) == 0) {
  382. if (sym->s_keyw || sym->s_kind == symtyp)
  383. return (sym);
  384. }
  385. }
  386. return (NULL);
  387. }
  388. static int
  389. keyw(sym_t *sym)
  390. {
  391. int t;
  392. if ((t = (int)sym->s_value.v_quad) == T_SCLASS) {
  393. yylval.y_scl = sym->s_scl;
  394. } else if (t == T_TYPE || t == T_SOU) {
  395. yylval.y_tspec = sym->s_tspec;
  396. } else if (t == T_QUAL) {
  397. yylval.y_tqual = sym->s_tqual;
  398. }
  399. return (t);
  400. }
  401. /*
  402. * Convert a string representing an integer into internal representation.
  403. * The value is returned in yylval. icon() (and yylex()) returns T_CON.
  404. */
  405. static int
  406. icon(int base)
  407. {
  408. int l_suffix, u_suffix;
  409. int len;
  410. const char *cp;
  411. char c, *eptr;
  412. tspec_t typ;
  413. u_long ul = 0;
  414. uint64_t uq = 0;
  415. int ansiu;
  416. static tspec_t contypes[2][3] = {
  417. { INT, LONG, QUAD },
  418. { UINT, ULONG, UQUAD }
  419. };
  420. cp = yytext;
  421. len = yyleng;
  422. /* skip 0x */
  423. if (base == 16) {
  424. cp += 2;
  425. len -= 2;
  426. }
  427. /* read suffixes */
  428. l_suffix = u_suffix = 0;
  429. for ( ; ; ) {
  430. if ((c = cp[len - 1]) == 'l' || c == 'L') {
  431. l_suffix++;
  432. } else if (c == 'u' || c == 'U') {
  433. u_suffix++;
  434. } else {
  435. break;
  436. }
  437. len--;
  438. }
  439. if (l_suffix > 2 || u_suffix > 1) {
  440. /* malformed integer constant */
  441. warning(251);
  442. if (l_suffix > 2)
  443. l_suffix = 2;
  444. if (u_suffix > 1)
  445. u_suffix = 1;
  446. }
  447. if (tflag && u_suffix != 0) {
  448. /* suffix U is illegal in traditional C */
  449. warning(97);
  450. }
  451. typ = contypes[u_suffix][l_suffix];
  452. errno = 0;
  453. if (l_suffix < 2) {
  454. ul = strtoul(cp, &eptr, base);
  455. } else {
  456. uq = strtouq(cp, &eptr, base);
  457. }
  458. if (eptr != cp + len)
  459. lerror("icon() 1");
  460. if (errno != 0)
  461. /* integer constant out of range */
  462. warning(252);
  463. /*
  464. * If the value is to big for the current type, we must choose
  465. * another type.
  466. */
  467. ansiu = 0;
  468. switch (typ) {
  469. case INT:
  470. if (ul <= INT_MAX) {
  471. /* ok */
  472. } else if (ul <= (unsigned)UINT_MAX && base != 10) {
  473. typ = UINT;
  474. } else if (ul <= LONG_MAX) {
  475. typ = LONG;
  476. } else {
  477. typ = ULONG;
  478. }
  479. if (typ == UINT || typ == ULONG) {
  480. if (tflag) {
  481. typ = LONG;
  482. } else if (!sflag) {
  483. /*
  484. * Remember that the constant is unsigned
  485. * only in ANSI C
  486. */
  487. ansiu = 1;
  488. }
  489. }
  490. break;
  491. case UINT:
  492. if (ul > (u_int)UINT_MAX)
  493. typ = ULONG;
  494. break;
  495. case LONG:
  496. if (ul > LONG_MAX && !tflag) {
  497. typ = ULONG;
  498. if (!sflag)
  499. ansiu = 1;
  500. }
  501. break;
  502. case QUAD:
  503. if (uq > QUAD_MAX && !tflag) {
  504. typ = UQUAD;
  505. if (!sflag)
  506. ansiu = 1;
  507. }
  508. break;
  509. /* LINTED (enumeration values not handled in switch) */
  510. case STRUCT:
  511. case VOID:
  512. case LDOUBLE:
  513. case FUNC:
  514. case ARRAY:
  515. case PTR:
  516. case ENUM:
  517. case UNION:
  518. case SIGNED:
  519. case NOTSPEC:
  520. case DOUBLE:
  521. case FLOAT:
  522. case UQUAD:
  523. case ULONG:
  524. case USHORT:
  525. case SHORT:
  526. case UCHAR:
  527. case SCHAR:
  528. case CHAR:
  529. case UNSIGN:
  530. break;
  531. }
  532. if (typ != QUAD && typ != UQUAD) {
  533. if (isutyp(typ)) {
  534. uq = ul;
  535. } else {
  536. uq = (int64_t)(long)ul;
  537. }
  538. }
  539. uq = (uint64_t)xsign((int64_t)uq, typ, -1);
  540. if ((yylval.y_val = calloc(1, sizeof(val_t))) == NULL)
  541. nomem();
  542. yylval.y_val->v_tspec = typ;
  543. yylval.y_val->v_ansiu = ansiu;
  544. yylval.y_val->v_quad = (int64_t)uq;
  545. return (T_CON);
  546. }
  547. /*
  548. * Returns 1 if t is a signed type and the value is negative.
  549. *
  550. * len is the number of significant bits. If len is -1, len is set
  551. * to the width of type t.
  552. */
  553. int
  554. sign(int64_t q, tspec_t t, int len)
  555. {
  556. if (t == PTR || isutyp(t))
  557. return (0);
  558. return (msb(q, t, len));
  559. }
  560. int
  561. msb(int64_t q, tspec_t t, int len)
  562. {
  563. if (len <= 0)
  564. len = size(t);
  565. return ((q & qbmasks[len - 1]) != 0);
  566. }
  567. /*
  568. * Extends the sign of q.
  569. */
  570. int64_t
  571. xsign(int64_t q, tspec_t t, int len)
  572. {
  573. if (len <= 0)
  574. len = size(t);
  575. if (t == PTR || isutyp(t) || !sign(q, t, len)) {
  576. q &= qlmasks[len];
  577. } else {
  578. q |= qumasks[len];
  579. }
  580. return (q);
  581. }
  582. /*
  583. * Convert a string representing a floating point value into its interal
  584. * representation. Type and value are returned in yylval. fcon()
  585. * (and yylex()) returns T_CON.
  586. * XXX Currently it is not possible to convert constants of type
  587. * long double which are greater than DBL_MAX.
  588. */
  589. static int
  590. fcon(void)
  591. {
  592. const char *cp;
  593. int len;
  594. tspec_t typ;
  595. char c, *eptr;
  596. double d;
  597. float f = 0;
  598. cp = yytext;
  599. len = yyleng;
  600. if ((c = cp[len - 1]) == 'f' || c == 'F') {
  601. typ = FLOAT;
  602. len--;
  603. } else if (c == 'l' || c == 'L') {
  604. typ = LDOUBLE;
  605. len--;
  606. } else {
  607. typ = DOUBLE;
  608. }
  609. if (tflag && typ != DOUBLE) {
  610. /* suffixes F and L are illegal in traditional C */
  611. warning(98);
  612. }
  613. errno = 0;
  614. d = strtod(cp, &eptr);
  615. if (eptr != cp + len)
  616. lerror("fcon() 1");
  617. if (errno != 0)
  618. /* floating-point constant out of range */
  619. warning(248);
  620. if (typ == FLOAT) {
  621. f = (float)d;
  622. if (!finite(f)) {
  623. /* floating-point constant out of range */
  624. warning(248);
  625. f = f > 0 ? FLT_MAX : -FLT_MAX;
  626. }
  627. }
  628. if ((yylval.y_val = calloc(1, sizeof (val_t))) == NULL)
  629. nomem();
  630. yylval.y_val->v_tspec = typ;
  631. if (typ == FLOAT) {
  632. yylval.y_val->v_ldbl = f;
  633. } else {
  634. yylval.y_val->v_ldbl = d;
  635. }
  636. return (T_CON);
  637. }
  638. static int
  639. operator(int t, op_t o)
  640. {
  641. yylval.y_op = o;
  642. return (t);
  643. }
  644. /*
  645. * Called if lex found a leading \'.
  646. */
  647. static int
  648. ccon(void)
  649. {
  650. int n, val, c;
  651. char cv;
  652. n = 0;
  653. val = 0;
  654. while ((c = getescc('\'')) >= 0) {
  655. val = (val << CHAR_BIT) + c;
  656. n++;
  657. }
  658. if (c == -2) {
  659. /* unterminated character constant */
  660. error(253);
  661. } else {
  662. if (n > sizeof (int) || (n > 1 && (pflag || hflag))) {
  663. /* too many characters in character constant */
  664. error(71);
  665. } else if (n > 1) {
  666. /* multi-character character constant */
  667. warning(294);
  668. } else if (n == 0) {
  669. /* empty character constant */
  670. error(73);
  671. }
  672. }
  673. if (n == 1) {
  674. cv = (char)val;
  675. val = cv;
  676. }
  677. yylval.y_val = xcalloc(1, sizeof (val_t));
  678. yylval.y_val->v_tspec = INT;
  679. yylval.y_val->v_quad = val;
  680. return (T_CON);
  681. }
  682. /*
  683. * Called if lex found a leading L\'
  684. */
  685. static int
  686. wccon(void)
  687. {
  688. static char buf[MB_LEN_MAX + 1];
  689. int i, c;
  690. wchar_t wc;
  691. i = 0;
  692. while ((c = getescc('\'')) >= 0) {
  693. if (i < MB_CUR_MAX)
  694. buf[i] = (char)c;
  695. i++;
  696. }
  697. wc = 0;
  698. if (c == -2) {
  699. /* unterminated character constant */
  700. error(253);
  701. } else if (c == 0) {
  702. /* empty character constant */
  703. error(73);
  704. } else {
  705. if (i > MB_CUR_MAX) {
  706. i = MB_CUR_MAX;
  707. /* too many characters in character constant */
  708. error(71);
  709. } else {
  710. buf[i] = '\0';
  711. (void)mbtowc(NULL, NULL, 0);
  712. if (mbtowc(&wc, buf, MB_CUR_MAX) < 0)
  713. /* invalid multibyte character */
  714. error(291);
  715. }
  716. }
  717. if ((yylval.y_val = calloc(1, sizeof (val_t))) == NULL)
  718. nomem();
  719. yylval.y_val->v_tspec = WCHAR;
  720. yylval.y_val->v_quad = wc;
  721. return (T_CON);
  722. }
  723. /*
  724. * Read a character which is part of a character constant or of a string
  725. * and handle escapes.
  726. *
  727. * The Argument is the character which delimits the character constant or
  728. * string.
  729. *
  730. * Returns -1 if the end of the character constant or string is reached,
  731. * -2 if the EOF is reached, and the character otherwise.
  732. */
  733. static int
  734. getescc(int d)
  735. {
  736. static int pbc = -1;
  737. int n, c, v;
  738. if (pbc == -1) {
  739. c = inpc();
  740. } else {
  741. c = pbc;
  742. pbc = -1;
  743. }
  744. if (c == d)
  745. return (-1);
  746. switch (c) {
  747. case '\n':
  748. if (tflag) {
  749. /* newline in string or char constant */
  750. error(254);
  751. return (-2);
  752. }
  753. return (c);
  754. case EOF:
  755. return (-2);
  756. case '\\':
  757. switch (c = inpc()) {
  758. case '"':
  759. if (tflag && d == '\'')
  760. /* \" inside character constant undef. ... */
  761. warning(262);
  762. return ('"');
  763. case '\'':
  764. return ('\'');
  765. case '?':
  766. if (tflag)
  767. /* \? undefined in traditional C */
  768. warning(263);
  769. return ('?');
  770. case '\\':
  771. return ('\\');
  772. case 'a':
  773. if (tflag)
  774. /* \a undefined in traditional C */
  775. warning(81);
  776. return ('\a');
  777. case 'b':
  778. return ('\b');
  779. case 'f':
  780. return ('\f');
  781. case 'n':
  782. return ('\n');
  783. case 'r':
  784. return ('\r');
  785. case 't':
  786. return ('\t');
  787. case 'v':
  788. if (tflag)
  789. /* \v undefined in traditional C */
  790. warning(264);
  791. return ('\v');
  792. case '8': case '9':
  793. /* bad octal digit %c */
  794. warning(77, c);
  795. /* FALLTHROUGH */
  796. case '0': case '1': case '2': case '3':
  797. case '4': case '5': case '6': case '7':
  798. n = 3;
  799. v = 0;
  800. do {
  801. v = (v << 3) + (c - '0');
  802. c = inpc();
  803. } while (--n && isdigit(c) && (tflag || c <= '7'));
  804. if (tflag && n > 0 && isdigit(c))
  805. /* bad octal digit %c */
  806. warning(77, c);
  807. pbc = c;
  808. if (v > UCHAR_MAX) {
  809. /* character escape does not fit in char. */
  810. warning(76);
  811. v &= CHAR_MASK;
  812. }
  813. return (v);
  814. case 'x':
  815. if (tflag)
  816. /* \x undefined in traditional C */
  817. warning(82);
  818. v = 0;
  819. n = 0;
  820. while ((c = inpc()) >= 0 && isxdigit(c)) {
  821. c = isdigit(c) ?
  822. c - '0' : toupper(c) - 'A' + 10;
  823. v = (v << 4) + c;
  824. if (n >= 0) {
  825. if ((v & ~CHAR_MASK) != 0) {
  826. /* overflow in hex escape */
  827. warning(75);
  828. n = -1;
  829. } else {
  830. n++;
  831. }
  832. }
  833. }
  834. pbc = c;
  835. if (n == 0) {
  836. /* no hex digits follow \x */
  837. error(74);
  838. } if (n == -1) {
  839. v &= CHAR_MASK;
  840. }
  841. return (v);
  842. case '\n':
  843. return (getescc(d));
  844. case EOF:
  845. return (-2);
  846. default:
  847. if (isprint(c)) {
  848. /* dubious escape \%c */
  849. warning(79, c);
  850. } else {
  851. /* dubious escape \%o */
  852. warning(80, c);
  853. }
  854. }
  855. }
  856. return (c);
  857. }
  858. /*
  859. * Called for preprocessor directives. Currently implemented are:
  860. * # lineno
  861. * # lineno "filename"
  862. */
  863. static void
  864. directive(void)
  865. {
  866. const char *cp, *fn;
  867. char c, *eptr;
  868. size_t fnl;
  869. long ln;
  870. static int first = 1;
  871. /* Go to first non-whitespace after # */
  872. for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++)
  873. continue;
  874. if (!isdigit((unsigned char)c)) {
  875. error:
  876. /* undefined or invalid # directive */
  877. warning(255);
  878. return;
  879. }
  880. ln = strtol(--cp, &eptr, 10);
  881. if (cp == eptr)
  882. goto error;
  883. if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0')
  884. goto error;
  885. while ((c = *cp++) == ' ' || c == '\t')
  886. continue;
  887. if (c != '\0') {
  888. if (c != '"')
  889. goto error;
  890. fn = cp;
  891. while ((c = *cp) != '"' && c != '\0')
  892. cp++;
  893. if (c != '"')
  894. goto error;
  895. if ((fnl = cp++ - fn) > PATH_MAX)
  896. goto error;
  897. while ((c = *cp++) == ' ' || c == '\t')
  898. continue;
  899. #if 0
  900. if (c != '\0')
  901. warning("extra character(s) after directive");
  902. #endif
  903. /* empty string means stdin */
  904. if (fnl == 0) {
  905. fn = "{standard input}";
  906. fnl = 16; /* strlen (fn) */
  907. }
  908. curr_pos.p_file = fnnalloc(fn, fnl);
  909. /*
  910. * If this is the first directive, the name is the name
  911. * of the C source file as specified at the command line.
  912. * It is written to the output file.
  913. */
  914. if (first) {
  915. csrc_pos.p_file = curr_pos.p_file;
  916. outsrc(curr_pos.p_file);
  917. first = 0;
  918. }
  919. }
  920. curr_pos.p_line = (int)ln - 1;
  921. curr_pos.p_uniq = 0;
  922. if (curr_pos.p_file == csrc_pos.p_file) {
  923. csrc_pos.p_line = (int)ln - 1;
  924. csrc_pos.p_uniq = 0;
  925. }
  926. }
  927. /*
  928. * Handle lint comments. Following comments are currently understood:
  929. * ARGSUSEDn
  930. * BITFIELDTYPE
  931. * CONSTCOND CONSTANTCOND CONSTANTCONDITION
  932. * FALLTHRU FALLTHROUGH
  933. * LINTLIBRARY
  934. * LINTED NOSTRICT
  935. * LONGLONG
  936. * NOTREACHED
  937. * PRINTFLIKEn
  938. * PROTOLIB
  939. * SCANFLIKEn
  940. * VARARGSn
  941. * If one of this comments is recognized, the arguments, if any, are
  942. * parsed and a function which handles this comment is called.
  943. */
  944. static void
  945. comment(void)
  946. {
  947. int c, lc;
  948. static struct {
  949. const char *keywd;
  950. int arg;
  951. void (*func)(int);
  952. } keywtab[] = {
  953. { "ARGSUSED", 1, argsused },
  954. { "BITFIELDTYPE", 0, bitfieldtype },
  955. { "CONSTCOND", 0, constcond },
  956. { "CONSTANTCOND", 0, constcond },
  957. { "CONSTANTCONDITION", 0, constcond },
  958. { "FALLTHRU", 0, fallthru },
  959. { "FALLTHROUGH", 0, fallthru },
  960. { "LINTLIBRARY", 0, lintlib },
  961. { "LINTED", 0, linted },
  962. { "LONGLONG", 0, longlong },
  963. { "NOSTRICT", 0, linted },
  964. { "NOTREACHED", 0, notreach },
  965. { "PRINTFLIKE", 1, printflike },
  966. { "PROTOLIB", 1, protolib },
  967. { "SCANFLIKE", 1, scanflike },
  968. { "VARARGS", 1, varargs },
  969. };
  970. char keywd[32];
  971. char arg[32];
  972. int l, i, a;
  973. int eoc;
  974. eoc = 0;
  975. /* Skip white spaces after the start of the comment */
  976. while ((c = inpc()) != EOF && isspace(c))
  977. continue;
  978. /* Read the potential keyword to keywd */
  979. l = 0;
  980. while (c != EOF && isupper(c) && l < sizeof (keywd) - 1) {
  981. keywd[l++] = (char)c;
  982. c = inpc();
  983. }
  984. keywd[l] = '\0';
  985. /* look for the keyword */
  986. for (i = 0; i < sizeof (keywtab) / sizeof (keywtab[0]); i++) {
  987. if (strcmp(keywtab[i].keywd, keywd) == 0)
  988. break;
  989. }
  990. if (i == sizeof (keywtab) / sizeof (keywtab[0]))
  991. goto skip_rest;
  992. /* skip white spaces after the keyword */
  993. while (c != EOF && isspace(c))
  994. c = inpc();
  995. /* read the argument, if the keyword accepts one and there is one */
  996. l = 0;
  997. if (keywtab[i].arg) {
  998. while (c != EOF && isdigit(c) && l < sizeof (arg) - 1) {
  999. arg[l++] = (char)c;
  1000. c = inpc();
  1001. }
  1002. }
  1003. arg[l] = '\0';
  1004. a = l != 0 ? atoi(arg) : -1;
  1005. /* skip white spaces after the argument */
  1006. while (c != EOF && isspace(c))
  1007. c = inpc();
  1008. if (c != '*' || (c = inpc()) != '/') {
  1009. if (keywtab[i].func != linted)
  1010. /* extra characters in lint comment */
  1011. warning(257);
  1012. } else {
  1013. /*
  1014. * remember that we have already found the end of the
  1015. * comment
  1016. */
  1017. eoc = 1;
  1018. }
  1019. if (keywtab[i].func != NULL)
  1020. (*keywtab[i].func)(a);
  1021. skip_rest:
  1022. while (!eoc) {
  1023. lc = c;
  1024. if ((c = inpc()) == EOF) {
  1025. /* unterminated comment */
  1026. error(256);
  1027. break;
  1028. }
  1029. if (lc == '*' && c == '/')
  1030. eoc = 1;
  1031. }
  1032. }
  1033. /*
  1034. * Handle // style comments
  1035. */
  1036. static void
  1037. slashslashcomment(void)
  1038. {
  1039. int c;
  1040. if (sflag < 2 && !gflag)
  1041. /* // comments only supported in C99 */
  1042. (void)gnuism(312, tflag ? "traditional" : "ANSI");
  1043. while ((c = inpc()) != EOF && c != '\n')
  1044. continue;
  1045. }
  1046. /*
  1047. * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND.
  1048. * clrwflgs() is called after function definitions and global and
  1049. * local declarations and definitions. It is also called between
  1050. * the controlling expression and the body of control statements
  1051. * (if, switch, for, while).
  1052. */
  1053. void
  1054. clrwflgs(void)
  1055. {
  1056. nowarn = 0;
  1057. quadflg = 0;
  1058. ccflg = 0;
  1059. }
  1060. /*
  1061. * Strings are stored in a dynamically alloceted buffer and passed
  1062. * in yylval.y_xstrg to the parser. The parser or the routines called
  1063. * by the parser are responsible for freeing this buffer.
  1064. */
  1065. static int
  1066. string(void)
  1067. {
  1068. u_char *s;
  1069. int c;
  1070. size_t len, max;
  1071. strg_t *strg;
  1072. if ((s = malloc(max = 64)) == NULL)
  1073. nomem();
  1074. len = 0;
  1075. while ((c = getescc('"')) >= 0) {
  1076. /* +1 to reserve space for a trailing NUL character */
  1077. if (len + 1 == max)
  1078. if ((s = realloc(s, max *= 2)) == NULL)
  1079. nomem();
  1080. s[len++] = (char)c;
  1081. }
  1082. s[len] = '\0';
  1083. if (c == -2)
  1084. /* unterminated string constant */
  1085. error(258);
  1086. if ((strg = calloc(1, sizeof (strg_t))) == NULL)
  1087. nomem();
  1088. strg->st_tspec = CHAR;
  1089. strg->st_len = len;
  1090. strg->st_cp = s;
  1091. yylval.y_strg = strg;
  1092. return (T_STRING);
  1093. }
  1094. static int
  1095. wcstrg(void)
  1096. {
  1097. char *s;
  1098. int c, i, n, wi;
  1099. size_t len, max, wlen;
  1100. wchar_t *ws;
  1101. strg_t *strg;
  1102. if ((s = malloc(max = 64)) == NULL)
  1103. nomem();
  1104. len = 0;
  1105. while ((c = getescc('"')) >= 0) {
  1106. /* +1 to save space for a trailing NUL character */
  1107. if (len + 1 >= max)
  1108. if ((s = realloc(s, max *= 2)) == NULL)
  1109. nomem();
  1110. s[len++] = (char)c;
  1111. }
  1112. s[len] = '\0';
  1113. if (c == -2)
  1114. /* unterminated string constant */
  1115. error(258);
  1116. /* get length of wide character string */
  1117. (void)mblen(NULL, 0);
  1118. for (i = 0, wlen = 0; i < len; i += n, wlen++) {
  1119. if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) {
  1120. /* invalid multibyte character */
  1121. error(291);
  1122. break;
  1123. }
  1124. if (n == 0)
  1125. n = 1;
  1126. }
  1127. if ((ws = malloc((wlen + 1) * sizeof (wchar_t))) == NULL)
  1128. nomem();
  1129. /* convert from multibyte to wide char */
  1130. (void)mbtowc(NULL, NULL, 0);
  1131. for (i = 0, wi = 0; i < len; i += n, wi++) {
  1132. if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1)
  1133. break;
  1134. if (n == 0)
  1135. n = 1;
  1136. }
  1137. ws[wi] = 0;
  1138. free(s);
  1139. if ((strg = calloc(1, sizeof (strg_t))) == NULL)
  1140. nomem();
  1141. strg->st_tspec = WCHAR;
  1142. strg->st_len = wlen;
  1143. strg->st_wcp = ws;
  1144. yylval.y_strg = strg;
  1145. return (T_STRING);
  1146. }
  1147. /*
  1148. * As noted above the scanner does not create new symbol table entries
  1149. * for symbols it cannot find in the symbol table. This is to avoid
  1150. * putting undeclared symbols into the symbol table if a syntax error
  1151. * occurs.
  1152. *
  1153. * getsym() is called as soon as it is probably ok to put the symbol to
  1154. * the symbol table. This does not mean that it is not possible that
  1155. * symbols are put to the symbol table which are than not completely
  1156. * declared due to syntax errors. To avoid too many problems in this
  1157. * case symbols get type int in getsym().
  1158. *
  1159. * XXX calls to getsym() should be delayed until decl1*() is called
  1160. */
  1161. sym_t *
  1162. getsym(sbuf_t *sb)
  1163. {
  1164. dinfo_t *di;
  1165. char *s;
  1166. sym_t *sym;
  1167. sym = sb->sb_sym;
  1168. /*
  1169. * During member declaration it is possible that name() looked
  1170. * for symbols of type FVFT, although it should have looked for
  1171. * symbols of type FTAG. Same can happen for labels. Both cases
  1172. * are compensated here.
  1173. */
  1174. if (symtyp == FMOS || symtyp == FLAB) {
  1175. if (sym == NULL || sym->s_kind == FVFT)
  1176. sym = search(sb);
  1177. }
  1178. if (sym != NULL) {
  1179. if (sym->s_kind != symtyp)
  1180. lerror("storesym() 1");
  1181. symtyp = FVFT;
  1182. freesb(sb);
  1183. return (sym);
  1184. }
  1185. /* create a new symbol table entry */
  1186. /* labels must always be allocated at level 1 (outhermost block) */
  1187. if (symtyp == FLAB) {
  1188. sym = getlblk(1, sizeof (sym_t));
  1189. s = getlblk(1, sb->sb_len + 1);
  1190. (void)memcpy(s, sb->sb_name, sb->sb_len + 1);
  1191. sym->s_name = s;
  1192. sym->s_blklev = 1;
  1193. di = dcs;
  1194. while (di->d_nxt != NULL && di->d_nxt->d_nxt != NULL)
  1195. di = di->d_nxt;
  1196. if (di->d_ctx != AUTO)
  1197. lerror("storesym() 2");
  1198. } else {
  1199. sym = getblk(sizeof (sym_t));
  1200. sym->s_name = sb->sb_name;
  1201. sym->s_blklev = blklev;
  1202. di = dcs;
  1203. }
  1204. UNIQUE_CURR_POS(sym->s_dpos);
  1205. if ((sym->s_kind = symtyp) != FLAB)
  1206. sym->s_type = gettyp(INT);
  1207. symtyp = FVFT;
  1208. if ((sym->s_link = symtab[sb->sb_hash]) != NULL)
  1209. symtab[sb->sb_hash]->s_rlink = &sym->s_link;
  1210. (symtab[sb->sb_hash] = sym)->s_rlink = &symtab[sb->sb_hash];
  1211. *di->d_ldlsym = sym;
  1212. di->d_ldlsym = &sym->s_dlnxt;
  1213. freesb(sb);
  1214. return (sym);
  1215. }
  1216. /*
  1217. * Remove a symbol forever from the symbol table. s_blklev
  1218. * is set to -1 to avoid that the symbol will later be put
  1219. * back to the symbol table.
  1220. */
  1221. void
  1222. rmsym(sym_t *sym)
  1223. {
  1224. if ((*sym->s_rlink = sym->s_link) != NULL)
  1225. sym->s_link->s_rlink = sym->s_rlink;
  1226. sym->s_blklev = -1;
  1227. sym->s_link = NULL;
  1228. }
  1229. /*
  1230. * Remove a list of symbols declared at one level from the symbol
  1231. * table.
  1232. */
  1233. void
  1234. rmsyms(sym_t *syms)
  1235. {
  1236. sym_t *sym;
  1237. for (sym = syms; sym != NULL; sym = sym->s_dlnxt) {
  1238. if (sym->s_blklev != -1) {
  1239. if ((*sym->s_rlink = sym->s_link) != NULL)
  1240. sym->s_link->s_rlink = sym->s_rlink;
  1241. sym->s_link = NULL;
  1242. sym->s_rlink = NULL;
  1243. }
  1244. }
  1245. }
  1246. /*
  1247. * Put a symbol into the symbol table
  1248. */
  1249. void
  1250. inssym(int bl, sym_t *sym)
  1251. {
  1252. int h;
  1253. h = hash(sym->s_name);
  1254. if ((sym->s_link = symtab[h]) != NULL)
  1255. symtab[h]->s_rlink = &sym->s_link;
  1256. (symtab[h] = sym)->s_rlink = &symtab[h];
  1257. sym->s_blklev = bl;
  1258. if (sym->s_link != NULL && sym->s_blklev < sym->s_link->s_blklev)
  1259. lerror("inssym()");
  1260. }
  1261. /*
  1262. * Called at level 0 after syntax errors
  1263. * Removes all symbols which are not declared at level 0 from the
  1264. * symbol table. Also frees all memory which is not associated with
  1265. * level 0.
  1266. */
  1267. void
  1268. cleanup(void)
  1269. {
  1270. sym_t *sym, *nsym;
  1271. int i;
  1272. for (i = 0; i < HSHSIZ1; i++) {
  1273. for (sym = symtab[i]; sym != NULL; sym = nsym) {
  1274. nsym = sym->s_link;
  1275. if (sym->s_blklev >= 1) {
  1276. if ((*sym->s_rlink = nsym) != NULL)
  1277. nsym->s_rlink = sym->s_rlink;
  1278. }
  1279. }
  1280. }
  1281. for (i = mblklev; i > 0; i--)
  1282. freelblk(i);
  1283. }
  1284. /*
  1285. * Create a new symbol with the name of an existing symbol.
  1286. */
  1287. sym_t *
  1288. pushdown(sym_t *sym)
  1289. {
  1290. int h;
  1291. sym_t *nsym;
  1292. h = hash(sym->s_name);
  1293. nsym = getblk(sizeof (sym_t));
  1294. if (sym->s_blklev > blklev)
  1295. lerror("pushdown()");
  1296. nsym->s_name = sym->s_name;
  1297. UNIQUE_CURR_POS(nsym->s_dpos);
  1298. nsym->s_kind = sym->s_kind;
  1299. nsym->s_blklev = blklev;
  1300. if ((nsym->s_link = symtab[h]) != NULL)
  1301. symtab[h]->s_rlink = &nsym->s_link;
  1302. (symtab[h] = nsym)->s_rlink = &symtab[h];
  1303. *dcs->d_ldlsym = nsym;
  1304. dcs->d_ldlsym = &nsym->s_dlnxt;
  1305. return (nsym);
  1306. }
  1307. /*
  1308. * Free any dynamically allocated memory referenced by
  1309. * the value stack or yylval.
  1310. * The type of information in yylval is described by tok.
  1311. */
  1312. void
  1313. freeyyv(void *sp, int tok)
  1314. {
  1315. if (tok == T_NAME || tok == T_TYPENAME) {
  1316. sbuf_t *sb = *(sbuf_t **)sp;
  1317. freesb(sb);
  1318. } else if (tok == T_CON) {
  1319. val_t *val = *(val_t **)sp;
  1320. free(val);
  1321. } else if (tok == T_STRING) {
  1322. strg_t *strg = *(strg_t **)sp;
  1323. if (strg->st_tspec == CHAR) {
  1324. free(strg->st_cp);
  1325. } else if (strg->st_tspec == WCHAR) {
  1326. free(strg->st_wcp);
  1327. } else {
  1328. lerror("fryylv() 1");
  1329. }
  1330. free(strg);
  1331. }
  1332. }