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

1.18    ! pvalchev    1: /*     $OpenBSD: main.c,v 1.17 2003/06/03 02:56:24 millert 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:  */
                     35:
                     36: #ifndef lint
                     37: char copyright[] =
                     38: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
                     39:  All rights reserved.\n";
                     40: #endif /* not lint */
                     41:
1.1       deraadt    42: #ifndef lint
1.3       deraadt    43: #if 0
                     44: static char sccsid[] = "@(#)main.c     5.5 (Berkeley) 5/24/93";
                     45: #else
1.18    ! pvalchev   46: static char rcsid[] = "$OpenBSD: main.c,v 1.17 2003/06/03 02:56:24 millert Exp $";
1.3       deraadt    47: #endif
1.1       deraadt    48: #endif /* not lint */
                     49:
1.4       deraadt    50: #include <sys/types.h>
1.6       tholo      51: #include <fcntl.h>
1.10      millert    52: #include <paths.h>
1.12      pvalchev   53: #include <signal.h>
1.4       deraadt    54: #include <stdlib.h>
1.12      pvalchev   55: #include <unistd.h>
1.1       deraadt    56: #include "defs.h"
                     57:
                     58: char dflag;
                     59: char lflag;
                     60: char rflag;
                     61: char tflag;
                     62: char vflag;
                     63:
                     64: char *symbol_prefix;
                     65: char *file_prefix = "y";
                     66:
                     67: int lineno;
                     68: int outline;
                     69:
1.2       niklas     70: int explicit_file_name;
                     71:
1.1       deraadt    72: char *action_file_name;
                     73: char *code_file_name;
                     74: char *defines_file_name;
                     75: char *input_file_name = "";
                     76: char *output_file_name;
                     77: char *text_file_name;
                     78: char *union_file_name;
                     79: char *verbose_file_name;
                     80:
                     81: FILE *action_file;     /*  a temp file, used to save actions associated    */
                     82:                        /*  with rules until the parser is written          */
                     83: FILE *code_file;       /*  y.code.c (used when the -r option is specified) */
                     84: FILE *defines_file;    /*  y.tab.h                                         */
                     85: FILE *input_file;      /*  the input file                                  */
                     86: FILE *output_file;     /*  y.tab.c                                         */
                     87: FILE *text_file;       /*  a temp file, used to save text until all        */
                     88:                        /*  symbols have been defined                       */
                     89: FILE *union_file;      /*  a temp file, used to save the union             */
                     90:                        /*  definition until all symbol have been           */
                     91:                        /*  defined                                         */
                     92: FILE *verbose_file;    /*  y.output                                        */
                     93:
                     94: int nitems;
                     95: int nrules;
                     96: int nsyms;
                     97: int ntokens;
                     98: int nvars;
                     99:
                    100: int   start_symbol;
                    101: char  **symbol_name;
                    102: short *symbol_value;
                    103: short *symbol_prec;
                    104: char  *symbol_assoc;
                    105:
                    106: short *ritem;
                    107: short *rlhs;
                    108: short *rrhs;
                    109: short *rprec;
                    110: char  *rassoc;
                    111: short **derives;
                    112: char *nullable;
                    113:
1.15      millert   114: void onintr(int);
                    115: void set_signals(void);
                    116: void usage(void);
                    117: void getargs(int, char *[]);
                    118: void create_file_names(void);
                    119: void open_files(void);
1.12      pvalchev  120:
1.13      deraadt   121: volatile sig_atomic_t sigdie;
                    122:
1.12      pvalchev  123: void
1.18    ! pvalchev  124: done(int k)
1.1       deraadt   125: {
1.13      deraadt   126:     if (action_file)
                    127:        unlink(action_file_name);
                    128:     if (text_file)
                    129:        unlink(text_file_name);
                    130:     if (union_file)
                    131:        unlink(union_file_name);
                    132:     if (sigdie)
                    133:        _exit(k);
1.1       deraadt   134:     exit(k);
                    135: }
                    136:
                    137:
                    138: void
1.18    ! pvalchev  139: onintr(int signo)
1.1       deraadt   140: {
1.13      deraadt   141:     sigdie = 1;
                    142:     done(1);
1.1       deraadt   143: }
                    144:
                    145:
1.12      pvalchev  146: void
1.18    ! pvalchev  147: set_signals(void)
1.1       deraadt   148: {
                    149: #ifdef SIGINT
                    150:     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                    151:        signal(SIGINT, onintr);
                    152: #endif
                    153: #ifdef SIGTERM
                    154:     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
                    155:        signal(SIGTERM, onintr);
                    156: #endif
                    157: #ifdef SIGHUP
                    158:     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                    159:        signal(SIGHUP, onintr);
                    160: #endif
                    161: }
                    162:
                    163:
1.12      pvalchev  164: void
1.18    ! pvalchev  165: usage(void)
1.1       deraadt   166: {
1.10      millert   167:     fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-o outputfile] [-p symbol_prefix] filename\n", __progname);
1.1       deraadt   168:     exit(1);
                    169: }
                    170:
                    171:
1.12      pvalchev  172: void
1.18    ! pvalchev  173: getargs(int argc, char *argv[])
1.1       deraadt   174: {
1.14      mpech     175:     int i;
                    176:     char *s;
1.1       deraadt   177:
                    178:     for (i = 1; i < argc; ++i)
                    179:     {
                    180:        s = argv[i];
                    181:        if (*s != '-') break;
                    182:        switch (*++s)
                    183:        {
                    184:        case '\0':
                    185:            input_file = stdin;
                    186:            if (i + 1 < argc) usage();
                    187:            return;
                    188:
                    189:        case '-':
                    190:            ++i;
                    191:            goto no_more_options;
                    192:
                    193:        case 'b':
                    194:            if (*++s)
                    195:                 file_prefix = s;
                    196:            else if (++i < argc)
                    197:                file_prefix = argv[i];
                    198:            else
                    199:                usage();
                    200:            continue;
                    201:
                    202:        case 'd':
                    203:            dflag = 1;
                    204:            break;
                    205:
                    206:        case 'l':
                    207:            lflag = 1;
                    208:            break;
                    209:
1.2       niklas    210:         case 'o':
                    211:             if (*++s)
                    212:                output_file_name = s;
                    213:             else if (++i < argc)
                    214:                 output_file_name = argv[i];
                    215:             else
                    216:                 usage();
                    217:             explicit_file_name = 1;
                    218:             continue;
                    219:
1.1       deraadt   220:        case 'p':
                    221:            if (*++s)
                    222:                symbol_prefix = s;
                    223:            else if (++i < argc)
                    224:                symbol_prefix = argv[i];
                    225:            else
                    226:                usage();
                    227:            continue;
                    228:
                    229:        case 'r':
                    230:            rflag = 1;
                    231:            break;
                    232:
                    233:        case 't':
                    234:            tflag = 1;
                    235:            break;
                    236:
                    237:        case 'v':
                    238:            vflag = 1;
                    239:            break;
                    240:
                    241:        default:
                    242:            usage();
                    243:        }
                    244:
                    245:        for (;;)
                    246:        {
                    247:            switch (*++s)
                    248:            {
                    249:            case '\0':
                    250:                goto end_of_option;
                    251:
                    252:            case 'd':
                    253:                dflag = 1;
                    254:                break;
                    255:
                    256:            case 'l':
                    257:                lflag = 1;
                    258:                break;
                    259:
                    260:            case 'r':
                    261:                rflag = 1;
                    262:                break;
                    263:
                    264:            case 't':
                    265:                tflag = 1;
                    266:                break;
                    267:
                    268:            case 'v':
                    269:                vflag = 1;
                    270:                break;
                    271:
                    272:            default:
                    273:                usage();
                    274:            }
                    275:        }
                    276: end_of_option:;
                    277:     }
                    278:
                    279: no_more_options:;
                    280:     if (i + 1 != argc) usage();
                    281:     input_file_name = argv[i];
                    282: }
                    283:
                    284:
                    285: char *
1.18    ! pvalchev  286: allocate(unsigned int n)
1.1       deraadt   287: {
1.14      mpech     288:     char *p;
1.1       deraadt   289:
                    290:     p = NULL;
                    291:     if (n)
                    292:     {
                    293:        p = CALLOC(1, n);
                    294:        if (!p) no_space();
                    295:     }
                    296:     return (p);
                    297: }
                    298:
1.16      millert   299: #define TEMPNAME(s, c, d, l)   \
                    300:        (asprintf(&(s), "%.*s/yacc.%xXXXXXXXXXX", (int)(l), (d), (c)))
                    301:
1.12      pvalchev  302: void
1.18    ! pvalchev  303: create_file_names(void)
1.1       deraadt   304: {
1.16      millert   305:     size_t len;
1.1       deraadt   306:     char *tmpdir;
                    307:
1.16      millert   308:     if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0')
1.10      millert   309:        tmpdir = _PATH_TMP;
1.1       deraadt   310:
                    311:     len = strlen(tmpdir);
1.16      millert   312:     if (tmpdir[len-1] == '/')
                    313:        len--;
1.1       deraadt   314:
1.16      millert   315:     if (TEMPNAME(action_file_name, 'a', tmpdir, len) == -1 ||
                    316:        TEMPNAME(text_file_name, 'r', tmpdir, len) == -1 ||
                    317:        TEMPNAME(union_file_name, 'u', tmpdir, len) == -1)
                    318:        no_space();
1.1       deraadt   319:
1.16      millert   320:     if (output_file_name == NULL)
1.2       niklas    321:     {
1.16      millert   322:        if (asprintf(&output_file_name, "%s%s", file_prefix, OUTPUT_SUFFIX)
                    323:            == -1)
1.2       niklas    324:            no_space();
                    325:     }
1.1       deraadt   326:
1.16      millert   327:     if (rflag) {
                    328:        if (asprintf(&code_file_name, "%s%s", file_prefix, CODE_SUFFIX) == -1)
1.1       deraadt   329:            no_space();
1.16      millert   330:     } else
1.1       deraadt   331:        code_file_name = output_file_name;
                    332:
                    333:     if (dflag)
                    334:     {
1.2       niklas    335:         if (explicit_file_name)
                    336:        {
1.8       deraadt   337:            char *suffix;
                    338:
1.16      millert   339:            defines_file_name = strdup(output_file_name);
1.2       niklas    340:            if (defines_file_name == 0)
                    341:                no_space();
1.8       deraadt   342:
                    343:             /* does the output_file_name have a known suffix */
                    344:             if ((suffix = strrchr(output_file_name, '.')) != 0 &&
                    345:                 (!strcmp(suffix, ".c") ||      /* good, old-fashioned C */
                    346:                  !strcmp(suffix, ".C") ||      /* C++, or C on Windows */
                    347:                  !strcmp(suffix, ".cc") ||     /* C++ */
                    348:                  !strcmp(suffix, ".cxx") ||    /* C++ */
                    349:                  !strcmp(suffix, ".cpp")))     /* C++ (Windows) */
                    350:             {
                    351:                 strncpy(defines_file_name, output_file_name,
                    352:                     suffix - output_file_name + 1);
                    353:                 defines_file_name[suffix - output_file_name + 1] = 'h';
                    354:                 defines_file_name[suffix - output_file_name + 2] = '\0';
                    355:             } else {
                    356:                 fprintf(stderr,"%s: suffix of output file name %s"
                    357:                     " not recognized, no -d file generated.\n",
1.10      millert   358:                     __progname, output_file_name);
1.8       deraadt   359:                 dflag = 0;
                    360:                 free(defines_file_name);
                    361:                 defines_file_name = 0;
                    362:             }
1.2       niklas    363:        }
                    364:        else
                    365:        {
1.16      millert   366:            if (asprintf(&defines_file_name, "%s%s", file_prefix,
                    367:                DEFINES_SUFFIX) == -1)
1.2       niklas    368:                no_space();
                    369:        }
1.1       deraadt   370:     }
                    371:
                    372:     if (vflag)
                    373:     {
1.16      millert   374:        if (asprintf(&verbose_file_name, "%s%s", file_prefix,
                    375:            VERBOSE_SUFFIX) == -1)
1.1       deraadt   376:            no_space();
                    377:     }
                    378: }
                    379:
                    380:
1.4       deraadt   381: FILE *
1.18    ! pvalchev  382: fsopen(char *name, char *mode)
1.4       deraadt   383: {
                    384:     FILE *fp = NULL;
                    385:     int fd, mod = O_RDONLY;
                    386:
                    387:     if (strchr(mode, 'w'))
                    388:        mod = O_RDWR;
                    389:     if ((fd = open(name, mod | O_EXCL|O_CREAT, 0666)) == -1 ||
                    390:        (fp = fdopen(fd, mode)) == NULL) {
                    391:        if (fd != -1)
                    392:            close(fd);
                    393:     }
                    394:     return (fp);
                    395: }
                    396:
1.12      pvalchev  397: void
1.18    ! pvalchev  398: open_files(void)
1.1       deraadt   399: {
1.4       deraadt   400:     int fd;
                    401:
1.1       deraadt   402:     create_file_names();
                    403:
                    404:     if (input_file == 0)
                    405:     {
                    406:        input_file = fopen(input_file_name, "r");
                    407:        if (input_file == 0)
                    408:            open_error(input_file_name);
                    409:     }
                    410:
1.10      millert   411:     fd = mkstemp(action_file_name);
                    412:     if (fd == -1 || (action_file = fdopen(fd, "w")) == NULL)
1.1       deraadt   413:        open_error(action_file_name);
                    414:
1.10      millert   415:     fd = mkstemp(text_file_name);
                    416:     if (fd == -1 || (text_file = fdopen(fd, "w")) == NULL)
1.1       deraadt   417:        open_error(text_file_name);
                    418:
                    419:     if (vflag)
                    420:     {
                    421:        verbose_file = fopen(verbose_file_name, "w");
                    422:        if (verbose_file == 0)
                    423:            open_error(verbose_file_name);
                    424:     }
                    425:
                    426:     if (dflag)
                    427:     {
                    428:        defines_file = fopen(defines_file_name, "w");
                    429:        if (defines_file == 0)
                    430:            open_error(defines_file_name);
1.10      millert   431:        fd = mkstemp(union_file_name);
                    432:        if (fd == -1 || (union_file = fdopen(fd, "w")) == NULL)
1.1       deraadt   433:            open_error(union_file_name);
                    434:     }
                    435:
                    436:     output_file = fopen(output_file_name, "w");
                    437:     if (output_file == 0)
                    438:        open_error(output_file_name);
                    439:
                    440:     if (rflag)
                    441:     {
                    442:        code_file = fopen(code_file_name, "w");
                    443:        if (code_file == 0)
                    444:            open_error(code_file_name);
                    445:     }
                    446:     else
                    447:        code_file = output_file;
                    448: }
                    449:
                    450:
                    451: int
1.18    ! pvalchev  452: main(int argc, char *argv[])
1.1       deraadt   453: {
                    454:     set_signals();
                    455:     getargs(argc, argv);
                    456:     open_files();
                    457:     reader();
                    458:     lr0();
                    459:     lalr();
                    460:     make_parser();
                    461:     verbose();
                    462:     output();
                    463:     done(0);
                    464:     /*NOTREACHED*/
1.12      pvalchev  465:     return (0);
1.1       deraadt   466: }