[BACK]Return to misc.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / lex

Annotation of src/usr.bin/lex/misc.c, Revision 1.20

1.20    ! jmc         1: /*     $OpenBSD: misc.c,v 1.19 2015/11/19 23:34:56 mmcc Exp $  */
1.2       deraadt     2:
1.1       deraadt     3: /* misc - miscellaneous flex routines */
                      4:
1.15      tedu        5: /*  Copyright (c) 1990 The Regents of the University of California. */
                      6: /*  All rights reserved. */
                      7:
                      8: /*  This code is derived from software contributed to Berkeley by */
                      9: /*  Vern Paxson. */
1.1       deraadt    10:
1.15      tedu       11: /*  The United States Government has rights in this work pursuant */
                     12: /*  to contract no. DE-AC03-76SF00098 between the United States */
                     13: /*  Department of Energy and the University of California. */
                     14:
                     15: /*  This file is part of flex. */
                     16:
                     17: /*  Redistribution and use in source and binary forms, with or without */
                     18: /*  modification, are permitted provided that the following conditions */
                     19: /*  are met: */
                     20:
                     21: /*  1. Redistributions of source code must retain the above copyright */
                     22: /*     notice, this list of conditions and the following disclaimer. */
                     23: /*  2. Redistributions in binary form must reproduce the above copyright */
                     24: /*     notice, this list of conditions and the following disclaimer in the */
                     25: /*     documentation and/or other materials provided with the distribution. */
                     26:
                     27: /*  Neither the name of the University nor the names of its contributors */
                     28: /*  may be used to endorse or promote products derived from this software */
                     29: /*  without specific prior written permission. */
                     30:
                     31: /*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
                     32: /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
                     33: /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
                     34: /*  PURPOSE. */
1.1       deraadt    35:
                     36: #include "flexdef.h"
1.15      tedu       37: #include "tables.h"
                     38:
                     39: #define CMD_IF_TABLES_SER    "%if-tables-serialization"
                     40: #define CMD_TABLES_YYDMAP    "%tables-yydmap"
                     41: #define CMD_DEFINE_YYTABLES  "%define-yytables"
                     42: #define CMD_IF_CPP_ONLY      "%if-c++-only"
                     43: #define CMD_IF_C_ONLY        "%if-c-only"
                     44: #define CMD_IF_C_OR_CPP      "%if-c-or-c++"
                     45: #define CMD_NOT_FOR_HEADER   "%not-for-header"
                     46: #define CMD_OK_FOR_HEADER    "%ok-for-header"
                     47: #define CMD_PUSH             "%push"
                     48: #define CMD_POP              "%pop"
                     49: #define CMD_IF_REENTRANT     "%if-reentrant"
                     50: #define CMD_IF_NOT_REENTRANT "%if-not-reentrant"
                     51: #define CMD_IF_BISON_BRIDGE  "%if-bison-bridge"
                     52: #define CMD_IF_NOT_BISON_BRIDGE  "%if-not-bison-bridge"
                     53: #define CMD_ENDIF            "%endif"
                     54:
                     55: /* we allow the skeleton to push and pop. */
                     56: struct sko_state {
1.16      tedu       57:        bool dc;                /**< do_copy */
1.15      tedu       58: };
1.16      tedu       59: static struct sko_state *sko_stack = 0;
                     60: static int sko_len = 0, sko_sz = 0;
                     61: static void
                     62: sko_push(bool dc)
                     63: {
                     64:        if (!sko_stack) {
                     65:                sko_sz = 1;
1.18      tedu       66:                sko_stack = malloc(sizeof(struct sko_state) * sko_sz);
1.16      tedu       67:                if (!sko_stack)
                     68:                        flexfatal(_("allocation of sko_stack failed"));
                     69:                sko_len = 0;
                     70:        }
                     71:        if (sko_len >= sko_sz) {
                     72:                sko_sz *= 2;
1.18      tedu       73:                sko_stack = realloc(sko_stack, sizeof(struct sko_state) * sko_sz);
1.16      tedu       74:        }
                     75:        /* initialize to zero and push */
                     76:        sko_stack[sko_len].dc = dc;
                     77:        sko_len++;
                     78: }
                     79: static void
                     80: sko_peek(bool * dc)
                     81: {
                     82:        if (sko_len <= 0)
                     83:                flex_die("peek attempt when sko stack is empty");
                     84:        if (dc)
                     85:                *dc = sko_stack[sko_len - 1].dc;
                     86: }
                     87: static void
                     88: sko_pop(bool * dc)
                     89: {
                     90:        sko_peek(dc);
                     91:        sko_len--;
                     92:        if (sko_len < 0)
                     93:                flex_die("popped too many times in skeleton.");
1.15      tedu       94: }
                     95:
                     96: /* Append "#define defname value\n" to the running buffer. */
1.16      tedu       97: void
                     98: action_define(defname, value)
                     99:        const char *defname;
                    100:        int value;
                    101: {
                    102:        char buf[MAXLINE];
                    103:        char *cpy;
                    104:
                    105:        if ((int) strlen(defname) > MAXLINE / 2) {
                    106:                format_pinpoint_message(_
                    107:                    ("name \"%s\" ridiculously long"),
                    108:                    defname);
1.15      tedu      109:                return;
                    110:        }
1.16      tedu      111:        snprintf(buf, sizeof(buf), "#define %s %d\n", defname, value);
                    112:        add_action(buf);
1.15      tedu      113:
                    114:        /* track #defines so we can undef them when we're done. */
1.16      tedu      115:        cpy = copy_string(defname);
                    116:        buf_append(&defs_buf, &cpy, 1);
1.15      tedu      117: }
1.1       deraadt   118:
                    119:
1.15      tedu      120: /** Append "m4_define([[defname]],[[value]])m4_dnl\n" to the running buffer.
                    121:  *  @param defname The macro name.
                    122:  *  @param value The macro value, can be NULL, which is the same as the empty string.
                    123:  */
1.16      tedu      124: void
                    125: action_m4_define(const char *defname, const char *value)
1.15      tedu      126: {
1.16      tedu      127:        char buf[MAXLINE];
1.15      tedu      128:
1.16      tedu      129:        flexfatal("DO NOT USE THIS FUNCTION!");
1.15      tedu      130:
1.16      tedu      131:        if ((int) strlen(defname) > MAXLINE / 2) {
                    132:                format_pinpoint_message(_
                    133:                    ("name \"%s\" ridiculously long"),
                    134:                    defname);
1.1       deraadt   135:                return;
                    136:        }
1.16      tedu      137:        snprintf(buf, sizeof(buf), "m4_define([[%s]],[[%s]])m4_dnl\n", defname, value ? value : "");
                    138:        add_action(buf);
1.15      tedu      139: }
                    140:
                    141: /* Append "new_text" to the running buffer. */
1.16      tedu      142: void
                    143: add_action(new_text)
                    144:        const char *new_text;
1.15      tedu      145: {
1.16      tedu      146:        int len = strlen(new_text);
1.1       deraadt   147:
1.15      tedu      148:        while (len + action_index >= action_size - 10 /* slop */ ) {
1.16      tedu      149:                int new_size = action_size * 2;
1.1       deraadt   150:
1.15      tedu      151:                if (new_size <= 0)
1.16      tedu      152:                        /*
                    153:                         * Increase just a little, to try to avoid overflow
1.1       deraadt   154:                         * on 16-bit machines.
                    155:                         */
                    156:                        action_size += action_size / 8;
                    157:                else
                    158:                        action_size = new_size;
                    159:
                    160:                action_array =
1.16      tedu      161:                    reallocate_character_array(action_array,
                    162:                    action_size);
1.15      tedu      163:        }
1.1       deraadt   164:
1.16      tedu      165:        strlcpy(&action_array[action_index], new_text,
                    166:            action_size - action_index);
1.1       deraadt   167:
                    168:        action_index += len;
1.15      tedu      169: }
1.1       deraadt   170:
                    171:
                    172: /* allocate_array - allocate memory for an integer array of the given size */
                    173:
1.16      tedu      174: void *
                    175: allocate_array(size, element_size)
                    176:        int size;
                    177:        size_t element_size;
1.15      tedu      178: {
1.6       mpech     179:        void *mem;
1.16      tedu      180:        size_t num_bytes = element_size * size;
1.1       deraadt   181:
1.18      tedu      182:        mem = malloc(num_bytes);
1.15      tedu      183:        if (!mem)
1.16      tedu      184:                flexfatal(_
                    185:                    ("memory allocation failed in allocate_array()"));
1.1       deraadt   186:
                    187:        return mem;
1.15      tedu      188: }
1.1       deraadt   189:
                    190:
                    191: /* all_lower - true if a string is all lower-case */
                    192:
1.16      tedu      193: int
                    194: all_lower(str)
                    195:        char *str;
1.15      tedu      196: {
                    197:        while (*str) {
1.19      mmcc      198:                if (!isascii((u_char) * str) || !islower((u_char) * str))
1.1       deraadt   199:                        return 0;
                    200:                ++str;
1.15      tedu      201:        }
1.1       deraadt   202:
                    203:        return 1;
1.15      tedu      204: }
1.1       deraadt   205:
                    206:
                    207: /* all_upper - true if a string is all upper-case */
                    208:
1.16      tedu      209: int
                    210: all_upper(str)
                    211:        char *str;
1.15      tedu      212: {
                    213:        while (*str) {
1.19      mmcc      214:                if (!isascii((u_char) * str) || !isupper((u_char) * str))
1.1       deraadt   215:                        return 0;
                    216:                ++str;
1.15      tedu      217:        }
1.1       deraadt   218:
                    219:        return 1;
1.15      tedu      220: }
                    221:
1.1       deraadt   222:
1.15      tedu      223: /* intcmp - compares two integers for use by qsort. */
1.1       deraadt   224:
1.16      tedu      225: int
                    226: intcmp(const void *a, const void *b)
1.15      tedu      227: {
1.16      tedu      228:        return *(const int *) a - *(const int *) b;
1.15      tedu      229: }
1.1       deraadt   230:
                    231:
                    232: /* check_char - checks a character to make sure it's within the range
                    233:  *             we're expecting.  If not, generates fatal error message
                    234:  *             and exits.
                    235:  */
                    236:
1.16      tedu      237: void
                    238: check_char(c)
                    239:        int c;
1.15      tedu      240: {
                    241:        if (c >= CSIZE)
1.16      tedu      242:                lerrsf(_("bad character '%s' detected in check_char()"),
                    243:                    readable_form(c));
1.15      tedu      244:
                    245:        if (c >= csize)
1.16      tedu      246:                lerrsf(_
                    247:                    ("scanner requires -8 flag to use the character %s"),
                    248:                    readable_form(c));
1.15      tedu      249: }
1.1       deraadt   250:
                    251:
                    252:
                    253: /* clower - replace upper-case letter to lower-case */
                    254:
1.19      mmcc      255: u_char
1.16      tedu      256: clower(c)
                    257:        int c;
1.15      tedu      258: {
1.19      mmcc      259:        return (u_char) ((isascii(c) && isupper(c)) ? tolower(c) : c);
1.15      tedu      260: }
1.1       deraadt   261:
                    262:
                    263: /* copy_string - returns a dynamically allocated copy of a string */
                    264:
1.16      tedu      265: char *
                    266: copy_string(str)
                    267:        const char *str;
1.15      tedu      268: {
1.6       mpech     269:        const char *c1;
                    270:        char *c2;
1.16      tedu      271:        char *copy;
1.1       deraadt   272:        unsigned int size;
                    273:
                    274:        /* find length */
1.16      tedu      275:        for (c1 = str; *c1; ++c1);
1.15      tedu      276:
1.16      tedu      277:        size = (c1 - str + 1) * sizeof(char);
1.1       deraadt   278:
1.18      tedu      279:        copy = (char *) malloc(size);
1.1       deraadt   280:
1.15      tedu      281:        if (copy == NULL)
1.16      tedu      282:                flexfatal(_("dynamic memory failure in copy_string()"));
1.1       deraadt   283:
1.16      tedu      284:        for (c2 = copy; (*c2++ = *str++) != 0;);
1.1       deraadt   285:
                    286:        return copy;
1.15      tedu      287: }
1.1       deraadt   288:
                    289:
                    290: /* copy_unsigned_string -
                    291:  *    returns a dynamically allocated copy of a (potentially) unsigned string
                    292:  */
                    293:
1.19      mmcc      294: u_char *
1.16      tedu      295: copy_unsigned_string(str)
1.19      mmcc      296:        u_char *str;
1.15      tedu      297: {
1.19      mmcc      298:        u_char *c;
                    299:        u_char *copy;
1.1       deraadt   300:
                    301:        /* find length */
1.16      tedu      302:        for (c = str; *c; ++c);
1.1       deraadt   303:
1.16      tedu      304:        copy = allocate_Character_array(c - str + 1);
1.1       deraadt   305:
1.16      tedu      306:        for (c = copy; (*c++ = *str++) != 0;);
1.1       deraadt   307:
                    308:        return copy;
1.15      tedu      309: }
                    310:
1.1       deraadt   311:
1.15      tedu      312: /* cclcmp - compares two characters for use by qsort with '\0' sorting last. */
1.1       deraadt   313:
1.16      tedu      314: int
                    315: cclcmp(const void *a, const void *b)
1.15      tedu      316: {
1.19      mmcc      317:        if (!*(const u_char *) a)
1.16      tedu      318:                return 1;
1.19      mmcc      319:        else if (!*(const u_char *) b)
1.16      tedu      320:                return -1;
1.15      tedu      321:        else
1.19      mmcc      322:                return *(const u_char *) a - *(const u_char *) b;
1.15      tedu      323: }
1.1       deraadt   324:
                    325:
                    326: /* dataend - finish up a block of data declarations */
                    327:
1.16      tedu      328: void
                    329: dataend()
1.15      tedu      330: {
                    331:        /* short circuit any output */
                    332:        if (gentables) {
1.1       deraadt   333:
1.15      tedu      334:                if (datapos > 0)
1.16      tedu      335:                        dataflush();
1.1       deraadt   336:
1.15      tedu      337:                /* add terminator for initialization; { for vi */
1.16      tedu      338:                outn("    } ;\n");
1.15      tedu      339:        }
1.1       deraadt   340:        dataline = 0;
                    341:        datapos = 0;
1.15      tedu      342: }
1.1       deraadt   343:
                    344:
                    345: /* dataflush - flush generated data statements */
                    346:
1.16      tedu      347: void
                    348: dataflush()
1.15      tedu      349: {
                    350:        /* short circuit any output */
                    351:        if (!gentables)
                    352:                return;
                    353:
1.16      tedu      354:        outc('\n');
1.1       deraadt   355:
1.15      tedu      356:        if (++dataline >= NUMDATALINES) {
1.16      tedu      357:                /*
                    358:                 * Put out a blank line so that the table is grouped into
1.1       deraadt   359:                 * large blocks that enable the user to find elements easily.
                    360:                 */
1.16      tedu      361:                outc('\n');
1.1       deraadt   362:                dataline = 0;
1.15      tedu      363:        }
1.1       deraadt   364:        /* Reset the number of characters written on the current line. */
                    365:        datapos = 0;
1.15      tedu      366: }
1.1       deraadt   367:
                    368:
                    369: /* flexerror - report an error message and terminate */
                    370:
1.16      tedu      371: void
                    372: flexerror(msg)
                    373:        const char *msg;
1.15      tedu      374: {
1.16      tedu      375:        fprintf(stderr, "%s: %s\n", program_name, msg);
                    376:        flexend(1);
1.15      tedu      377: }
1.1       deraadt   378:
                    379:
                    380: /* flexfatal - report a fatal error message and terminate */
                    381:
1.16      tedu      382: void
                    383: flexfatal(msg)
                    384:        const char *msg;
                    385: {
                    386:        fprintf(stderr, _("%s: fatal internal error, %s\n"),
                    387:            program_name, msg);
                    388:        FLEX_EXIT(1);
1.15      tedu      389: }
1.1       deraadt   390:
                    391:
                    392: /* htoi - convert a hexadecimal digit string to an integer value */
                    393:
1.16      tedu      394: int
                    395: htoi(str)
1.19      mmcc      396:        u_char str[];
1.15      tedu      397: {
1.1       deraadt   398:        unsigned int result;
                    399:
1.16      tedu      400:        (void) sscanf((char *) str, "%x", &result);
1.1       deraadt   401:
                    402:        return result;
1.15      tedu      403: }
1.1       deraadt   404:
                    405:
                    406: /* lerrif - report an error message formatted with one integer argument */
                    407:
1.16      tedu      408: void
                    409: lerrif(msg, arg)
                    410:        const char *msg;
                    411:        int arg;
1.15      tedu      412: {
1.16      tedu      413:        char errmsg[MAXLINE];
1.15      tedu      414:
1.16      tedu      415:        snprintf(errmsg, sizeof(errmsg), msg, arg);
                    416:        flexerror(errmsg);
1.15      tedu      417: }
1.1       deraadt   418:
                    419:
                    420: /* lerrsf - report an error message formatted with one string argument */
                    421:
1.16      tedu      422: void
                    423: lerrsf(msg, arg)
1.15      tedu      424:        const char *msg, arg[];
                    425: {
1.16      tedu      426:        char errmsg[MAXLINE];
1.15      tedu      427:
1.16      tedu      428:        snprintf(errmsg, sizeof(errmsg) - 1, msg, arg);
                    429:        errmsg[sizeof(errmsg) - 1] = 0; /* ensure NULL termination */
                    430:        flexerror(errmsg);
1.15      tedu      431: }
                    432:
                    433:
                    434: /* lerrsf_fatal - as lerrsf, but call flexfatal */
                    435:
1.16      tedu      436: void
                    437: lerrsf_fatal(msg, arg)
1.15      tedu      438:        const char *msg, arg[];
                    439: {
1.16      tedu      440:        char errmsg[MAXLINE];
1.15      tedu      441:
1.16      tedu      442:        snprintf(errmsg, sizeof(errmsg) - 1, msg, arg);
                    443:        errmsg[sizeof(errmsg) - 1] = 0; /* ensure NULL termination */
                    444:        flexfatal(errmsg);
1.15      tedu      445: }
1.1       deraadt   446:
                    447:
                    448: /* line_directive_out - spit out a "#line" statement */
                    449:
1.16      tedu      450: void
                    451: line_directive_out(output_file, do_infile)
                    452:        FILE *output_file;
                    453:        int do_infile;
1.15      tedu      454: {
1.16      tedu      455:        char directive[MAXLINE], filename[MAXLINE];
                    456:        char *s1, *s2, *s3;
1.15      tedu      457:        static const char *line_fmt = "#line %d \"%s\"\n";
1.1       deraadt   458:
1.15      tedu      459:        if (!gen_line_dirs)
1.1       deraadt   460:                return;
                    461:
1.15      tedu      462:        s1 = do_infile ? infilename : "M4_YY_OUTFILE_NAME";
1.1       deraadt   463:
1.15      tedu      464:        if (do_infile && !s1)
1.16      tedu      465:                s1 = "<stdin>";
                    466:
1.1       deraadt   467:        s2 = filename;
1.16      tedu      468:        s3 = &filename[sizeof(filename) - 2];
1.1       deraadt   469:
1.15      tedu      470:        while (s2 < s3 && *s1) {
                    471:                if (*s1 == '\\')
1.1       deraadt   472:                        /* Escape the '\' */
                    473:                        *s2++ = '\\';
                    474:
                    475:                *s2++ = *s1++;
1.15      tedu      476:        }
1.1       deraadt   477:
                    478:        *s2 = '\0';
                    479:
1.15      tedu      480:        if (do_infile)
1.16      tedu      481:                snprintf(directive, sizeof(directive), line_fmt, linenum, filename);
1.15      tedu      482:        else {
1.16      tedu      483:                snprintf(directive, sizeof(directive), line_fmt, 0, filename);
1.15      tedu      484:        }
1.1       deraadt   485:
1.16      tedu      486:        /*
                    487:         * If output_file is nil then we should put the directive in the
                    488:         * accumulated actions.
1.1       deraadt   489:         */
1.15      tedu      490:        if (output_file) {
1.16      tedu      491:                fputs(directive, output_file);
                    492:        } else
                    493:                add_action(directive);
1.15      tedu      494: }
1.1       deraadt   495:
                    496:
                    497: /* mark_defs1 - mark the current position in the action array as
                    498:  *               representing where the user's section 1 definitions end
                    499:  *              and the prolog begins
                    500:  */
1.16      tedu      501: void
                    502: mark_defs1()
1.15      tedu      503: {
1.1       deraadt   504:        defs1_offset = 0;
                    505:        action_array[action_index++] = '\0';
                    506:        action_offset = prolog_offset = action_index;
                    507:        action_array[action_index] = '\0';
1.15      tedu      508: }
1.1       deraadt   509:
                    510:
                    511: /* mark_prolog - mark the current position in the action array as
                    512:  *               representing the end of the action prolog
                    513:  */
1.16      tedu      514: void
                    515: mark_prolog()
1.15      tedu      516: {
1.1       deraadt   517:        action_array[action_index++] = '\0';
                    518:        action_offset = action_index;
                    519:        action_array[action_index] = '\0';
1.15      tedu      520: }
1.1       deraadt   521:
                    522:
                    523: /* mk2data - generate a data statement for a two-dimensional array
                    524:  *
                    525:  * Generates a data statement initializing the current 2-D array to "value".
                    526:  */
1.16      tedu      527: void
                    528: mk2data(value)
                    529:        int value;
1.15      tedu      530: {
                    531:        /* short circuit any output */
                    532:        if (!gentables)
                    533:                return;
                    534:
                    535:        if (datapos >= NUMDATAITEMS) {
1.16      tedu      536:                outc(',');
                    537:                dataflush();
1.15      tedu      538:        }
                    539:        if (datapos == 0)
1.1       deraadt   540:                /* Indent. */
1.16      tedu      541:                out("    ");
1.1       deraadt   542:
                    543:        else
1.16      tedu      544:                outc(',');
1.1       deraadt   545:
                    546:        ++datapos;
                    547:
1.16      tedu      548:        out_dec("%5d", value);
1.15      tedu      549: }
1.1       deraadt   550:
                    551:
                    552: /* mkdata - generate a data statement
                    553:  *
                    554:  * Generates a data statement initializing the current array element to
                    555:  * "value".
                    556:  */
1.16      tedu      557: void
                    558: mkdata(value)
                    559:        int value;
1.15      tedu      560: {
                    561:        /* short circuit any output */
                    562:        if (!gentables)
                    563:                return;
                    564:
                    565:        if (datapos >= NUMDATAITEMS) {
1.16      tedu      566:                outc(',');
                    567:                dataflush();
1.15      tedu      568:        }
                    569:        if (datapos == 0)
1.1       deraadt   570:                /* Indent. */
1.16      tedu      571:                out("    ");
1.1       deraadt   572:        else
1.16      tedu      573:                outc(',');
1.1       deraadt   574:
                    575:        ++datapos;
                    576:
1.16      tedu      577:        out_dec("%5d", value);
1.15      tedu      578: }
1.1       deraadt   579:
                    580:
                    581: /* myctoi - return the integer represented by a string of digits */
                    582:
1.16      tedu      583: int
                    584: myctoi(array)
                    585:        const char *array;
1.15      tedu      586: {
1.16      tedu      587:        int val = 0;
1.1       deraadt   588:
1.16      tedu      589:        (void) sscanf(array, "%d", &val);
1.1       deraadt   590:
                    591:        return val;
1.15      tedu      592: }
1.1       deraadt   593:
                    594:
                    595: /* myesc - return character corresponding to escape sequence */
                    596:
1.19      mmcc      597: u_char
1.16      tedu      598: myesc(array)
1.19      mmcc      599:        u_char array[];
1.15      tedu      600: {
1.19      mmcc      601:        u_char c, esc_char;
1.15      tedu      602:
                    603:        switch (array[1]) {
                    604:        case 'b':
                    605:                return '\b';
                    606:        case 'f':
                    607:                return '\f';
                    608:        case 'n':
                    609:                return '\n';
                    610:        case 'r':
                    611:                return '\r';
                    612:        case 't':
                    613:                return '\t';
                    614:
                    615: #if defined (__STDC__)
                    616:        case 'a':
                    617:                return '\a';
                    618:        case 'v':
                    619:                return '\v';
1.1       deraadt   620: #else
1.15      tedu      621:        case 'a':
                    622:                return '\007';
                    623:        case 'v':
                    624:                return '\013';
1.1       deraadt   625: #endif
                    626:
1.15      tedu      627:        case '0':
                    628:        case '1':
                    629:        case '2':
                    630:        case '3':
                    631:        case '4':
                    632:        case '5':
                    633:        case '6':
                    634:        case '7':
                    635:                {               /* \<octal> */
1.16      tedu      636:                        int sptr = 1;
1.1       deraadt   637:
1.16      tedu      638:                        while (isascii(array[sptr]) &&
                    639:                            isdigit(array[sptr]))
                    640:                                /*
                    641:                                 * Don't increment inside loop control
1.1       deraadt   642:                                 * because if isdigit() is a macro it might
                    643:                                 * expand into multiple increments ...
                    644:                                 */
                    645:                                ++sptr;
                    646:
                    647:                        c = array[sptr];
                    648:                        array[sptr] = '\0';
                    649:
1.16      tedu      650:                        esc_char = otoi(array + 1);
1.1       deraadt   651:
                    652:                        array[sptr] = c;
                    653:
                    654:                        return esc_char;
1.15      tedu      655:                }
1.1       deraadt   656:
1.15      tedu      657:        case 'x':
                    658:                {               /* \x<hex> */
1.16      tedu      659:                        int sptr = 2;
1.1       deraadt   660:
1.16      tedu      661:                        while (isascii(array[sptr]) &&
                    662:                            isxdigit(array[sptr]))
                    663:                                /*
                    664:                                 * Don't increment inside loop control
1.1       deraadt   665:                                 * because if isdigit() is a macro it might
                    666:                                 * expand into multiple increments ...
                    667:                                 */
                    668:                                ++sptr;
                    669:
                    670:                        c = array[sptr];
                    671:                        array[sptr] = '\0';
                    672:
1.16      tedu      673:                        esc_char = htoi(array + 2);
1.1       deraadt   674:
                    675:                        array[sptr] = c;
                    676:
                    677:                        return esc_char;
1.15      tedu      678:                }
1.1       deraadt   679:
1.15      tedu      680:        default:
                    681:                return array[1];
1.1       deraadt   682:        }
1.15      tedu      683: }
1.1       deraadt   684:
                    685:
                    686: /* otoi - convert an octal digit string to an integer value */
                    687:
1.16      tedu      688: int
                    689: otoi(str)
1.19      mmcc      690:        u_char str[];
1.15      tedu      691: {
1.1       deraadt   692:        unsigned int result;
                    693:
1.16      tedu      694:        (void) sscanf((char *) str, "%o", &result);
1.1       deraadt   695:        return result;
1.15      tedu      696: }
1.1       deraadt   697:
                    698:
1.20    ! jmc       699: /* out - various flavors of outputting a (possibly formatted) string for the
1.1       deraadt   700:  *      generated scanner, keeping track of the line count.
                    701:  */
                    702:
1.16      tedu      703: void
                    704: out(str)
                    705:        const char *str;
1.15      tedu      706: {
1.16      tedu      707:        fputs(str, stdout);
1.15      tedu      708: }
                    709:
1.16      tedu      710: void
                    711: out_dec(fmt, n)
                    712:        const char *fmt;
                    713:        int n;
1.15      tedu      714: {
1.16      tedu      715:        fprintf(stdout, fmt, n);
1.15      tedu      716: }
                    717:
1.16      tedu      718: void
                    719: out_dec2(fmt, n1, n2)
                    720:        const char *fmt;
                    721:        int n1, n2;
1.15      tedu      722: {
1.16      tedu      723:        fprintf(stdout, fmt, n1, n2);
1.15      tedu      724: }
                    725:
1.16      tedu      726: void
                    727: out_hex(fmt, x)
                    728:        const char *fmt;
                    729:        unsigned int x;
1.15      tedu      730: {
1.16      tedu      731:        fprintf(stdout, fmt, x);
1.15      tedu      732: }
                    733:
1.16      tedu      734: void
                    735: out_str(fmt, str)
                    736:        const char *fmt, str[];
1.15      tedu      737: {
1.16      tedu      738:        fprintf(stdout, fmt, str);
1.15      tedu      739: }
                    740:
1.16      tedu      741: void
                    742: out_str3(fmt, s1, s2, s3)
                    743:        const char *fmt, s1[], s2[], s3[];
1.15      tedu      744: {
1.16      tedu      745:        fprintf(stdout, fmt, s1, s2, s3);
1.15      tedu      746: }
                    747:
1.16      tedu      748: void
                    749: out_str_dec(fmt, str, n)
                    750:        const char *fmt, str[];
                    751:        int n;
1.15      tedu      752: {
1.16      tedu      753:        fprintf(stdout, fmt, str, n);
1.15      tedu      754: }
                    755:
1.16      tedu      756: void
                    757: outc(c)
                    758:        int c;
1.15      tedu      759: {
1.16      tedu      760:        fputc(c, stdout);
1.15      tedu      761: }
                    762:
1.16      tedu      763: void
                    764: outn(str)
                    765:        const char *str;
1.15      tedu      766: {
1.16      tedu      767:        fputs(str, stdout);
                    768:        fputc('\n', stdout);
1.15      tedu      769: }
                    770:
                    771: /** Print "m4_define( [[def]], [[val]])m4_dnl\n".
                    772:  * @param def The m4 symbol to define.
                    773:  * @param val The definition; may be NULL.
                    774:  * @return buf
                    775:  */
1.16      tedu      776: void
                    777: out_m4_define(const char *def, const char *val)
1.15      tedu      778: {
1.16      tedu      779:        const char *fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n";
                    780:        fprintf(stdout, fmt, def, val ? val : "");
1.15      tedu      781: }
1.1       deraadt   782:
                    783:
1.12      miod      784: /* readable_form - return the human-readable form of a character
1.1       deraadt   785:  *
                    786:  * The returned string is in static storage.
                    787:  */
                    788:
1.16      tedu      789: char *
                    790: readable_form(c)
                    791:        int c;
1.15      tedu      792: {
1.1       deraadt   793:        static char rform[10];
                    794:
1.15      tedu      795:        if ((c >= 0 && c < 32) || c >= 127) {
                    796:                switch (c) {
                    797:                case '\b':
                    798:                        return "\\b";
                    799:                case '\f':
                    800:                        return "\\f";
                    801:                case '\n':
                    802:                        return "\\n";
                    803:                case '\r':
                    804:                        return "\\r";
                    805:                case '\t':
                    806:                        return "\\t";
                    807:
                    808: #if defined (__STDC__)
                    809:                case '\a':
                    810:                        return "\\a";
                    811:                case '\v':
                    812:                        return "\\v";
1.1       deraadt   813: #endif
                    814:
1.15      tedu      815:                default:
1.16      tedu      816:                        snprintf(rform, sizeof(rform), "\\%.3o", (unsigned int) c);
1.15      tedu      817:                        return rform;
1.1       deraadt   818:                }
1.16      tedu      819:        } else if (c == ' ')
1.1       deraadt   820:                return "' '";
                    821:
1.15      tedu      822:        else {
1.1       deraadt   823:                rform[0] = c;
                    824:                rform[1] = '\0';
                    825:
                    826:                return rform;
                    827:        }
1.15      tedu      828: }
1.1       deraadt   829:
                    830:
                    831: /* reallocate_array - increase the size of a dynamic array */
                    832:
1.16      tedu      833: void *
                    834: reallocate_array(array, size, element_size)
                    835:        void *array;
                    836:        int size;
                    837:        size_t element_size;
1.15      tedu      838: {
1.6       mpech     839:        void *new_array;
1.16      tedu      840:        size_t num_bytes = element_size * size;
1.1       deraadt   841:
1.18      tedu      842:        new_array = realloc(array, num_bytes);
1.15      tedu      843:        if (!new_array)
1.16      tedu      844:                flexfatal(_("attempt to increase array size failed"));
1.1       deraadt   845:
                    846:        return new_array;
1.15      tedu      847: }
1.1       deraadt   848:
                    849:
                    850: /* skelout - write out one section of the skeleton file
                    851:  *
                    852:  * Description
                    853:  *    Copies skelfile or skel array to stdout until a line beginning with
                    854:  *    "%%" or EOF is found.
                    855:  */
1.16      tedu      856: void
                    857: skelout()
1.15      tedu      858: {
1.16      tedu      859:        char buf_storage[MAXLINE];
                    860:        char *buf = buf_storage;
                    861:        bool do_copy = true;
                    862:
                    863:        /* "reset" the state by clearing the buffer and pushing a '1' */
                    864:        if (sko_len > 0)
                    865:                sko_peek(&do_copy);
                    866:        sko_len = 0;
                    867:        sko_push(do_copy = true);
                    868:
                    869:
                    870:        /*
                    871:         * Loop pulling lines either from the skelfile, if we're using one,
                    872:         * or from the skel[] array.
1.1       deraadt   873:         */
1.15      tedu      874:        while (skelfile ?
1.16      tedu      875:            (fgets(buf, MAXLINE, skelfile) != NULL) :
                    876:            ((buf = (char *) skel[skel_ind++]) != 0)) {
1.15      tedu      877:
                    878:                if (skelfile)
1.16      tedu      879:                        chomp(buf);
1.15      tedu      880:
                    881:                /* copy from skel array */
                    882:                if (buf[0] == '%') {    /* control line */
                    883:                        /* print the control line as a comment. */
                    884:                        if (ddebug && buf[1] != '#') {
1.16      tedu      885:                                if (buf[strlen(buf) - 1] == '\\')
                    886:                                        out_str("/* %s */\\\n", buf);
1.15      tedu      887:                                else
1.16      tedu      888:                                        out_str("/* %s */\n", buf);
1.15      tedu      889:                        }
1.16      tedu      890:                        /*
                    891:                         * We've been accused of using cryptic markers in the
                    892:                         * skel. So we'll use
                    893:                         * emacs-style-hyphenated-commands. We might consider
                    894:                         * a hash if this if-else-if-else chain gets too
                    895:                         * large.
1.15      tedu      896:                         */
                    897: #define cmd_match(s) (strncmp(buf,(s),strlen(s))==0)
                    898:
                    899:                        if (buf[1] == '%') {
                    900:                                /* %% is a break point for skelout() */
                    901:                                return;
1.16      tedu      902:                        } else if (cmd_match(CMD_PUSH)) {
                    903:                                sko_push(do_copy);
                    904:                                if (ddebug) {
                    905:                                        out_str("/*(state = (%s) */", do_copy ? "true" : "false");
                    906:                                }
                    907:                                out_str("%s\n", buf[strlen(buf) - 1] == '\\' ? "\\" : "");
                    908:                        } else if (cmd_match(CMD_POP)) {
                    909:                                sko_pop(&do_copy);
                    910:                                if (ddebug) {
                    911:                                        out_str("/*(state = (%s) */", do_copy ? "true" : "false");
                    912:                                }
                    913:                                out_str("%s\n", buf[strlen(buf) - 1] == '\\' ? "\\" : "");
                    914:                        } else if (cmd_match(CMD_IF_REENTRANT)) {
                    915:                                sko_push(do_copy);
                    916:                                do_copy = reentrant && do_copy;
                    917:                        } else if (cmd_match(CMD_IF_NOT_REENTRANT)) {
                    918:                                sko_push(do_copy);
                    919:                                do_copy = !reentrant && do_copy;
                    920:                        } else if (cmd_match(CMD_IF_BISON_BRIDGE)) {
                    921:                                sko_push(do_copy);
                    922:                                do_copy = bison_bridge_lval && do_copy;
                    923:                        } else if (cmd_match(CMD_IF_NOT_BISON_BRIDGE)) {
                    924:                                sko_push(do_copy);
                    925:                                do_copy = !bison_bridge_lval && do_copy;
                    926:                        } else if (cmd_match(CMD_ENDIF)) {
                    927:                                sko_pop(&do_copy);
                    928:                        } else if (cmd_match(CMD_IF_TABLES_SER)) {
                    929:                                do_copy = do_copy && tablesext;
                    930:                        } else if (cmd_match(CMD_TABLES_YYDMAP)) {
1.15      tedu      931:                                if (tablesext && yydmap_buf.elts)
1.16      tedu      932:                                        outn((char *) (yydmap_buf.elts));
                    933:                        } else if (cmd_match(CMD_DEFINE_YYTABLES)) {
                    934:                                out_str("#define YYTABLES_NAME \"%s\"\n",
                    935:                                    tablesname ? tablesname : "yytables");
                    936:                        } else if (cmd_match(CMD_IF_CPP_ONLY)) {
1.15      tedu      937:                                /* only for C++ */
1.16      tedu      938:                                sko_push(do_copy);
1.15      tedu      939:                                do_copy = C_plus_plus;
1.16      tedu      940:                        } else if (cmd_match(CMD_IF_C_ONLY)) {
1.15      tedu      941:                                /* %- only for C */
1.16      tedu      942:                                sko_push(do_copy);
1.15      tedu      943:                                do_copy = !C_plus_plus;
1.16      tedu      944:                        } else if (cmd_match(CMD_IF_C_OR_CPP)) {
1.15      tedu      945:                                /* %* for C and C++ */
1.16      tedu      946:                                sko_push(do_copy);
1.15      tedu      947:                                do_copy = true;
1.16      tedu      948:                        } else if (cmd_match(CMD_NOT_FOR_HEADER)) {
1.15      tedu      949:                                /* %c begin linkage-only (non-header) code. */
1.16      tedu      950:                                OUT_BEGIN_CODE();
                    951:                        } else if (cmd_match(CMD_OK_FOR_HEADER)) {
1.15      tedu      952:                                /* %e end linkage-only code. */
1.16      tedu      953:                                OUT_END_CODE();
                    954:                        } else if (buf[1] == '#') {
1.15      tedu      955:                                /* %# a comment in the skel. ignore. */
1.16      tedu      956:                        } else {
                    957:                                flexfatal(_("bad line in skeleton file"));
1.15      tedu      958:                        }
1.16      tedu      959:                } else if (do_copy)
                    960:                        outn(buf);
1.15      tedu      961:        }                       /* end while */
                    962: }
1.1       deraadt   963:
                    964:
                    965: /* transition_struct_out - output a yy_trans_info structure
                    966:  *
                    967:  * outputs the yy_trans_info structure with the two elements, element_v and
                    968:  * element_n.  Formats the output with spaces and carriage returns.
                    969:  */
                    970:
1.16      tedu      971: void
                    972: transition_struct_out(element_v, element_n)
                    973:        int element_v, element_n;
1.15      tedu      974: {
                    975:
                    976:        /* short circuit any output */
                    977:        if (!gentables)
                    978:                return;
                    979:
1.16      tedu      980:        out_dec2(" {%4d,%4d },", element_v, element_n);
1.1       deraadt   981:
                    982:        datapos += TRANS_STRUCT_PRINT_LENGTH;
                    983:
1.15      tedu      984:        if (datapos >= 79 - TRANS_STRUCT_PRINT_LENGTH) {
1.16      tedu      985:                outc('\n');
1.1       deraadt   986:
1.15      tedu      987:                if (++dataline % 10 == 0)
1.16      tedu      988:                        outc('\n');
1.1       deraadt   989:
                    990:                datapos = 0;
                    991:        }
1.15      tedu      992: }
1.1       deraadt   993:
                    994:
                    995: /* The following is only needed when building flex's parser using certain
                    996:  * broken versions of bison.
                    997:  */
1.16      tedu      998: void *
                    999: yy_flex_xmalloc(size)
                   1000:        int size;
1.15      tedu     1001: {
1.18      tedu     1002:        void *result = malloc((size_t) size);
1.15      tedu     1003:
                   1004:        if (!result)
1.16      tedu     1005:                flexfatal(_
                   1006:                    ("memory allocation failed in yy_flex_xmalloc()"));
1.1       deraadt  1007:
                   1008:        return result;
1.15      tedu     1009: }
1.1       deraadt  1010:
1.15      tedu     1011:
                   1012: /* Remove all '\n' and '\r' characters, if any, from the end of str.
                   1013:  * str can be any null-terminated string, or NULL.
                   1014:  * returns str. */
1.16      tedu     1015: char *
                   1016: chomp(str)
                   1017:        char *str;
1.15      tedu     1018: {
1.16      tedu     1019:        char *p = str;
1.15      tedu     1020:
                   1021:        if (!str || !*str)      /* s is null or empty string */
                   1022:                return str;
                   1023:
                   1024:        /* find end of string minus one */
                   1025:        while (*p)
                   1026:                ++p;
                   1027:        --p;
                   1028:
                   1029:        /* eat newlines */
                   1030:        while (p >= str && (*p == '\r' || *p == '\n'))
                   1031:                *p-- = 0;
                   1032:        return str;
                   1033: }