[BACK]Return to scan.l CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / xlint / lint1

Annotation of src/usr.bin/xlint/lint1/scan.l, Revision 1.85

1.1       cgd         1: %{
1.85    ! christos    2: /* $NetBSD: scan.l,v 1.84 2018/10/07 14:20:01 christos Exp $ */
1.2       cgd         3:
1.1       cgd         4: /*
1.9       cgd         5:  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
1.1       cgd         6:  * Copyright (c) 1994, 1995 Jochen Pohl
                      7:  * All Rights Reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *      This product includes software developed by Jochen Pohl for
                     20:  *      The NetBSD Project.
                     21:  * 4. The name of the author may not be used to endorse or promote products
                     22:  *    derived from this software without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     25:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     26:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     27:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     28:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     29:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     30:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     31:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     32:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     33:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     34:  */
                     35:
1.11      christos   36: #include <sys/cdefs.h>
1.25      tv         37: #if defined(__RCSID) && !defined(lint)
1.85    ! christos   38: __RCSID("$NetBSD: scan.l,v 1.84 2018/10/07 14:20:01 christos Exp $");
1.1       cgd        39: #endif
                     40:
                     41: #include <stdlib.h>
                     42: #include <string.h>
                     43: #include <limits.h>
                     44: #include <float.h>
                     45: #include <ctype.h>
                     46: #include <errno.h>
                     47: #include <math.h>
                     48:
                     49: #include "lint1.h"
1.12      tv         50: #include "cgram.h"
1.1       cgd        51:
1.61      joerg      52: #define CHAR_MASK      ((int)(~(~0U << CHAR_BIT)))
1.1       cgd        53:
                     54: /* Current position (its also updated when an included file is parsed) */
1.9       cgd        55: pos_t  curr_pos = { 1, "", 0 };
1.1       cgd        56:
                     57: /*
                     58:  * Current position in C source (not updated when an included file is
                     59:  * parsed).
                     60:  */
1.9       cgd        61: pos_t  csrc_pos = { 1, "", 0 };
1.1       cgd        62:
1.55      christos   63: /* Are we parsing a gcc attribute? */
                     64: int attron;
                     65:
1.19      lukem      66: static void    incline(void);
                     67: static void    badchar(int);
                     68: static sbuf_t  *allocsb(void);
                     69: static void    freesb(sbuf_t *);
                     70: static int     inpc(void);
                     71: static int     hash(const char *);
                     72: static sym_t   *search(sbuf_t *);
                     73: static int     name(void);
                     74: static int     keyw(sym_t *);
                     75: static int     icon(int);
                     76: static int     fcon(void);
                     77: static int     operator(int, op_t);
                     78: static int     ccon(void);
                     79: static int     wccon(void);
                     80: static int     getescc(int);
                     81: static void    directive(void);
                     82: static void    comment(void);
                     83: static void    slashslashcomment(void);
                     84: static int     string(void);
                     85: static int     wcstrg(void);
1.1       cgd        86:
                     87: %}
                     88:
1.62      christos   89:
1.1       cgd        90: L      [_A-Za-z]
                     91: D      [0-9]
                     92: NZD    [1-9]
1.62      christos   93: BD     [0-1]
1.1       cgd        94: OD     [0-7]
                     95: HD     [0-9A-Fa-f]
                     96: EX     ([eE][+-]?[0-9]+)
1.47      christos   97: HX     (p[+-]?[0-9A-Fa-f]+)
                     98: TL     ([fFlL]?[i]?)
1.1       cgd        99:
1.46      christos  100: %option nounput
                    101:
1.1       cgd       102: %%
                    103:
                    104: {L}({L}|{D})*                  return (name());
1.62      christos  105: 0[bB]{BD}+[lLuU]*              return (icon(2));
1.1       cgd       106: 0{OD}*[lLuU]*                  return (icon(8));
                    107: {NZD}{D}*[lLuU]*               return (icon(10));
                    108: 0[xX]{HD}+[lLuU]*              return (icon(16));
1.47      christos  109: {D}+\.{D}*{EX}?{TL}    |
                    110: {D}+{EX}{TL}           |
                    111: 0[xX]{HD}+\.{HD}*{HX}{TL} |
                    112: 0[xX]{HD}+{HX}{TL}     |
                    113: \.{D}+{EX}?{TL}                return (fcon());
1.1       cgd       114: "="                            return (operator(T_ASSIGN, ASSIGN));
                    115: "*="                           return (operator(T_OPASS, MULASS));
                    116: "/="                           return (operator(T_OPASS, DIVASS));
                    117: "%="                           return (operator(T_OPASS, MODASS));
                    118: "+="                           return (operator(T_OPASS, ADDASS));
                    119: "-="                           return (operator(T_OPASS, SUBASS));
                    120: "<<="                          return (operator(T_OPASS, SHLASS));
                    121: ">>="                          return (operator(T_OPASS, SHRASS));
                    122: "&="                           return (operator(T_OPASS, ANDASS));
                    123: "^="                           return (operator(T_OPASS, XORASS));
                    124: "|="                           return (operator(T_OPASS, ORASS));
                    125: "||"                           return (operator(T_LOGOR, LOGOR));
                    126: "&&"                           return (operator(T_LOGAND, LOGAND));
                    127: "|"                            return (operator(T_OR, OR));
                    128: "&"                            return (operator(T_AND, AND));
                    129: "^"                            return (operator(T_XOR, XOR));
                    130: "=="                           return (operator(T_EQOP, EQ));
                    131: "!="                           return (operator(T_EQOP, NE));
                    132: "<"                            return (operator(T_RELOP, LT));
                    133: ">"                            return (operator(T_RELOP, GT));
                    134: "<="                           return (operator(T_RELOP, LE));
                    135: ">="                           return (operator(T_RELOP, GE));
                    136: "<<"                           return (operator(T_SHFTOP, SHL));
                    137: ">>"                           return (operator(T_SHFTOP, SHR));
                    138: "++"                           return (operator(T_INCDEC, INC));
                    139: "--"                           return (operator(T_INCDEC, DEC));
                    140: "->"                           return (operator(T_STROP, ARROW));
                    141: "."                            return (operator(T_STROP, POINT));
                    142: "+"                            return (operator(T_ADDOP, PLUS));
                    143: "-"                            return (operator(T_ADDOP, MINUS));
                    144: "*"                            return (operator(T_MULT, MULT));
                    145: "/"                            return (operator(T_DIVOP, DIV));
                    146: "%"                            return (operator(T_DIVOP, MOD));
                    147: "!"                            return (operator(T_UNOP, NOT));
                    148: "~"                            return (operator(T_UNOP, COMPL));
                    149: "\""                           return (string());
                    150: "L\""                          return (wcstrg());
                    151: ";"                            return (T_SEMI);
                    152: "{"                            return (T_LBRACE);
                    153: "}"                            return (T_RBRACE);
                    154: ","                            return (T_COMMA);
                    155: ":"                            return (T_COLON);
                    156: "?"                            return (T_QUEST);
                    157: "["                            return (T_LBRACK);
                    158: "]"                            return (T_RBRACK);
                    159: "("                            return (T_LPARN);
                    160: ")"                            return (T_RPARN);
                    161: "..."                          return (T_ELLIPSE);
                    162: "'"                            return (ccon());
                    163: "L'"                           return (wccon());
                    164: ^#.*$                          directive();
                    165: \n                             incline();
                    166: \t|" "|\f|\v                   ;
                    167: "/*"                           comment();
1.18      lukem     168: "//"                           slashslashcomment();
1.1       cgd       169: .                              badchar(yytext[0]);
                    170:
                    171: %%
                    172:
                    173: static void
1.19      lukem     174: incline(void)
1.1       cgd       175: {
                    176:        curr_pos.p_line++;
1.9       cgd       177:        curr_pos.p_uniq = 0;
                    178:        if (curr_pos.p_file == csrc_pos.p_file) {
1.1       cgd       179:                csrc_pos.p_line++;
1.9       cgd       180:                csrc_pos.p_uniq = 0;
                    181:        }
1.1       cgd       182: }
                    183:
                    184: static void
1.19      lukem     185: badchar(int c)
1.1       cgd       186: {
1.19      lukem     187:
1.1       cgd       188:        /* unknown character \%o */
                    189:        error(250, c);
                    190: }
                    191:
                    192: /*
                    193:  * Keywords.
                    194:  * During initialisation they are written to the symbol table.
                    195:  */
                    196: static struct  kwtab {
                    197:        const   char *kw_name;  /* keyword */
                    198:        int     kw_token;       /* token returned by yylex() */
                    199:        scl_t   kw_scl;         /* storage class if kw_token T_SCLASS */
                    200:        tspec_t kw_tspec;       /* type spec. if kw_token T_TYPE or T_SOU */
                    201:        tqual_t kw_tqual;       /* type qual. fi kw_token T_QUAL */
1.55      christos  202:        u_int   kw_c89 : 1;     /* c89 keyword */
                    203:        u_int   kw_c99 : 1;     /* c99 keyword */
                    204:        u_int   kw_gcc : 1;     /* GCC keyword */
                    205:        u_int   kw_attr : 1;    /* GCC attribute, keyword */
1.73      christos  206:        u_int   kw_deco : 3;    /* name[1] __name[2] __name__[4] */
1.1       cgd       207: } kwtab[] = {
1.83      christos  208: #ifdef INT128_SIZE
                    209:        { "__int128_t", T_TYPE,         0,      INT128, 0,        0,1,0,0,1 },
                    210:        { "__uint128_t",T_TYPE,         0,      UINT128,0,        0,1,0,0,1 },
                    211: #endif
1.73      christos  212:        { "_Bool",      T_TYPE,         0,      BOOL,   0,        0,1,0,0,1 },
                    213:        { "_Complex",   T_TYPE,         0,      COMPLEX,0,        0,1,0,0,1 },
                    214:        { "_Generic",   T_GENERIC,      0,      0,      0,        0,1,0,0,1 },
1.80      christos  215:        { "_Noreturn",  T_NORETURN,     0,      0,      0,        0,1,0,0,1 },
1.73      christos  216:        { "alias",      T_AT_ALIAS,     0,      0,      0,        0,0,1,1,5 },
                    217:        { "aligned",    T_AT_ALIGNED,   0,      0,      0,        0,0,1,1,5 },
                    218:        { "alignof",    T_ALIGNOF,      0,      0,      0,        0,0,0,0,4 },
                    219:        { "always_inline", T_AT_ALWAYS_INLINE, 0,0,     0,        0,0,1,1,5 },
                    220:        { "asm",        T_ASM,          0,      0,      0,        0,0,1,0,7 },
                    221:        { "attribute",  T_ATTRIBUTE,    0,      0,      0,        0,0,1,0,6 },
                    222:        { "auto",       T_SCLASS,       AUTO,   0,      0,        0,0,0,0,1 },
1.75      christos  223:        { "bounded",    T_AT_BOUNDED,   0,      0,      0,        0,0,1,1,5 },
1.73      christos  224:        { "break",      T_BREAK,        0,      0,      0,        0,0,0,0,1 },
1.76      christos  225:        { "buffer",     T_AT_BUFFER,    0,      0,      0,        0,0,1,1,5 },
1.79      christos  226:        { "builtin_offsetof", T_BUILTIN_OFFSETOF, 0, 0, 0,        0,0,1,0,2 },
1.73      christos  227:        { "case",       T_CASE,         0,      0,      0,        0,0,0,0,1 },
                    228:        { "char",       T_TYPE,         0,      CHAR,   0,        0,0,0,0,1 },
                    229:        { "cold",       T_AT_COLD,      0,      0,      0,        0,0,1,1,5 },
                    230:        { "const",      T_QUAL,         0,      0,      CONST,    1,0,0,0,7 },
                    231:        { "constructor",T_AT_CONSTRUCTOR,0,     0,      0,        0,0,1,1,5 },
                    232:        { "continue",   T_CONTINUE,     0,      0,      0,        0,0,0,0,1 },
                    233:        { "default",    T_DEFAULT,      0,      0,      0,        0,0,0,0,1 },
                    234:        { "deprecated", T_AT_DEPRECATED,0,      0,      0,        0,0,1,1,5 },
                    235:        { "do",         T_DO,           0,      0,      0,        0,0,0,0,1 },
                    236:        { "double",     T_TYPE,         0,      DOUBLE, 0,        0,0,0,0,1 },
                    237:        { "else",       T_ELSE,         0,      0,      0,        0,0,0,0,1 },
                    238:        { "enum",       T_ENUM,         0,      0,      0,        0,0,0,0,1 },
                    239:        { "extension",  T_EXTENSION,    0,      0,      0,        0,0,1,0,4 },
                    240:        { "extern",     T_SCLASS,       EXTERN, 0,      0,        0,0,0,0,1 },
                    241:        { "float",      T_TYPE,         0,      FLOAT,  0,        0,0,0,0,1 },
                    242:        { "for",        T_FOR,          0,      0,      0,        0,0,0,0,1 },
                    243:        { "format",     T_AT_FORMAT,    0,      0,      0,        0,0,1,1,5 },
                    244:        { "format_arg", T_AT_FORMAT_ARG,0,      0,      0,        0,0,1,1,5 },
                    245:        { "gnu_inline", T_AT_GNU_INLINE,0,      0,      0,        0,0,1,1,5 },
                    246:        { "goto",       T_GOTO,         0,      0,      0,        0,0,0,0,1 },
                    247:        { "if",         T_IF,           0,      0,      0,        0,0,0,0,1 },
                    248:        { "imag",       T_IMAG,         0,      0,      0,        0,1,0,0,4 },
                    249:        { "inline",     T_SCLASS,       INLINE, 0,      0,        0,1,0,0,7 },
                    250:        { "int",        T_TYPE,         0,      INT,    0,        0,0,0,0,1 },
                    251:        { "long",       T_TYPE,         0,      LONG,   0,        0,0,0,0,1 },
                    252:        { "may_alias",  T_AT_MAY_ALIAS, 0,      0,      0,        0,0,1,1,5 },
1.75      christos  253:        { "minbytes",   T_AT_MINBYTES,  0,      0,      0,        0,0,1,1,5 },
1.73      christos  254:        { "mode",       T_AT_MODE,      0,      0,      0,        0,0,1,1,5 },
1.69      christos  255:        { "no_instrument_function", T_AT_NO_INSTRUMENT_FUNCTION,
1.73      christos  256:                                        0,      0,      0,        0,0,1,1,5 },
1.75      christos  257:        { "nonnull",    T_AT_NONNULL,   0,      0,      0,        0,0,1,1,5 },
1.82      christos  258:        { "noinline",   T_AT_NOINLINE,  0,      0,      0,        0,0,1,1,5 },
1.73      christos  259:        { "noreturn",   T_AT_NORETURN,  0,      0,      0,        0,0,1,1,5 },
                    260:        { "packed",     T_AT_PACKED,    0,      0,      0,        0,0,1,1,5 },
                    261:        { "packed",     T_PACKED,       0,      0,      0,        0,0,0,0,2 },
1.77      christos  262:        { "pcs",        T_AT_PCS,       0,      0,      0,        0,0,0,0,5 },
1.73      christos  263:        { "printf",     T_AT_FORMAT_PRINTF,0,   0,      0,        0,0,1,1,5 },
                    264:        { "pure",       T_AT_PURE,      0,      0,      0,        0,0,1,1,5 },
                    265:        { "real",       T_REAL,         0,      0,      0,        0,1,0,0,4 },
                    266:        { "register",   T_SCLASS,       REG,    0,      0,        0,0,0,0,1 },
                    267:        { "restrict",   T_QUAL,         0,      0,      RESTRICT, 0,1,0,0,5 },
                    268:        { "return",     T_RETURN,       0,      0,      0,        0,0,0,0,1 },
                    269:        { "returns_twice", T_AT_RETURNS_TWICE,0,0,      0,        0,0,1,1,5 },
                    270:        { "scanf",      T_AT_FORMAT_SCANF,0,    0,      0,        0,0,1,1,5 },
                    271:        { "section",    T_AT_SECTION,   0,      0,      0,        0,0,1,1,7 },
                    272:        { "sentinel",   T_AT_SENTINEL,  0,      0,      0,        0,0,1,1,5 },
                    273:        { "short",      T_TYPE,         0,      SHORT,  0,        0,0,0,0,1 },
                    274:        { "signed",     T_TYPE,         0,      SIGNED, 0,        1,0,0,0,3 },
                    275:        { "sizeof",     T_SIZEOF,       0,      0,      0,        0,0,0,0,1 },
                    276:        { "static",     T_SCLASS,       STATIC, 0,      0,        0,0,0,0,1 },
                    277:        { "strfmon",    T_AT_FORMAT_STRFMON,0,  0,      0,        0,0,1,1,5 },
                    278:        { "strftime",   T_AT_FORMAT_STRFTIME,0, 0,      0,        0,0,1,1,5 },
1.75      christos  279:        { "string",     T_AT_STRING,    0,      0,      0,        0,0,1,1,5 },
1.73      christos  280:        { "struct",     T_SOU,          0,      STRUCT, 0,        0,0,0,0,1 },
                    281:        { "switch",     T_SWITCH,       0,      0,      0,        0,0,0,0,1 },
                    282:        { "symbolrename", T_SYMBOLRENAME, 0,    0,      0,        0,0,0,0,2 },
1.81      christos  283:        { "syslog",     T_AT_FORMAT_SYSLOG,0,   0,      0,        0,0,1,1,5 },
1.73      christos  284:        { "transparent_union",T_AT_TUNION,0,    0,      0,        0,0,1,1,5 },
                    285:        { "typedef",    T_SCLASS,       TYPEDEF, 0,     0,        0,0,0,0,1 },
1.74      christos  286:        { "typeof",     T_TYPEOF,       0,      0,      0,        0,0,1,0,7 },
1.73      christos  287:        { "union",      T_SOU,          0,      UNION,  0,        0,0,0,0,1 },
                    288:        { "unsigned",   T_TYPE,         0,      UNSIGN, 0,        0,0,0,0,1 },
                    289:        { "unused",     T_AT_UNUSED,    0,      0,      0,        0,0,1,1,5 },
                    290:        { "used",       T_AT_USED,      0,      0,      0,        0,0,1,1,5 },
                    291:        { "visibility", T_AT_VISIBILITY,0,      0,      0,        0,0,1,1,5 },
                    292:        { "void",       T_TYPE,         0,      VOID,   0,        0,0,0,0,1 },
                    293:        { "volatile",   T_QUAL,         0,      0,      VOLATILE, 1,0,0,0,7 },
1.85    ! christos  294:        { "warn_unused_result", T_AT_WARN_UNUSED_RESULT, 0, 0, 0, 0,0,1,1,5 },
1.73      christos  295:        { "weak",       T_AT_WEAK,      0,      0,      0,        0,0,1,1,5 },
                    296:        { "while",      T_WHILE,        0,      0,      0,        0,0,0,0,1 },
                    297:        { NULL,         0,              0,      0,      0,        0,0,0,0,0 }
1.1       cgd       298: };
                    299:
                    300: /* Symbol table */
                    301: static sym_t   *symtab[HSHSIZ1];
                    302:
                    303: /* bit i of the entry with index i is set */
1.27      thorpej   304: uint64_t qbmasks[sizeof(uint64_t) * CHAR_BIT];
1.1       cgd       305:
                    306: /* least significant i bits are set in the entry with index i */
1.27      thorpej   307: uint64_t qlmasks[sizeof(uint64_t) * CHAR_BIT + 1];
1.1       cgd       308:
                    309: /* least significant i bits are not set in the entry with index i */
1.27      thorpej   310: uint64_t qumasks[sizeof(uint64_t) * CHAR_BIT + 1];
1.1       cgd       311:
                    312: /* free list for sbuf structures */
                    313: static sbuf_t   *sbfrlst;
                    314:
                    315: /* Typ of next expected symbol */
                    316: symt_t symtyp;
                    317:
                    318:
1.73      christos  319: static void
                    320: addkw(struct kwtab *kw, int deco)
                    321: {
                    322:        sym_t *sym;
                    323:        size_t h;
                    324:        char buf[256];
                    325:        const char *name;
                    326:
                    327:        if (!(kw->kw_deco & deco))
                    328:                return;
                    329:
                    330:        switch (deco) {
                    331:        case 1:
                    332:                name = kw->kw_name;
                    333:                break;
                    334:        case 2:
                    335:                snprintf(buf, sizeof(buf), "__%s", kw->kw_name);
                    336:                name = strdup(buf);
                    337:                break;
                    338:        case 4:
                    339:                snprintf(buf, sizeof(buf), "__%s__", kw->kw_name);
                    340:                name = strdup(buf);
                    341:                break;
                    342:        default:
                    343:                abort();
                    344:        }
                    345:
                    346:        if (name == NULL)
                    347:                err(1, "Can't init symbol table");
                    348:
                    349:        sym = getblk(sizeof (sym_t));
                    350:        sym->s_name = name;
                    351:        sym->s_keyw = kw;
                    352:        sym->s_value.v_quad = kw->kw_token;
                    353:        if (kw->kw_token == T_TYPE || kw->kw_token == T_SOU) {
                    354:                sym->s_tspec = kw->kw_tspec;
                    355:        } else if (kw->kw_token == T_SCLASS) {
                    356:                sym->s_scl = kw->kw_scl;
                    357:        } else if (kw->kw_token == T_QUAL) {
                    358:                sym->s_tqual = kw->kw_tqual;
                    359:        }
                    360:        h = hash(sym->s_name);
                    361:        if ((sym->s_link = symtab[h]) != NULL)
                    362:                symtab[h]->s_rlink = &sym->s_link;
                    363:        sym->s_rlink = &symtab[h];
                    364:        symtab[h] = sym;
                    365: }
                    366:
1.1       cgd       367: /*
                    368:  * All keywords are written to the symbol table. This saves us looking
                    369:  * in a extra table for each name we found.
                    370:  */
                    371: void
1.19      lukem     372: initscan(void)
1.1       cgd       373: {
                    374:        struct  kwtab *kw;
1.73      christos  375:        size_t  i;
1.27      thorpej   376:        uint64_t uq;
1.1       cgd       377:
                    378:        for (kw = kwtab; kw->kw_name != NULL; kw++) {
1.32      perry     379:                if ((kw->kw_c89 || kw->kw_c99) && tflag)
                    380:                        continue;
                    381:                if (kw->kw_c99 && !(Sflag || gflag))
1.5       jpo       382:                        continue;
                    383:                if (kw->kw_gcc && !gflag)
                    384:                        continue;
1.73      christos  385:                addkw(kw, 1);
                    386:                addkw(kw, 2);
                    387:                addkw(kw, 4);
1.1       cgd       388:        }
                    389:
                    390:        /* initialize bit-masks for quads */
1.27      thorpej   391:        for (i = 0; i < sizeof (uint64_t) * CHAR_BIT; i++) {
                    392:                qbmasks[i] = (uint64_t)1 << i;
                    393:                uq = ~(uint64_t)0 << i;
1.1       cgd       394:                qumasks[i] = uq;
                    395:                qlmasks[i] = ~uq;
                    396:        }
                    397:        qumasks[i] = 0;
1.27      thorpej   398:        qlmasks[i] = ~(uint64_t)0;
1.1       cgd       399: }
                    400:
                    401: /*
                    402:  * Get a free sbuf structure, if possible from the free list
                    403:  */
                    404: static sbuf_t *
1.19      lukem     405: allocsb(void)
1.1       cgd       406: {
                    407:        sbuf_t  *sb;
                    408:
                    409:        if ((sb = sbfrlst) != NULL) {
                    410:                sbfrlst = sb->sb_nxt;
1.55      christos  411: #ifdef BLKDEBUG
                    412:                (void)memset(sb, 0, sizeof (*sb));
                    413: #else
                    414:                sb->sb_nxt = NULL;
                    415: #endif
1.1       cgd       416:        } else {
                    417:                sb = xmalloc(sizeof (sbuf_t));
1.55      christos  418:                (void)memset(sb, 0, sizeof (*sb));
1.1       cgd       419:        }
                    420:        return (sb);
                    421: }
                    422:
                    423: /*
                    424:  * Put a sbuf structure to the free list
                    425:  */
                    426: static void
1.19      lukem     427: freesb(sbuf_t *sb)
1.1       cgd       428: {
1.19      lukem     429:
1.55      christos  430:        (void)memset(sb, ZERO, sizeof (*sb));
1.1       cgd       431:        sb->sb_nxt = sbfrlst;
                    432:        sbfrlst = sb;
                    433: }
                    434:
                    435: /*
                    436:  * Read a character and ensure that it is positive (except EOF).
                    437:  * Increment line count(s) if necessary.
                    438:  */
                    439: static int
1.19      lukem     440: inpc(void)
1.1       cgd       441: {
                    442:        int     c;
                    443:
                    444:        if ((c = input()) != EOF && (c &= CHAR_MASK) == '\n')
                    445:                incline();
                    446:        return (c);
                    447: }
                    448:
                    449: static int
1.19      lukem     450: hash(const char *s)
1.1       cgd       451: {
                    452:        u_int   v;
                    453:        const   u_char *us;
                    454:
                    455:        v = 0;
                    456:        for (us = (const u_char *)s; *us != '\0'; us++) {
                    457:                v = (v << sizeof (v)) + *us;
                    458:                v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v));
                    459:        }
                    460:        return (v % HSHSIZ1);
                    461: }
                    462:
                    463: /*
                    464:  * Lex has found a letter followed by zero or more letters or digits.
                    465:  * It looks for a symbol in the symbol table with the same name. This
                    466:  * symbol must either be a keyword or a symbol of the type required by
                    467:  * symtyp (label, member, tag, ...).
                    468:  *
                    469:  * If it is a keyword, the token is returned. In some cases it is described
                    470:  * more deeply by data written to yylval.
                    471:  *
                    472:  * If it is a symbol, T_NAME is returned and the pointer to a sbuf struct
1.60      snj       473:  * is stored in yylval. This struct contains the name of the symbol, its
1.1       cgd       474:  * length and hash value. If there is already a symbol of the same name
                    475:  * and type in the symbol table, the sbuf struct also contains a pointer
                    476:  * to the symbol table entry.
                    477:  */
                    478: static int
1.19      lukem     479: name(void)
1.1       cgd       480: {
                    481:        char    *s;
                    482:        sbuf_t  *sb;
                    483:        sym_t   *sym;
                    484:        int     tok;
                    485:
                    486:        sb = allocsb();
                    487:        sb->sb_name = yytext;
                    488:        sb->sb_len = yyleng;
                    489:        sb->sb_hash = hash(yytext);
                    490:        if ((sym = search(sb)) != NULL && sym->s_keyw) {
1.56      christos  491:                freesb(sb);
                    492:                return (keyw(sym));
1.1       cgd       493:        }
                    494:
                    495:        sb->sb_sym = sym;
                    496:
                    497:        if (sym != NULL) {
                    498:                if (blklev < sym->s_blklev)
1.28      christos  499:                        LERROR("name()");
1.1       cgd       500:                sb->sb_name = sym->s_name;
                    501:                sb->sb_len = strlen(sym->s_name);
                    502:                tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME;
                    503:        } else {
                    504:                s = getblk(yyleng + 1);
                    505:                (void)memcpy(s, yytext, yyleng + 1);
                    506:                sb->sb_name = s;
                    507:                sb->sb_len = yyleng;
                    508:                tok = T_NAME;
                    509:        }
                    510:
                    511:        yylval.y_sb = sb;
                    512:        return (tok);
                    513: }
                    514:
                    515: static sym_t *
1.19      lukem     516: search(sbuf_t *sb)
1.1       cgd       517: {
                    518:        sym_t   *sym;
                    519:
                    520:        for (sym = symtab[sb->sb_hash]; sym != NULL; sym = sym->s_link) {
                    521:                if (strcmp(sym->s_name, sb->sb_name) == 0) {
1.56      christos  522:                        if (sym->s_keyw) {
                    523:                                struct kwtab *kw = sym->s_keyw;
                    524:                                if (!kw->kw_attr || attron)
                    525:                                        return (sym);
1.72      christos  526:                        } else if (!attron && sym->s_kind == symtyp)
1.56      christos  527:                                return sym;
1.1       cgd       528:                }
                    529:        }
                    530:
                    531:        return (NULL);
                    532: }
1.19      lukem     533:
1.1       cgd       534: static int
1.19      lukem     535: keyw(sym_t *sym)
1.1       cgd       536: {
                    537:        int     t;
                    538:
                    539:        if ((t = (int)sym->s_value.v_quad) == T_SCLASS) {
                    540:                yylval.y_scl = sym->s_scl;
                    541:        } else if (t == T_TYPE || t == T_SOU) {
                    542:                yylval.y_tspec = sym->s_tspec;
                    543:        } else if (t == T_QUAL) {
                    544:                yylval.y_tqual = sym->s_tqual;
                    545:        }
                    546:        return (t);
                    547: }
                    548:
                    549: /*
                    550:  * Convert a string representing an integer into internal representation.
                    551:  * The value is returned in yylval. icon() (and yylex()) returns T_CON.
                    552:  */
                    553: static int
1.19      lukem     554: icon(int base)
1.1       cgd       555: {
                    556:        int     l_suffix, u_suffix;
                    557:        int     len;
1.64      christos  558:        const   char *cp;
1.1       cgd       559:        char    c, *eptr;
                    560:        tspec_t typ;
1.83      christos  561:        int     ansiu;
1.84      christos  562: #ifdef TARG_INT128_MAX
1.83      christos  563:        __uint128_t uq = 0;
                    564:        static  tspec_t contypes[2][4] = {
                    565:                { INT,  LONG,  QUAD, INT128, },
                    566:                { UINT, ULONG, UQUAD, UINT128, }
                    567:        };
                    568: #else
1.27      thorpej   569:        uint64_t uq = 0;
1.1       cgd       570:        static  tspec_t contypes[2][3] = {
1.83      christos  571:                { INT,  LONG,  QUAD, },
                    572:                { UINT, ULONG, UQUAD, }
1.1       cgd       573:        };
1.83      christos  574: #endif
1.1       cgd       575:
                    576:        cp = yytext;
                    577:        len = yyleng;
                    578:
1.62      christos  579:        /* skip 0[xX] or 0[bB] */
                    580:        if (base == 16 || base == 2) {
1.1       cgd       581:                cp += 2;
                    582:                len -= 2;
                    583:        }
                    584:
                    585:        /* read suffixes */
                    586:        l_suffix = u_suffix = 0;
                    587:        for ( ; ; ) {
                    588:                if ((c = cp[len - 1]) == 'l' || c == 'L') {
                    589:                        l_suffix++;
                    590:                } else if (c == 'u' || c == 'U') {
                    591:                        u_suffix++;
                    592:                } else {
                    593:                        break;
                    594:                }
                    595:                len--;
                    596:        }
                    597:        if (l_suffix > 2 || u_suffix > 1) {
                    598:                /* malformed integer constant */
                    599:                warning(251);
                    600:                if (l_suffix > 2)
                    601:                        l_suffix = 2;
                    602:                if (u_suffix > 1)
                    603:                        u_suffix = 1;
                    604:        }
                    605:        if (tflag && u_suffix != 0) {
                    606:                /* suffix U is illegal in traditional C */
                    607:                warning(97);
                    608:        }
                    609:        typ = contypes[u_suffix][l_suffix];
                    610:
                    611:        errno = 0;
1.35      he        612:
1.64      christos  613:        uq = strtouq(cp, &eptr, base);
1.1       cgd       614:        if (eptr != cp + len)
1.28      christos  615:                LERROR("icon()");
1.1       cgd       616:        if (errno != 0)
                    617:                /* integer constant out of range */
                    618:                warning(252);
                    619:
                    620:        /*
1.35      he        621:         * If the value is too big for the current type, we must choose
1.1       cgd       622:         * another type.
                    623:         */
                    624:        ansiu = 0;
                    625:        switch (typ) {
                    626:        case INT:
1.35      he        627:                if (uq <= TARG_INT_MAX) {
1.1       cgd       628:                        /* ok */
1.35      he        629:                } else if (uq <= TARG_UINT_MAX && base != 10) {
1.1       cgd       630:                        typ = UINT;
1.35      he        631:                } else if (uq <= TARG_LONG_MAX) {
1.1       cgd       632:                        typ = LONG;
                    633:                } else {
                    634:                        typ = ULONG;
1.35      he        635:                        if (uq > TARG_ULONG_MAX) {
                    636:                                /* integer constant out of range */
                    637:                                warning(252);
                    638:                        }
1.1       cgd       639:                }
                    640:                if (typ == UINT || typ == ULONG) {
                    641:                        if (tflag) {
                    642:                                typ = LONG;
                    643:                        } else if (!sflag) {
                    644:                                /*
                    645:                                 * Remember that the constant is unsigned
                    646:                                 * only in ANSI C
                    647:                                 */
                    648:                                ansiu = 1;
                    649:                        }
                    650:                }
                    651:                break;
                    652:        case UINT:
1.35      he        653:                if (uq > TARG_UINT_MAX) {
1.1       cgd       654:                        typ = ULONG;
1.35      he        655:                        if (uq > TARG_ULONG_MAX) {
                    656:                                /* integer constant out of range */
                    657:                                warning(252);
                    658:                        }
                    659:                }
1.1       cgd       660:                break;
                    661:        case LONG:
1.35      he        662:                if (uq > TARG_LONG_MAX && !tflag) {
1.1       cgd       663:                        typ = ULONG;
                    664:                        if (!sflag)
                    665:                                ansiu = 1;
1.35      he        666:                        if (uq > TARG_ULONG_MAX) {
                    667:                                /* integer constant out of range */
                    668:                                warning(252);
                    669:                        }
1.1       cgd       670:                }
                    671:                break;
1.39      joerg     672:        case ULONG:
                    673:                if (uq > TARG_ULONG_MAX) {
                    674:                        /* integer constant out of range */
                    675:                        warning(252);
                    676:                }
                    677:                break;
1.1       cgd       678:        case QUAD:
1.35      he        679:                if (uq > TARG_QUAD_MAX && !tflag) {
1.1       cgd       680:                        typ = UQUAD;
                    681:                        if (!sflag)
                    682:                                ansiu = 1;
                    683:                }
                    684:                break;
1.39      joerg     685:        case UQUAD:
                    686:                if (uq > TARG_UQUAD_MAX) {
                    687:                        /* integer constant out of range */
                    688:                        warning(252);
                    689:                }
                    690:                break;
1.83      christos  691: #ifdef INT128_SIZE
                    692:        case INT128:
1.84      christos  693: #ifdef TARG_INT128_MAX
1.83      christos  694:                if (uq > TARG_INT128_MAX && !tflag) {
                    695:                        typ = UINT128;
                    696:                        if (!sflag)
                    697:                                ansiu = 1;
                    698:                }
1.84      christos  699: #endif
1.83      christos  700:                break;
                    701:        case UINT128:
1.84      christos  702: #ifdef TARG_INT128_MAX
1.83      christos  703:                if (uq > TARG_UINT128_MAX) {
                    704:                        /* integer constant out of range */
                    705:                        warning(252);
                    706:                }
1.84      christos  707: #endif
1.83      christos  708:                break;
                    709: #endif
1.52      christos  710:                /* LINTED206: (enumeration values not handled in switch) */
1.11      christos  711:        case STRUCT:
                    712:        case VOID:
                    713:        case LDOUBLE:
                    714:        case FUNC:
                    715:        case ARRAY:
                    716:        case PTR:
                    717:        case ENUM:
                    718:        case UNION:
                    719:        case SIGNED:
                    720:        case NOTSPEC:
                    721:        case DOUBLE:
                    722:        case FLOAT:
                    723:        case USHORT:
                    724:        case SHORT:
                    725:        case UCHAR:
                    726:        case SCHAR:
                    727:        case CHAR:
1.33      yamt      728:        case BOOL:
1.11      christos  729:        case UNSIGN:
1.38      christos  730:        case FCOMPLEX:
                    731:        case DCOMPLEX:
1.40      matt      732:        case LCOMPLEX:
1.38      christos  733:        case COMPLEX:
1.23      thorpej   734:                break;
                    735:
                    736:        case NTSPEC:    /* this value unused */
1.11      christos  737:                break;
1.1       cgd       738:        }
                    739:
1.27      thorpej   740:        uq = (uint64_t)xsign((int64_t)uq, typ, -1);
1.1       cgd       741:
                    742:        (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ;
                    743:        yylval.y_val->v_ansiu = ansiu;
1.27      thorpej   744:        yylval.y_val->v_quad = (int64_t)uq;
1.1       cgd       745:
                    746:        return (T_CON);
                    747: }
                    748:
                    749: /*
                    750:  * Returns 1 if t is a signed type and the value is negative.
                    751:  *
                    752:  * len is the number of significant bits. If len is -1, len is set
                    753:  * to the width of type t.
                    754:  */
                    755: int
1.27      thorpej   756: sign(int64_t q, tspec_t t, int len)
1.1       cgd       757: {
1.19      lukem     758:
1.1       cgd       759:        if (t == PTR || isutyp(t))
                    760:                return (0);
                    761:        return (msb(q, t, len));
                    762: }
                    763:
                    764: int
1.27      thorpej   765: msb(int64_t q, tspec_t t, int len)
1.1       cgd       766: {
1.19      lukem     767:
1.1       cgd       768:        if (len <= 0)
                    769:                len = size(t);
                    770:        return ((q & qbmasks[len - 1]) != 0);
                    771: }
                    772:
                    773: /*
                    774:  * Extends the sign of q.
                    775:  */
1.27      thorpej   776: int64_t
                    777: xsign(int64_t q, tspec_t t, int len)
1.1       cgd       778: {
1.19      lukem     779:
1.1       cgd       780:        if (len <= 0)
                    781:                len = size(t);
                    782:
                    783:        if (t == PTR || isutyp(t) || !sign(q, t, len)) {
                    784:                q &= qlmasks[len];
                    785:        } else {
                    786:                q |= qumasks[len];
                    787:        }
                    788:        return (q);
                    789: }
                    790:
                    791: /*
                    792:  * Convert a string representing a floating point value into its interal
                    793:  * representation. Type and value are returned in yylval. fcon()
                    794:  * (and yylex()) returns T_CON.
                    795:  * XXX Currently it is not possible to convert constants of type
1.20      wiz       796:  * long double which are greater than DBL_MAX.
1.1       cgd       797:  */
                    798: static int
1.19      lukem     799: fcon(void)
1.1       cgd       800: {
                    801:        const   char *cp;
                    802:        int     len;
                    803:        tspec_t typ;
                    804:        char    c, *eptr;
                    805:        double  d;
1.11      christos  806:        float   f = 0;
1.1       cgd       807:
                    808:        cp = yytext;
                    809:        len = yyleng;
                    810:
1.38      christos  811:        if (cp[len - 1] == 'i') {
                    812:                /* imaginary, do nothing for now */
                    813:                len--;
                    814:        }
1.1       cgd       815:        if ((c = cp[len - 1]) == 'f' || c == 'F') {
                    816:                typ = FLOAT;
                    817:                len--;
                    818:        } else if (c == 'l' || c == 'L') {
                    819:                typ = LDOUBLE;
                    820:                len--;
                    821:        } else {
1.49      christos  822:                if (c == 'd' || c == 'D')
                    823:                        len--;
1.1       cgd       824:                typ = DOUBLE;
                    825:        }
                    826:
                    827:        if (tflag && typ != DOUBLE) {
                    828:                /* suffixes F and L are illegal in traditional C */
                    829:                warning(98);
                    830:        }
                    831:
                    832:        errno = 0;
                    833:        d = strtod(cp, &eptr);
1.37      he        834:        if (eptr != cp + len) {
                    835:                switch (*eptr) {
                    836:                /*
                    837:                 * XXX: non-native non-current strtod() may not handle hex
                    838:                 * floats, ignore the rest if we find traces of hex float
                    839:                 * syntax...
                    840:                 */
                    841:                case 'p':
                    842:                case 'P':
                    843:                case 'x':
                    844:                case 'X':
                    845:                        d = 0;
                    846:                        errno = 0;
                    847:                        break;
                    848:                default:
1.49      christos  849:                        LERROR("fcon(%s->%s)", cp, eptr);
1.37      he        850:                }
                    851:        }
1.1       cgd       852:        if (errno != 0)
                    853:                /* floating-point constant out of range */
                    854:                warning(248);
                    855:
                    856:        if (typ == FLOAT) {
                    857:                f = (float)d;
1.26      tv        858:                if (!finite(f)) {
1.1       cgd       859:                        /* floating-point constant out of range */
                    860:                        warning(248);
                    861:                        f = f > 0 ? FLT_MAX : -FLT_MAX;
                    862:                }
                    863:        }
                    864:
                    865:        (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ;
                    866:        if (typ == FLOAT) {
                    867:                yylval.y_val->v_ldbl = f;
                    868:        } else {
                    869:                yylval.y_val->v_ldbl = d;
                    870:        }
                    871:
                    872:        return (T_CON);
                    873: }
                    874:
                    875: static int
1.19      lukem     876: operator(int t, op_t o)
1.1       cgd       877: {
1.19      lukem     878:
1.1       cgd       879:        yylval.y_op = o;
                    880:        return (t);
                    881: }
                    882:
                    883: /*
                    884:  * Called if lex found a leading \'.
                    885:  */
                    886: static int
1.19      lukem     887: ccon(void)
1.1       cgd       888: {
1.43      christos  889:        size_t  n;
                    890:        int val, c;
1.1       cgd       891:        char    cv;
                    892:
                    893:        n = 0;
                    894:        val = 0;
                    895:        while ((c = getescc('\'')) >= 0) {
                    896:                val = (val << CHAR_BIT) + c;
                    897:                n++;
                    898:        }
                    899:        if (c == -2) {
                    900:                /* unterminated character constant */
                    901:                error(253);
                    902:        } else {
                    903:                if (n > sizeof (int) || (n > 1 && (pflag || hflag))) {
                    904:                        /* too many characters in character constant */
                    905:                        error(71);
                    906:                } else if (n > 1) {
                    907:                        /* multi-character character constant */
                    908:                        warning(294);
                    909:                } else if (n == 0) {
                    910:                        /* empty character constant */
                    911:                        error(73);
                    912:                }
                    913:        }
                    914:        if (n == 1) {
                    915:                cv = (char)val;
                    916:                val = cv;
                    917:        }
1.19      lukem     918:
1.1       cgd       919:        yylval.y_val = xcalloc(1, sizeof (val_t));
                    920:        yylval.y_val->v_tspec = INT;
                    921:        yylval.y_val->v_quad = val;
                    922:
                    923:        return (T_CON);
                    924: }
                    925:
                    926: /*
                    927:  * Called if lex found a leading L\'
                    928:  */
                    929: static int
1.19      lukem     930: wccon(void)
1.1       cgd       931: {
1.8       jpo       932:        static  char buf[MB_LEN_MAX + 1];
1.43      christos  933:        size_t  i;
                    934:        int c;
1.1       cgd       935:        wchar_t wc;
                    936:
                    937:        i = 0;
                    938:        while ((c = getescc('\'')) >= 0) {
                    939:                if (i < MB_CUR_MAX)
                    940:                        buf[i] = (char)c;
                    941:                i++;
                    942:        }
                    943:
                    944:        wc = 0;
                    945:
                    946:        if (c == -2) {
                    947:                /* unterminated character constant */
                    948:                error(253);
                    949:        } else if (c == 0) {
                    950:                /* empty character constant */
                    951:                error(73);
                    952:        } else {
                    953:                if (i > MB_CUR_MAX) {
                    954:                        i = MB_CUR_MAX;
                    955:                        /* too many characters in character constant */
                    956:                        error(71);
                    957:                } else {
                    958:                        buf[i] = '\0';
                    959:                        (void)mbtowc(NULL, NULL, 0);
                    960:                        if (mbtowc(&wc, buf, MB_CUR_MAX) < 0)
                    961:                                /* invalid multibyte character */
                    962:                                error(291);
                    963:                }
                    964:        }
                    965:
                    966:        yylval.y_val = xcalloc(1, sizeof (val_t));
                    967:        yylval.y_val->v_tspec = WCHAR;
                    968:        yylval.y_val->v_quad = wc;
                    969:
                    970:        return (T_CON);
                    971: }
                    972:
                    973: /*
                    974:  * Read a character which is part of a character constant or of a string
                    975:  * and handle escapes.
                    976:  *
                    977:  * The Argument is the character which delimits the character constant or
                    978:  * string.
                    979:  *
                    980:  * Returns -1 if the end of the character constant or string is reached,
1.16      lukem     981:  * -2 if the EOF is reached, and the character otherwise.
1.1       cgd       982:  */
                    983: static int
1.19      lukem     984: getescc(int d)
1.1       cgd       985: {
                    986:        static  int pbc = -1;
                    987:        int     n, c, v;
                    988:
                    989:        if (pbc == -1) {
                    990:                c = inpc();
                    991:        } else {
                    992:                c = pbc;
                    993:                pbc = -1;
                    994:        }
                    995:        if (c == d)
                    996:                return (-1);
                    997:        switch (c) {
                    998:        case '\n':
1.16      lukem     999:                if (tflag) {
                   1000:                        /* newline in string or char constant */
                   1001:                        error(254);
                   1002:                        return (-2);
                   1003:                }
                   1004:                return (c);
1.1       cgd      1005:        case EOF:
                   1006:                return (-2);
                   1007:        case '\\':
                   1008:                switch (c = inpc()) {
                   1009:                case '"':
                   1010:                        if (tflag && d == '\'')
                   1011:                                /* \" inside character constant undef. ... */
                   1012:                                warning(262);
                   1013:                        return ('"');
                   1014:                case '\'':
                   1015:                        return ('\'');
                   1016:                case '?':
                   1017:                        if (tflag)
                   1018:                                /* \? undefined in traditional C */
                   1019:                                warning(263);
                   1020:                        return ('?');
                   1021:                case '\\':
                   1022:                        return ('\\');
                   1023:                case 'a':
                   1024:                        if (tflag)
                   1025:                                /* \a undefined in traditional C */
                   1026:                                warning(81);
                   1027:                        return ('\a');
                   1028:                case 'b':
                   1029:                        return ('\b');
                   1030:                case 'f':
                   1031:                        return ('\f');
                   1032:                case 'n':
                   1033:                        return ('\n');
                   1034:                case 'r':
                   1035:                        return ('\r');
                   1036:                case 't':
                   1037:                        return ('\t');
                   1038:                case 'v':
                   1039:                        if (tflag)
                   1040:                                /* \v undefined in traditional C */
                   1041:                                warning(264);
                   1042:                        return ('\v');
                   1043:                case '8': case '9':
                   1044:                        /* bad octal digit %c */
                   1045:                        warning(77, c);
                   1046:                        /* FALLTHROUGH */
                   1047:                case '0': case '1': case '2': case '3':
                   1048:                case '4': case '5': case '6': case '7':
                   1049:                        n = 3;
                   1050:                        v = 0;
                   1051:                        do {
                   1052:                                v = (v << 3) + (c - '0');
                   1053:                                c = inpc();
                   1054:                        } while (--n && isdigit(c) && (tflag || c <= '7'));
                   1055:                        if (tflag && n > 0 && isdigit(c))
                   1056:                                /* bad octal digit %c */
                   1057:                                warning(77, c);
                   1058:                        pbc = c;
1.50      christos 1059:                        if (v > TARG_UCHAR_MAX) {
1.1       cgd      1060:                                /* character escape does not fit in char. */
                   1061:                                warning(76);
                   1062:                                v &= CHAR_MASK;
                   1063:                        }
                   1064:                        return (v);
                   1065:                case 'x':
                   1066:                        if (tflag)
                   1067:                                /* \x undefined in traditional C */
                   1068:                                warning(82);
                   1069:                        v = 0;
                   1070:                        n = 0;
                   1071:                        while ((c = inpc()) >= 0 && isxdigit(c)) {
                   1072:                                c = isdigit(c) ?
                   1073:                                        c - '0' : toupper(c) - 'A' + 10;
                   1074:                                v = (v << 4) + c;
                   1075:                                if (n >= 0) {
                   1076:                                        if ((v & ~CHAR_MASK) != 0) {
                   1077:                                                /* overflow in hex escape */
                   1078:                                                warning(75);
                   1079:                                                n = -1;
                   1080:                                        } else {
                   1081:                                                n++;
                   1082:                                        }
                   1083:                                }
                   1084:                        }
                   1085:                        pbc = c;
                   1086:                        if (n == 0) {
                   1087:                                /* no hex digits follow \x */
                   1088:                                error(74);
                   1089:                        } if (n == -1) {
                   1090:                                v &= CHAR_MASK;
                   1091:                        }
                   1092:                        return (v);
                   1093:                case '\n':
                   1094:                        return (getescc(d));
                   1095:                case EOF:
                   1096:                        return (-2);
                   1097:                default:
                   1098:                        if (isprint(c)) {
                   1099:                                /* dubious escape \%c */
                   1100:                                warning(79, c);
                   1101:                        } else {
                   1102:                                /* dubious escape \%o */
                   1103:                                warning(80, c);
                   1104:                        }
                   1105:                }
                   1106:        }
                   1107:        return (c);
                   1108: }
                   1109:
                   1110: /*
                   1111:  * Called for preprocessor directives. Currently implemented are:
                   1112:  *     # lineno
                   1113:  *     # lineno "filename"
                   1114:  */
                   1115: static void
1.19      lukem    1116: directive(void)
1.1       cgd      1117: {
                   1118:        const   char *cp, *fn;
                   1119:        char    c, *eptr;
                   1120:        size_t  fnl;
                   1121:        long    ln;
                   1122:        static  int first = 1;
                   1123:
                   1124:        /* Go to first non-whitespace after # */
1.19      lukem    1125:        for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++)
                   1126:                continue;
1.1       cgd      1127:
1.13      christos 1128:        if (!isdigit((unsigned char)c)) {
1.78      christos 1129:                if (strncmp(cp, "pragma", 6) == 0
                   1130:                    && isspace((unsigned char)cp[6]))
                   1131:                        return;
1.1       cgd      1132:        error:
                   1133:                /* undefined or invalid # directive */
                   1134:                warning(255);
                   1135:                return;
                   1136:        }
                   1137:        ln = strtol(--cp, &eptr, 10);
                   1138:        if (cp == eptr)
                   1139:                goto error;
                   1140:        if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0')
                   1141:                goto error;
1.17      lukem    1142:        while ((c = *cp++) == ' ' || c == '\t')
                   1143:                continue;
1.1       cgd      1144:        if (c != '\0') {
                   1145:                if (c != '"')
                   1146:                        goto error;
                   1147:                fn = cp;
                   1148:                while ((c = *cp) != '"' && c != '\0')
                   1149:                        cp++;
                   1150:                if (c != '"')
                   1151:                        goto error;
                   1152:                if ((fnl = cp++ - fn) > PATH_MAX)
                   1153:                        goto error;
1.17      lukem    1154:                while ((c = *cp++) == ' ' || c == '\t')
                   1155:                        continue;
1.1       cgd      1156: #if 0
                   1157:                if (c != '\0')
                   1158:                        warning("extra character(s) after directive");
                   1159: #endif
1.9       cgd      1160:
                   1161:                /* empty string means stdin */
                   1162:                if (fnl == 0) {
                   1163:                        fn = "{standard input}";
                   1164:                        fnl = 16;                       /* strlen (fn) */
                   1165:                }
1.1       cgd      1166:                curr_pos.p_file = fnnalloc(fn, fnl);
                   1167:                /*
                   1168:                 * If this is the first directive, the name is the name
                   1169:                 * of the C source file as specified at the command line.
                   1170:                 * It is written to the output file.
                   1171:                 */
                   1172:                if (first) {
                   1173:                        csrc_pos.p_file = curr_pos.p_file;
1.68      christos 1174:                        outsrc(fnxform(curr_pos.p_file,
                   1175:                            strlen(curr_pos.p_file)));
1.1       cgd      1176:                        first = 0;
                   1177:                }
                   1178:        }
                   1179:        curr_pos.p_line = (int)ln - 1;
1.9       cgd      1180:        curr_pos.p_uniq = 0;
                   1181:        if (curr_pos.p_file == csrc_pos.p_file) {
1.1       cgd      1182:                csrc_pos.p_line = (int)ln - 1;
1.9       cgd      1183:                csrc_pos.p_uniq = 0;
                   1184:        }
1.1       cgd      1185: }
                   1186:
                   1187: /*
                   1188:  * Handle lint comments. Following comments are currently understood:
                   1189:  *     ARGSUSEDn
1.22      thorpej  1190:  *     BITFIELDTYPE
1.1       cgd      1191:  *     CONSTCOND CONSTANTCOND CONSTANTCONDITION
                   1192:  *     FALLTHRU FALLTHROUGH
                   1193:  *     LINTLIBRARY
1.52      christos 1194:  *     LINTEDn NOSTRICTn
1.7       jpo      1195:  *     LONGLONG
1.1       cgd      1196:  *     NOTREACHED
                   1197:  *     PRINTFLIKEn
                   1198:  *     PROTOLIB
                   1199:  *     SCANFLIKEn
                   1200:  *     VARARGSn
                   1201:  * If one of this comments is recognized, the arguments, if any, are
                   1202:  * parsed and a function which handles this comment is called.
                   1203:  */
                   1204: static void
1.19      lukem    1205: comment(void)
1.1       cgd      1206: {
                   1207:        int     c, lc;
                   1208:        static struct {
                   1209:                const   char *keywd;
                   1210:                int     arg;
1.19      lukem    1211:                void    (*func)(int);
1.1       cgd      1212:        } keywtab[] = {
                   1213:                { "ARGSUSED",           1,      argsused        },
1.22      thorpej  1214:                { "BITFIELDTYPE",       0,      bitfieldtype    },
1.1       cgd      1215:                { "CONSTCOND",          0,      constcond       },
                   1216:                { "CONSTANTCOND",       0,      constcond       },
                   1217:                { "CONSTANTCONDITION",  0,      constcond       },
                   1218:                { "FALLTHRU",           0,      fallthru        },
                   1219:                { "FALLTHROUGH",        0,      fallthru        },
                   1220:                { "LINTLIBRARY",        0,      lintlib         },
1.51      christos 1221:                { "LINTED",             1,      linted          },
1.7       jpo      1222:                { "LONGLONG",           0,      longlong        },
1.52      christos 1223:                { "NOSTRICT",           1,      linted          },
1.1       cgd      1224:                { "NOTREACHED",         0,      notreach        },
                   1225:                { "PRINTFLIKE",         1,      printflike      },
                   1226:                { "PROTOLIB",           1,      protolib        },
                   1227:                { "SCANFLIKE",          1,      scanflike       },
                   1228:                { "VARARGS",            1,      varargs         },
                   1229:        };
                   1230:        char    keywd[32];
                   1231:        char    arg[32];
1.43      christos 1232:        size_t  l, i;
                   1233:        int     a;
1.1       cgd      1234:        int     eoc;
                   1235:
                   1236:        eoc = 0;
                   1237:
                   1238:        /* Skip white spaces after the start of the comment */
1.17      lukem    1239:        while ((c = inpc()) != EOF && isspace(c))
                   1240:                continue;
1.1       cgd      1241:
                   1242:        /* Read the potential keyword to keywd */
                   1243:        l = 0;
                   1244:        while (c != EOF && isupper(c) && l < sizeof (keywd) - 1) {
                   1245:                keywd[l++] = (char)c;
                   1246:                c = inpc();
                   1247:        }
                   1248:        keywd[l] = '\0';
                   1249:
                   1250:        /* look for the keyword */
                   1251:        for (i = 0; i < sizeof (keywtab) / sizeof (keywtab[0]); i++) {
                   1252:                if (strcmp(keywtab[i].keywd, keywd) == 0)
                   1253:                        break;
                   1254:        }
                   1255:        if (i == sizeof (keywtab) / sizeof (keywtab[0]))
                   1256:                goto skip_rest;
                   1257:
                   1258:        /* skip white spaces after the keyword */
                   1259:        while (c != EOF && isspace(c))
                   1260:                c = inpc();
                   1261:
                   1262:        /* read the argument, if the keyword accepts one and there is one */
                   1263:        l = 0;
                   1264:        if (keywtab[i].arg) {
                   1265:                while (c != EOF && isdigit(c) && l < sizeof (arg) - 1) {
                   1266:                        arg[l++] = (char)c;
                   1267:                        c = inpc();
                   1268:                }
                   1269:        }
                   1270:        arg[l] = '\0';
                   1271:        a = l != 0 ? atoi(arg) : -1;
                   1272:
                   1273:        /* skip white spaces after the argument */
                   1274:        while (c != EOF && isspace(c))
                   1275:                c = inpc();
                   1276:
                   1277:        if (c != '*' || (c = inpc()) != '/') {
                   1278:                if (keywtab[i].func != linted)
                   1279:                        /* extra characters in lint comment */
                   1280:                        warning(257);
                   1281:        } else {
                   1282:                /*
                   1283:                 * remember that we have already found the end of the
                   1284:                 * comment
                   1285:                 */
                   1286:                eoc = 1;
                   1287:        }
                   1288:
                   1289:        if (keywtab[i].func != NULL)
                   1290:                (*keywtab[i].func)(a);
                   1291:
                   1292:  skip_rest:
                   1293:        while (!eoc) {
                   1294:                lc = c;
                   1295:                if ((c = inpc()) == EOF) {
                   1296:                        /* unterminated comment */
                   1297:                        error(256);
                   1298:                        break;
                   1299:                }
                   1300:                if (lc == '*' && c == '/')
                   1301:                        eoc = 1;
                   1302:        }
1.18      lukem    1303: }
                   1304:
                   1305: /*
                   1306:  * Handle // style comments
                   1307:  */
                   1308: static void
1.19      lukem    1309: slashslashcomment(void)
1.18      lukem    1310: {
                   1311:        int c;
                   1312:
1.32      perry    1313:        if (!Sflag && !gflag)
1.21      wiz      1314:                /* // comments only supported in C99 */
1.18      lukem    1315:                (void)gnuism(312, tflag ? "traditional" : "ANSI");
                   1316:
                   1317:        while ((c = inpc()) != EOF && c != '\n')
                   1318:                continue;
1.7       jpo      1319: }
                   1320:
                   1321: /*
                   1322:  * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND.
                   1323:  * clrwflgs() is called after function definitions and global and
                   1324:  * local declarations and definitions. It is also called between
                   1325:  * the controlling expression and the body of control statements
                   1326:  * (if, switch, for, while).
                   1327:  */
                   1328: void
1.19      lukem    1329: clrwflgs(void)
1.7       jpo      1330: {
1.19      lukem    1331:
1.51      christos 1332:        lwarn = LWARN_ALL;
1.7       jpo      1333:        quadflg = 0;
                   1334:        ccflg = 0;
1.1       cgd      1335: }
                   1336:
                   1337: /*
                   1338:  * Strings are stored in a dynamically alloceted buffer and passed
                   1339:  * in yylval.y_xstrg to the parser. The parser or the routines called
                   1340:  * by the parser are responsible for freeing this buffer.
                   1341:  */
                   1342: static int
1.19      lukem    1343: string(void)
1.1       cgd      1344: {
                   1345:        u_char  *s;
                   1346:        int     c;
                   1347:        size_t  len, max;
                   1348:        strg_t  *strg;
                   1349:
                   1350:        s = xmalloc(max = 64);
                   1351:
                   1352:        len = 0;
                   1353:        while ((c = getescc('"')) >= 0) {
                   1354:                /* +1 to reserve space for a trailing NUL character */
                   1355:                if (len + 1 == max)
                   1356:                        s = xrealloc(s, max *= 2);
                   1357:                s[len++] = (char)c;
                   1358:        }
                   1359:        s[len] = '\0';
                   1360:        if (c == -2)
                   1361:                /* unterminated string constant */
                   1362:                error(258);
                   1363:
                   1364:        strg = xcalloc(1, sizeof (strg_t));
                   1365:        strg->st_tspec = CHAR;
                   1366:        strg->st_len = len;
                   1367:        strg->st_cp = s;
                   1368:
                   1369:        yylval.y_strg = strg;
                   1370:        return (T_STRING);
                   1371: }
                   1372:
                   1373: static int
1.19      lukem    1374: wcstrg(void)
1.1       cgd      1375: {
                   1376:        char    *s;
1.43      christos 1377:        int     c, n;
                   1378:        size_t  i, wi;
1.1       cgd      1379:        size_t  len, max, wlen;
                   1380:        wchar_t *ws;
                   1381:        strg_t  *strg;
                   1382:
                   1383:        s = xmalloc(max = 64);
                   1384:        len = 0;
                   1385:        while ((c = getescc('"')) >= 0) {
                   1386:                /* +1 to save space for a trailing NUL character */
                   1387:                if (len + 1 >= max)
                   1388:                        s = xrealloc(s, max *= 2);
                   1389:                s[len++] = (char)c;
                   1390:        }
                   1391:        s[len] = '\0';
                   1392:        if (c == -2)
                   1393:                /* unterminated string constant */
                   1394:                error(258);
                   1395:
1.48      wiz      1396:        /* get length of wide-character string */
1.1       cgd      1397:        (void)mblen(NULL, 0);
                   1398:        for (i = 0, wlen = 0; i < len; i += n, wlen++) {
                   1399:                if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) {
                   1400:                        /* invalid multibyte character */
                   1401:                        error(291);
                   1402:                        break;
                   1403:                }
                   1404:                if (n == 0)
                   1405:                        n = 1;
                   1406:        }
                   1407:
                   1408:        ws = xmalloc((wlen + 1) * sizeof (wchar_t));
                   1409:
                   1410:        /* convert from multibyte to wide char */
                   1411:        (void)mbtowc(NULL, NULL, 0);
                   1412:        for (i = 0, wi = 0; i < len; i += n, wi++) {
                   1413:                if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1)
                   1414:                        break;
                   1415:                if (n == 0)
                   1416:                        n = 1;
                   1417:        }
                   1418:        ws[wi] = 0;
                   1419:        free(s);
                   1420:
                   1421:        strg = xcalloc(1, sizeof (strg_t));
                   1422:        strg->st_tspec = WCHAR;
                   1423:        strg->st_len = wlen;
                   1424:        strg->st_wcp = ws;
                   1425:
                   1426:        yylval.y_strg = strg;
                   1427:        return (T_STRING);
                   1428: }
                   1429:
                   1430: /*
                   1431:  * As noted above the scanner does not create new symbol table entries
                   1432:  * for symbols it cannot find in the symbol table. This is to avoid
                   1433:  * putting undeclared symbols into the symbol table if a syntax error
                   1434:  * occurs.
                   1435:  *
                   1436:  * getsym() is called as soon as it is probably ok to put the symbol to
                   1437:  * the symbol table. This does not mean that it is not possible that
                   1438:  * symbols are put to the symbol table which are than not completely
                   1439:  * declared due to syntax errors. To avoid too many problems in this
                   1440:  * case symbols get type int in getsym().
                   1441:  *
                   1442:  * XXX calls to getsym() should be delayed until decl1*() is called
                   1443:  */
                   1444: sym_t *
1.19      lukem    1445: getsym(sbuf_t *sb)
1.1       cgd      1446: {
                   1447:        dinfo_t *di;
                   1448:        char    *s;
                   1449:        sym_t   *sym;
                   1450:
                   1451:        sym = sb->sb_sym;
                   1452:
                   1453:        /*
                   1454:         * During member declaration it is possible that name() looked
                   1455:         * for symbols of type FVFT, although it should have looked for
                   1456:         * symbols of type FTAG. Same can happen for labels. Both cases
                   1457:         * are compensated here.
                   1458:         */
                   1459:        if (symtyp == FMOS || symtyp == FLAB) {
                   1460:                if (sym == NULL || sym->s_kind == FVFT)
                   1461:                        sym = search(sb);
                   1462:        }
                   1463:
                   1464:        if (sym != NULL) {
                   1465:                if (sym->s_kind != symtyp)
1.56      christos 1466:                        LERROR("storesym(%d, %d)", sym->s_kind, symtyp);
1.1       cgd      1467:                symtyp = FVFT;
                   1468:                freesb(sb);
                   1469:                return (sym);
                   1470:        }
                   1471:
                   1472:        /* create a new symbol table entry */
                   1473:
                   1474:        /* labels must always be allocated at level 1 (outhermost block) */
                   1475:        if (symtyp == FLAB) {
                   1476:                sym = getlblk(1, sizeof (sym_t));
                   1477:                s = getlblk(1, sb->sb_len + 1);
                   1478:                (void)memcpy(s, sb->sb_name, sb->sb_len + 1);
                   1479:                sym->s_name = s;
                   1480:                sym->s_blklev = 1;
                   1481:                di = dcs;
1.3       jpo      1482:                while (di->d_nxt != NULL && di->d_nxt->d_nxt != NULL)
                   1483:                        di = di->d_nxt;
                   1484:                if (di->d_ctx != AUTO)
1.28      christos 1485:                        LERROR("storesym()");
1.1       cgd      1486:        } else {
                   1487:                sym = getblk(sizeof (sym_t));
                   1488:                sym->s_name = sb->sb_name;
                   1489:                sym->s_blklev = blklev;
                   1490:                di = dcs;
                   1491:        }
                   1492:
1.9       cgd      1493:        UNIQUE_CURR_POS(sym->s_dpos);
1.1       cgd      1494:        if ((sym->s_kind = symtyp) != FLAB)
                   1495:                sym->s_type = gettyp(INT);
                   1496:
                   1497:        symtyp = FVFT;
                   1498:
                   1499:        if ((sym->s_link = symtab[sb->sb_hash]) != NULL)
                   1500:                symtab[sb->sb_hash]->s_rlink = &sym->s_link;
1.53      christos 1501:        sym->s_rlink = &symtab[sb->sb_hash];
                   1502:        symtab[sb->sb_hash] = sym;
1.1       cgd      1503:
1.3       jpo      1504:        *di->d_ldlsym = sym;
                   1505:        di->d_ldlsym = &sym->s_dlnxt;
1.1       cgd      1506:
                   1507:        freesb(sb);
                   1508:        return (sym);
1.29      christos 1509: }
                   1510:
                   1511: /*
                   1512:  * Construct a temporary symbol. The symbol starts with a digit, so that
                   1513:  * it is illegal.
                   1514:  */
                   1515: sym_t *
                   1516: mktempsym(type_t *t)
                   1517: {
                   1518:        static int n = 0;
                   1519:        int h;
                   1520:        char *s = getlblk(blklev, 64);
                   1521:        sym_t *sym = getblk(sizeof (sym_t));
                   1522:
                   1523:        (void)snprintf(s, 64, "%.8d_tmp", n++);
                   1524:        h = hash(s);
1.30      christos 1525:
1.29      christos 1526:        sym->s_name = s;
                   1527:        sym->s_type = t;
                   1528:        sym->s_blklev = blklev;
                   1529:        sym->s_scl = AUTO;
1.30      christos 1530:        sym->s_kind = FVFT;
1.31      christos 1531:        sym->s_used = 1;
                   1532:        sym->s_set = 1;
1.30      christos 1533:
1.29      christos 1534:        if ((sym->s_link = symtab[h]) != NULL)
                   1535:                symtab[h]->s_rlink = &sym->s_link;
1.53      christos 1536:        sym->s_rlink = &symtab[h];
                   1537:        symtab[h] = sym;
1.30      christos 1538:
                   1539:        *dcs->d_ldlsym = sym;
                   1540:        dcs->d_ldlsym = &sym->s_dlnxt;
                   1541:
1.29      christos 1542:        return sym;
1.1       cgd      1543: }
                   1544:
                   1545: /*
                   1546:  * Remove a symbol forever from the symbol table. s_blklev
                   1547:  * is set to -1 to avoid that the symbol will later be put
                   1548:  * back to the symbol table.
                   1549:  */
                   1550: void
1.19      lukem    1551: rmsym(sym_t *sym)
1.1       cgd      1552: {
1.19      lukem    1553:
1.1       cgd      1554:        if ((*sym->s_rlink = sym->s_link) != NULL)
                   1555:                sym->s_link->s_rlink = sym->s_rlink;
                   1556:        sym->s_blklev = -1;
                   1557:        sym->s_link = NULL;
                   1558: }
                   1559:
                   1560: /*
                   1561:  * Remove a list of symbols declared at one level from the symbol
                   1562:  * table.
                   1563:  */
                   1564: void
1.19      lukem    1565: rmsyms(sym_t *syms)
1.1       cgd      1566: {
                   1567:        sym_t   *sym;
                   1568:
                   1569:        for (sym = syms; sym != NULL; sym = sym->s_dlnxt) {
                   1570:                if (sym->s_blklev != -1) {
                   1571:                        if ((*sym->s_rlink = sym->s_link) != NULL)
                   1572:                                sym->s_link->s_rlink = sym->s_rlink;
                   1573:                        sym->s_link = NULL;
                   1574:                        sym->s_rlink = NULL;
                   1575:                }
                   1576:        }
                   1577: }
                   1578:
                   1579: /*
                   1580:  * Put a symbol into the symbol table
                   1581:  */
                   1582: void
1.19      lukem    1583: inssym(int bl, sym_t *sym)
1.1       cgd      1584: {
                   1585:        int     h;
                   1586:
                   1587:        h = hash(sym->s_name);
                   1588:        if ((sym->s_link = symtab[h]) != NULL)
                   1589:                symtab[h]->s_rlink = &sym->s_link;
1.53      christos 1590:        sym->s_rlink = &symtab[h];
                   1591:        symtab[h] = sym;
1.1       cgd      1592:        sym->s_blklev = bl;
                   1593:        if (sym->s_link != NULL && sym->s_blklev < sym->s_link->s_blklev)
1.28      christos 1594:                LERROR("inssym()");
1.1       cgd      1595: }
                   1596:
                   1597: /*
                   1598:  * Called at level 0 after syntax errors
                   1599:  * Removes all symbols which are not declared at level 0 from the
                   1600:  * symbol table. Also frees all memory which is not associated with
                   1601:  * level 0.
                   1602:  */
                   1603: void
1.19      lukem    1604: cleanup(void)
1.1       cgd      1605: {
                   1606:        sym_t   *sym, *nsym;
                   1607:        int     i;
                   1608:
                   1609:        for (i = 0; i < HSHSIZ1; i++) {
                   1610:                for (sym = symtab[i]; sym != NULL; sym = nsym) {
                   1611:                        nsym = sym->s_link;
                   1612:                        if (sym->s_blklev >= 1) {
                   1613:                                if ((*sym->s_rlink = nsym) != NULL)
                   1614:                                        nsym->s_rlink = sym->s_rlink;
                   1615:                        }
                   1616:                }
                   1617:        }
                   1618:
                   1619:        for (i = mblklev; i > 0; i--)
                   1620:                freelblk(i);
                   1621: }
                   1622:
                   1623: /*
                   1624:  * Create a new symbol with the name of an existing symbol.
                   1625:  */
                   1626: sym_t *
1.19      lukem    1627: pushdown(sym_t *sym)
1.1       cgd      1628: {
                   1629:        int     h;
                   1630:        sym_t   *nsym;
                   1631:
                   1632:        h = hash(sym->s_name);
                   1633:        nsym = getblk(sizeof (sym_t));
                   1634:        if (sym->s_blklev > blklev)
1.28      christos 1635:                LERROR("pushdown()");
1.1       cgd      1636:        nsym->s_name = sym->s_name;
1.9       cgd      1637:        UNIQUE_CURR_POS(nsym->s_dpos);
1.1       cgd      1638:        nsym->s_kind = sym->s_kind;
                   1639:        nsym->s_blklev = blklev;
                   1640:
                   1641:        if ((nsym->s_link = symtab[h]) != NULL)
                   1642:                symtab[h]->s_rlink = &nsym->s_link;
1.53      christos 1643:        nsym->s_rlink = &symtab[h];
                   1644:        symtab[h] = nsym;
1.1       cgd      1645:
1.3       jpo      1646:        *dcs->d_ldlsym = nsym;
                   1647:        dcs->d_ldlsym = &nsym->s_dlnxt;
1.1       cgd      1648:
                   1649:        return (nsym);
1.6       jpo      1650: }
                   1651:
                   1652: /*
                   1653:  * Free any dynamically allocated memory referenced by
                   1654:  * the value stack or yylval.
                   1655:  * The type of information in yylval is described by tok.
                   1656:  */
                   1657: void
1.19      lukem    1658: freeyyv(void *sp, int tok)
1.6       jpo      1659: {
                   1660:        if (tok == T_NAME || tok == T_TYPENAME) {
                   1661:                sbuf_t *sb = *(sbuf_t **)sp;
                   1662:                freesb(sb);
                   1663:        } else if (tok == T_CON) {
                   1664:                val_t *val = *(val_t **)sp;
                   1665:                free(val);
                   1666:        } else if (tok == T_STRING) {
                   1667:                strg_t *strg = *(strg_t **)sp;
                   1668:                if (strg->st_tspec == CHAR) {
                   1669:                        free(strg->st_cp);
                   1670:                } else if (strg->st_tspec == WCHAR) {
                   1671:                        free(strg->st_wcp);
                   1672:                } else {
1.28      christos 1673:                        LERROR("fryylv()");
1.6       jpo      1674:                }
                   1675:                free(strg);
1.19      lukem    1676:        }
1.1       cgd      1677: }

CVSweb <webmaster@jp.NetBSD.org>