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

Annotation of src/usr.bin/yacc/main.c, Revision 1.23

1.23    ! deraadt     1: /*     $OpenBSD: main.c,v 1.22 2009/05/01 10:41:05 chl Exp $   */
1.3       deraadt     2: /*     $NetBSD: main.c,v 1.5 1996/03/19 03:21:38 jtc Exp $     */
                      3:
                      4: /*
                      5:  * Copyright (c) 1989 The Regents of the University of California.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to Berkeley by
                      9:  * Robert Paul Corbett.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
1.17      millert    19:  * 3. Neither the name of the University nor the names of its contributors
1.3       deraadt    20:  *    may be used to endorse or promote products derived from this software
                     21:  *    without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  */
1.1       deraadt    35:
1.4       deraadt    36: #include <sys/types.h>
1.6       tholo      37: #include <fcntl.h>
1.10      millert    38: #include <paths.h>
1.12      pvalchev   39: #include <signal.h>
1.4       deraadt    40: #include <stdlib.h>
1.12      pvalchev   41: #include <unistd.h>
1.1       deraadt    42: #include "defs.h"
                     43:
                     44: char dflag;
                     45: char lflag;
                     46: char rflag;
                     47: char tflag;
                     48: char vflag;
                     49:
                     50: char *symbol_prefix;
                     51: char *file_prefix = "y";
                     52:
                     53: int lineno;
                     54: int outline;
                     55:
1.2       niklas     56: int explicit_file_name;
                     57:
1.1       deraadt    58: char *action_file_name;
                     59: char *code_file_name;
                     60: char *defines_file_name;
                     61: char *input_file_name = "";
                     62: char *output_file_name;
                     63: char *text_file_name;
                     64: char *union_file_name;
                     65: char *verbose_file_name;
                     66:
                     67: FILE *action_file;     /*  a temp file, used to save actions associated    */
                     68:                        /*  with rules until the parser is written          */
                     69: FILE *code_file;       /*  y.code.c (used when the -r option is specified) */
                     70: FILE *defines_file;    /*  y.tab.h                                         */
                     71: FILE *input_file;      /*  the input file                                  */
                     72: FILE *output_file;     /*  y.tab.c                                         */
                     73: FILE *text_file;       /*  a temp file, used to save text until all        */
                     74:                        /*  symbols have been defined                       */
                     75: FILE *union_file;      /*  a temp file, used to save the union             */
                     76:                        /*  definition until all symbol have been           */
                     77:                        /*  defined                                         */
                     78: FILE *verbose_file;    /*  y.output                                        */
                     79:
                     80: int nitems;
                     81: int nrules;
                     82: int nsyms;
                     83: int ntokens;
                     84: int nvars;
                     85:
                     86: int   start_symbol;
                     87: char  **symbol_name;
                     88: short *symbol_value;
                     89: short *symbol_prec;
                     90: char  *symbol_assoc;
                     91:
                     92: short *ritem;
                     93: short *rlhs;
                     94: short *rrhs;
                     95: short *rprec;
                     96: char  *rassoc;
                     97: short **derives;
                     98: char *nullable;
                     99:
1.15      millert   100: void onintr(int);
                    101: void set_signals(void);
                    102: void usage(void);
                    103: void getargs(int, char *[]);
                    104: void create_file_names(void);
                    105: void open_files(void);
1.12      pvalchev  106:
1.13      deraadt   107: volatile sig_atomic_t sigdie;
                    108:
1.12      pvalchev  109: void
1.18      pvalchev  110: done(int k)
1.1       deraadt   111: {
1.13      deraadt   112:     if (action_file)
                    113:        unlink(action_file_name);
                    114:     if (text_file)
                    115:        unlink(text_file_name);
                    116:     if (union_file)
                    117:        unlink(union_file_name);
                    118:     if (sigdie)
                    119:        _exit(k);
1.1       deraadt   120:     exit(k);
                    121: }
                    122:
                    123:
                    124: void
1.18      pvalchev  125: onintr(int signo)
1.1       deraadt   126: {
1.13      deraadt   127:     sigdie = 1;
                    128:     done(1);
1.1       deraadt   129: }
                    130:
                    131:
1.12      pvalchev  132: void
1.18      pvalchev  133: set_signals(void)
1.1       deraadt   134: {
                    135: #ifdef SIGINT
                    136:     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                    137:        signal(SIGINT, onintr);
                    138: #endif
                    139: #ifdef SIGTERM
                    140:     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
                    141:        signal(SIGTERM, onintr);
                    142: #endif
                    143: #ifdef SIGHUP
                    144:     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                    145:        signal(SIGHUP, onintr);
                    146: #endif
                    147: }
                    148:
                    149:
1.12      pvalchev  150: void
1.18      pvalchev  151: usage(void)
1.1       deraadt   152: {
1.21      sobrado   153:     fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-o output_file] [-p symbol_prefix] file\n", __progname);
1.1       deraadt   154:     exit(1);
                    155: }
                    156:
                    157:
1.12      pvalchev  158: void
1.18      pvalchev  159: getargs(int argc, char *argv[])
1.1       deraadt   160: {
1.19      robert    161:     int ch;
1.1       deraadt   162:
1.19      robert    163:     while ((ch = getopt(argc, argv, "b:dlo:p:rtv")) != -1)
1.1       deraadt   164:     {
1.19      robert    165:        switch (ch)
1.1       deraadt   166:        {
                    167:        case 'b':
1.19      robert    168:            file_prefix = optarg;
                    169:            break;
                    170:
1.1       deraadt   171:        case 'd':
                    172:            dflag = 1;
                    173:            break;
                    174:
                    175:        case 'l':
                    176:            lflag = 1;
                    177:            break;
                    178:
1.2       niklas    179:         case 'o':
1.19      robert    180:            output_file_name = optarg;
                    181:            explicit_file_name = 1;
                    182:            break;
                    183:
1.1       deraadt   184:        case 'p':
1.19      robert    185:            symbol_prefix = optarg;
                    186:            break;
                    187:
1.1       deraadt   188:        case 'r':
                    189:            rflag = 1;
                    190:            break;
                    191:
                    192:        case 't':
                    193:            tflag = 1;
                    194:            break;
                    195:
                    196:        case 'v':
                    197:            vflag = 1;
                    198:            break;
                    199:
                    200:        default:
                    201:            usage();
                    202:        }
                    203:     }
1.19      robert    204:     argc -= optind;
                    205:     argv += optind;
1.1       deraadt   206:
1.19      robert    207:     if (argc != 1)
                    208:        usage();
                    209:     if (strcmp(*argv, "-") == 0)
                    210:        input_file = stdin;
                    211:     else
                    212:        input_file_name = *argv;
1.1       deraadt   213: }
                    214:
                    215:
                    216: char *
1.18      pvalchev  217: allocate(unsigned int n)
1.1       deraadt   218: {
1.14      mpech     219:     char *p;
1.1       deraadt   220:
                    221:     p = NULL;
                    222:     if (n)
                    223:     {
                    224:        p = CALLOC(1, n);
                    225:        if (!p) no_space();
                    226:     }
                    227:     return (p);
                    228: }
                    229:
1.16      millert   230: #define TEMPNAME(s, c, d, l)   \
                    231:        (asprintf(&(s), "%.*s/yacc.%xXXXXXXXXXX", (int)(l), (d), (c)))
                    232:
1.12      pvalchev  233: void
1.18      pvalchev  234: create_file_names(void)
1.1       deraadt   235: {
1.16      millert   236:     size_t len;
1.1       deraadt   237:     char *tmpdir;
                    238:
1.16      millert   239:     if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0')
1.10      millert   240:        tmpdir = _PATH_TMP;
1.1       deraadt   241:
                    242:     len = strlen(tmpdir);
1.16      millert   243:     if (tmpdir[len-1] == '/')
                    244:        len--;
1.1       deraadt   245:
1.16      millert   246:     if (TEMPNAME(action_file_name, 'a', tmpdir, len) == -1 ||
                    247:        TEMPNAME(text_file_name, 'r', tmpdir, len) == -1 ||
                    248:        TEMPNAME(union_file_name, 'u', tmpdir, len) == -1)
                    249:        no_space();
1.1       deraadt   250:
1.16      millert   251:     if (output_file_name == NULL)
1.2       niklas    252:     {
1.16      millert   253:        if (asprintf(&output_file_name, "%s%s", file_prefix, OUTPUT_SUFFIX)
                    254:            == -1)
1.2       niklas    255:            no_space();
                    256:     }
1.1       deraadt   257:
1.16      millert   258:     if (rflag) {
                    259:        if (asprintf(&code_file_name, "%s%s", file_prefix, CODE_SUFFIX) == -1)
1.1       deraadt   260:            no_space();
1.16      millert   261:     } else
1.1       deraadt   262:        code_file_name = output_file_name;
                    263:
                    264:     if (dflag)
                    265:     {
1.2       niklas    266:         if (explicit_file_name)
                    267:        {
1.8       deraadt   268:            char *suffix;
                    269:
1.16      millert   270:            defines_file_name = strdup(output_file_name);
1.2       niklas    271:            if (defines_file_name == 0)
                    272:                no_space();
1.8       deraadt   273:
                    274:             /* does the output_file_name have a known suffix */
                    275:             if ((suffix = strrchr(output_file_name, '.')) != 0 &&
                    276:                 (!strcmp(suffix, ".c") ||      /* good, old-fashioned C */
                    277:                  !strcmp(suffix, ".C") ||      /* C++, or C on Windows */
                    278:                  !strcmp(suffix, ".cc") ||     /* C++ */
                    279:                  !strcmp(suffix, ".cxx") ||    /* C++ */
                    280:                  !strcmp(suffix, ".cpp")))     /* C++ (Windows) */
                    281:             {
                    282:                 strncpy(defines_file_name, output_file_name,
                    283:                     suffix - output_file_name + 1);
                    284:                 defines_file_name[suffix - output_file_name + 1] = 'h';
                    285:                 defines_file_name[suffix - output_file_name + 2] = '\0';
                    286:             } else {
                    287:                 fprintf(stderr,"%s: suffix of output file name %s"
                    288:                     " not recognized, no -d file generated.\n",
1.10      millert   289:                     __progname, output_file_name);
1.8       deraadt   290:                 dflag = 0;
                    291:                 free(defines_file_name);
                    292:                 defines_file_name = 0;
                    293:             }
1.2       niklas    294:        }
                    295:        else
                    296:        {
1.16      millert   297:            if (asprintf(&defines_file_name, "%s%s", file_prefix,
                    298:                DEFINES_SUFFIX) == -1)
1.2       niklas    299:                no_space();
                    300:        }
1.1       deraadt   301:     }
                    302:
                    303:     if (vflag)
                    304:     {
1.16      millert   305:        if (asprintf(&verbose_file_name, "%s%s", file_prefix,
                    306:            VERBOSE_SUFFIX) == -1)
1.1       deraadt   307:            no_space();
                    308:     }
                    309: }
                    310:
1.4       deraadt   311:
1.12      pvalchev  312: void
1.18      pvalchev  313: open_files(void)
1.1       deraadt   314: {
1.4       deraadt   315:     int fd;
                    316:
1.1       deraadt   317:     create_file_names();
                    318:
                    319:     if (input_file == 0)
                    320:     {
                    321:        input_file = fopen(input_file_name, "r");
                    322:        if (input_file == 0)
                    323:            open_error(input_file_name);
                    324:     }
                    325:
1.10      millert   326:     fd = mkstemp(action_file_name);
                    327:     if (fd == -1 || (action_file = fdopen(fd, "w")) == NULL)
1.1       deraadt   328:        open_error(action_file_name);
                    329:
1.10      millert   330:     fd = mkstemp(text_file_name);
                    331:     if (fd == -1 || (text_file = fdopen(fd, "w")) == NULL)
1.1       deraadt   332:        open_error(text_file_name);
                    333:
                    334:     if (vflag)
                    335:     {
                    336:        verbose_file = fopen(verbose_file_name, "w");
                    337:        if (verbose_file == 0)
                    338:            open_error(verbose_file_name);
                    339:     }
                    340:
                    341:     if (dflag)
                    342:     {
                    343:        defines_file = fopen(defines_file_name, "w");
1.20      pvalchev  344:        if (defines_file == NULL)
                    345:            open_write_error(defines_file_name);
1.10      millert   346:        fd = mkstemp(union_file_name);
                    347:        if (fd == -1 || (union_file = fdopen(fd, "w")) == NULL)
1.1       deraadt   348:            open_error(union_file_name);
                    349:     }
                    350:
                    351:     output_file = fopen(output_file_name, "w");
                    352:     if (output_file == 0)
                    353:        open_error(output_file_name);
                    354:
                    355:     if (rflag)
                    356:     {
                    357:        code_file = fopen(code_file_name, "w");
                    358:        if (code_file == 0)
                    359:            open_error(code_file_name);
                    360:     }
                    361:     else
                    362:        code_file = output_file;
                    363: }
                    364:
                    365:
                    366: int
1.18      pvalchev  367: main(int argc, char *argv[])
1.1       deraadt   368: {
                    369:     set_signals();
                    370:     getargs(argc, argv);
                    371:     open_files();
                    372:     reader();
                    373:     lr0();
                    374:     lalr();
                    375:     make_parser();
                    376:     verbose();
                    377:     output();
                    378:     done(0);
                    379:     /*NOTREACHED*/
1.12      pvalchev  380:     return (0);
1.1       deraadt   381: }