[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.15

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