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

1.15    ! millert     1: /*     $OpenBSD: main.c,v 1.14 2001/11/19 19:02:18 mpech 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.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by the University of
                     22:  *     California, Berkeley and its contributors.
                     23:  * 4. Neither the name of the University nor the names of its contributors
                     24:  *    may be used to endorse or promote products derived from this software
                     25:  *    without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     28:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     29:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     30:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     31:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     32:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     33:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     34:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     35:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     36:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     37:  * SUCH DAMAGE.
                     38:  */
                     39:
                     40: #ifndef lint
                     41: char copyright[] =
                     42: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
                     43:  All rights reserved.\n";
                     44: #endif /* not lint */
                     45:
1.1       deraadt    46: #ifndef lint
1.3       deraadt    47: #if 0
                     48: static char sccsid[] = "@(#)main.c     5.5 (Berkeley) 5/24/93";
                     49: #else
1.15    ! millert    50: static char rcsid[] = "$OpenBSD: main.c,v 1.14 2001/11/19 19:02:18 mpech Exp $";
1.3       deraadt    51: #endif
1.1       deraadt    52: #endif /* not lint */
                     53:
1.4       deraadt    54: #include <sys/types.h>
1.6       tholo      55: #include <fcntl.h>
1.10      millert    56: #include <paths.h>
1.12      pvalchev   57: #include <signal.h>
1.4       deraadt    58: #include <stdlib.h>
1.12      pvalchev   59: #include <unistd.h>
1.1       deraadt    60: #include "defs.h"
                     61:
                     62: char dflag;
                     63: char lflag;
                     64: char rflag;
                     65: char tflag;
                     66: char vflag;
                     67:
                     68: char *symbol_prefix;
                     69: char *file_prefix = "y";
1.10      millert    70: char *temp_form = "yacc.XXXXXXXXXXX";
1.1       deraadt    71:
                     72: int lineno;
                     73: int outline;
                     74:
1.2       niklas     75: int explicit_file_name;
                     76:
1.1       deraadt    77: char *action_file_name;
                     78: char *code_file_name;
                     79: char *defines_file_name;
                     80: char *input_file_name = "";
                     81: char *output_file_name;
                     82: char *text_file_name;
                     83: char *union_file_name;
                     84: char *verbose_file_name;
                     85:
                     86: FILE *action_file;     /*  a temp file, used to save actions associated    */
                     87:                        /*  with rules until the parser is written          */
                     88: FILE *code_file;       /*  y.code.c (used when the -r option is specified) */
                     89: FILE *defines_file;    /*  y.tab.h                                         */
                     90: FILE *input_file;      /*  the input file                                  */
                     91: FILE *output_file;     /*  y.tab.c                                         */
                     92: FILE *text_file;       /*  a temp file, used to save text until all        */
                     93:                        /*  symbols have been defined                       */
                     94: FILE *union_file;      /*  a temp file, used to save the union             */
                     95:                        /*  definition until all symbol have been           */
                     96:                        /*  defined                                         */
                     97: FILE *verbose_file;    /*  y.output                                        */
                     98:
                     99: int nitems;
                    100: int nrules;
                    101: int nsyms;
                    102: int ntokens;
                    103: int nvars;
                    104:
                    105: int   start_symbol;
                    106: char  **symbol_name;
                    107: short *symbol_value;
                    108: short *symbol_prec;
                    109: char  *symbol_assoc;
                    110:
                    111: short *ritem;
                    112: short *rlhs;
                    113: short *rrhs;
                    114: short *rprec;
                    115: char  *rassoc;
                    116: short **derives;
                    117: char *nullable;
                    118:
1.15    ! millert   119: void onintr(int);
        !           120: void set_signals(void);
        !           121: void usage(void);
        !           122: void getargs(int, char *[]);
        !           123: void create_file_names(void);
        !           124: void open_files(void);
1.12      pvalchev  125:
1.13      deraadt   126: volatile sig_atomic_t sigdie;
                    127:
1.12      pvalchev  128: void
1.1       deraadt   129: done(k)
                    130: int k;
                    131: {
1.13      deraadt   132:     if (action_file)
                    133:        unlink(action_file_name);
                    134:     if (text_file)
                    135:        unlink(text_file_name);
                    136:     if (union_file)
                    137:        unlink(union_file_name);
                    138:     if (sigdie)
                    139:        _exit(k);
1.1       deraadt   140:     exit(k);
                    141: }
                    142:
                    143:
                    144: void
1.3       deraadt   145: onintr(signo)
                    146:        int signo;
1.1       deraadt   147: {
1.13      deraadt   148:     sigdie = 1;
                    149:     done(1);
1.1       deraadt   150: }
                    151:
                    152:
1.12      pvalchev  153: void
1.1       deraadt   154: set_signals()
                    155: {
                    156: #ifdef SIGINT
                    157:     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                    158:        signal(SIGINT, onintr);
                    159: #endif
                    160: #ifdef SIGTERM
                    161:     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
                    162:        signal(SIGTERM, onintr);
                    163: #endif
                    164: #ifdef SIGHUP
                    165:     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                    166:        signal(SIGHUP, onintr);
                    167: #endif
                    168: }
                    169:
                    170:
1.12      pvalchev  171: void
1.1       deraadt   172: usage()
                    173: {
1.10      millert   174:     fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-o outputfile] [-p symbol_prefix] filename\n", __progname);
1.1       deraadt   175:     exit(1);
                    176: }
                    177:
                    178:
1.12      pvalchev  179: void
1.1       deraadt   180: getargs(argc, argv)
                    181: int argc;
                    182: char *argv[];
                    183: {
1.14      mpech     184:     int i;
                    185:     char *s;
1.1       deraadt   186:
                    187:     for (i = 1; i < argc; ++i)
                    188:     {
                    189:        s = argv[i];
                    190:        if (*s != '-') break;
                    191:        switch (*++s)
                    192:        {
                    193:        case '\0':
                    194:            input_file = stdin;
                    195:            if (i + 1 < argc) usage();
                    196:            return;
                    197:
                    198:        case '-':
                    199:            ++i;
                    200:            goto no_more_options;
                    201:
                    202:        case 'b':
                    203:            if (*++s)
                    204:                 file_prefix = s;
                    205:            else if (++i < argc)
                    206:                file_prefix = argv[i];
                    207:            else
                    208:                usage();
                    209:            continue;
                    210:
                    211:        case 'd':
                    212:            dflag = 1;
                    213:            break;
                    214:
                    215:        case 'l':
                    216:            lflag = 1;
                    217:            break;
                    218:
1.2       niklas    219:         case 'o':
                    220:             if (*++s)
                    221:                output_file_name = s;
                    222:             else if (++i < argc)
                    223:                 output_file_name = argv[i];
                    224:             else
                    225:                 usage();
                    226:             explicit_file_name = 1;
                    227:             continue;
                    228:
1.1       deraadt   229:        case 'p':
                    230:            if (*++s)
                    231:                symbol_prefix = s;
                    232:            else if (++i < argc)
                    233:                symbol_prefix = argv[i];
                    234:            else
                    235:                usage();
                    236:            continue;
                    237:
                    238:        case 'r':
                    239:            rflag = 1;
                    240:            break;
                    241:
                    242:        case 't':
                    243:            tflag = 1;
                    244:            break;
                    245:
                    246:        case 'v':
                    247:            vflag = 1;
                    248:            break;
                    249:
                    250:        default:
                    251:            usage();
                    252:        }
                    253:
                    254:        for (;;)
                    255:        {
                    256:            switch (*++s)
                    257:            {
                    258:            case '\0':
                    259:                goto end_of_option;
                    260:
                    261:            case 'd':
                    262:                dflag = 1;
                    263:                break;
                    264:
                    265:            case 'l':
                    266:                lflag = 1;
                    267:                break;
                    268:
                    269:            case 'r':
                    270:                rflag = 1;
                    271:                break;
                    272:
                    273:            case 't':
                    274:                tflag = 1;
                    275:                break;
                    276:
                    277:            case 'v':
                    278:                vflag = 1;
                    279:                break;
                    280:
                    281:            default:
                    282:                usage();
                    283:            }
                    284:        }
                    285: end_of_option:;
                    286:     }
                    287:
                    288: no_more_options:;
                    289:     if (i + 1 != argc) usage();
                    290:     input_file_name = argv[i];
                    291: }
                    292:
                    293:
                    294: char *
                    295: allocate(n)
                    296: unsigned n;
                    297: {
1.14      mpech     298:     char *p;
1.1       deraadt   299:
                    300:     p = NULL;
                    301:     if (n)
                    302:     {
                    303:        p = CALLOC(1, n);
                    304:        if (!p) no_space();
                    305:     }
                    306:     return (p);
                    307: }
                    308:
1.12      pvalchev  309: void
1.1       deraadt   310: create_file_names()
                    311: {
                    312:     int i, len;
                    313:     char *tmpdir;
                    314:
1.10      millert   315:     if (!(tmpdir = getenv("TMPDIR")))
                    316:        tmpdir = _PATH_TMP;
1.1       deraadt   317:
                    318:     len = strlen(tmpdir);
1.9       deraadt   319:     i = len + strlen(temp_form) + 1;
1.1       deraadt   320:     if (len && tmpdir[len-1] != '/')
                    321:        ++i;
                    322:
                    323:     action_file_name = MALLOC(i);
                    324:     if (action_file_name == 0) no_space();
                    325:     text_file_name = MALLOC(i);
                    326:     if (text_file_name == 0) no_space();
                    327:     union_file_name = MALLOC(i);
                    328:     if (union_file_name == 0) no_space();
                    329:
                    330:     strcpy(action_file_name, tmpdir);
                    331:     strcpy(text_file_name, tmpdir);
                    332:     strcpy(union_file_name, tmpdir);
                    333:
                    334:     if (len && tmpdir[len - 1] != '/')
                    335:     {
                    336:        action_file_name[len] = '/';
                    337:        text_file_name[len] = '/';
                    338:        union_file_name[len] = '/';
                    339:        ++len;
                    340:     }
                    341:
                    342:     strcpy(action_file_name + len, temp_form);
                    343:     strcpy(text_file_name + len, temp_form);
                    344:     strcpy(union_file_name + len, temp_form);
                    345:
                    346:     action_file_name[len + 5] = 'a';
                    347:     text_file_name[len + 5] = 't';
                    348:     union_file_name[len + 5] = 'u';
                    349:
                    350:     len = strlen(file_prefix);
                    351:
1.2       niklas    352:     if (!output_file_name)
                    353:     {
                    354:         output_file_name = MALLOC(len + 7);
                    355:         if (output_file_name == 0)
                    356:            no_space();
                    357:         strcpy(output_file_name, file_prefix);
                    358:         strcpy(output_file_name + len, OUTPUT_SUFFIX);
                    359:     }
1.1       deraadt   360:
                    361:     if (rflag)
                    362:     {
                    363:        code_file_name = MALLOC(len + 8);
                    364:        if (code_file_name == 0)
                    365:            no_space();
                    366:        strcpy(code_file_name, file_prefix);
                    367:        strcpy(code_file_name + len, CODE_SUFFIX);
                    368:     }
                    369:     else
                    370:        code_file_name = output_file_name;
                    371:
                    372:     if (dflag)
                    373:     {
1.2       niklas    374:         if (explicit_file_name)
                    375:        {
1.8       deraadt   376:            char *suffix;
                    377:
                    378:            defines_file_name = MALLOC(strlen(output_file_name)+1);
1.2       niklas    379:            if (defines_file_name == 0)
                    380:                no_space();
                    381:            strcpy(defines_file_name, output_file_name);
1.8       deraadt   382:
                    383:             /* does the output_file_name have a known suffix */
                    384:             if ((suffix = strrchr(output_file_name, '.')) != 0 &&
                    385:                 (!strcmp(suffix, ".c") ||      /* good, old-fashioned C */
                    386:                  !strcmp(suffix, ".C") ||      /* C++, or C on Windows */
                    387:                  !strcmp(suffix, ".cc") ||     /* C++ */
                    388:                  !strcmp(suffix, ".cxx") ||    /* C++ */
                    389:                  !strcmp(suffix, ".cpp")))     /* C++ (Windows) */
                    390:             {
                    391:                 strncpy(defines_file_name, output_file_name,
                    392:                     suffix - output_file_name + 1);
                    393:                 defines_file_name[suffix - output_file_name + 1] = 'h';
                    394:                 defines_file_name[suffix - output_file_name + 2] = '\0';
                    395:             } else {
                    396:                 fprintf(stderr,"%s: suffix of output file name %s"
                    397:                     " not recognized, no -d file generated.\n",
1.10      millert   398:                     __progname, output_file_name);
1.8       deraadt   399:                 dflag = 0;
                    400:                 free(defines_file_name);
                    401:                 defines_file_name = 0;
                    402:             }
1.2       niklas    403:        }
                    404:        else
                    405:        {
                    406:            defines_file_name = MALLOC(len + 7);
                    407:            if (defines_file_name == 0)
                    408:                no_space();
                    409:            strcpy(defines_file_name, file_prefix);
                    410:            strcpy(defines_file_name + len, DEFINES_SUFFIX);
                    411:        }
1.1       deraadt   412:     }
                    413:
                    414:     if (vflag)
                    415:     {
                    416:        verbose_file_name = MALLOC(len + 8);
                    417:        if (verbose_file_name == 0)
                    418:            no_space();
                    419:        strcpy(verbose_file_name, file_prefix);
                    420:        strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
                    421:     }
                    422: }
                    423:
                    424:
1.4       deraadt   425: FILE *
                    426: fsopen(name, mode)
                    427:     char *name;
                    428:     char *mode;
                    429: {
                    430:     FILE *fp = NULL;
                    431:     int fd, mod = O_RDONLY;
                    432:
                    433:     if (strchr(mode, 'w'))
                    434:        mod = O_RDWR;
                    435:     if ((fd = open(name, mod | O_EXCL|O_CREAT, 0666)) == -1 ||
                    436:        (fp = fdopen(fd, mode)) == NULL) {
                    437:        if (fd != -1)
                    438:            close(fd);
                    439:     }
                    440:     return (fp);
                    441: }
                    442:
1.12      pvalchev  443: void
1.1       deraadt   444: open_files()
                    445: {
1.4       deraadt   446:     int fd;
                    447:
1.1       deraadt   448:     create_file_names();
                    449:
                    450:     if (input_file == 0)
                    451:     {
                    452:        input_file = fopen(input_file_name, "r");
                    453:        if (input_file == 0)
                    454:            open_error(input_file_name);
                    455:     }
                    456:
1.10      millert   457:     fd = mkstemp(action_file_name);
                    458:     if (fd == -1 || (action_file = fdopen(fd, "w")) == NULL)
1.1       deraadt   459:        open_error(action_file_name);
                    460:
1.10      millert   461:     fd = mkstemp(text_file_name);
                    462:     if (fd == -1 || (text_file = fdopen(fd, "w")) == NULL)
1.1       deraadt   463:        open_error(text_file_name);
                    464:
                    465:     if (vflag)
                    466:     {
                    467:        verbose_file = fopen(verbose_file_name, "w");
                    468:        if (verbose_file == 0)
                    469:            open_error(verbose_file_name);
                    470:     }
                    471:
                    472:     if (dflag)
                    473:     {
                    474:        defines_file = fopen(defines_file_name, "w");
                    475:        if (defines_file == 0)
                    476:            open_error(defines_file_name);
1.10      millert   477:        fd = mkstemp(union_file_name);
                    478:        if (fd == -1 || (union_file = fdopen(fd, "w")) == NULL)
1.1       deraadt   479:            open_error(union_file_name);
                    480:     }
                    481:
                    482:     output_file = fopen(output_file_name, "w");
                    483:     if (output_file == 0)
                    484:        open_error(output_file_name);
                    485:
                    486:     if (rflag)
                    487:     {
                    488:        code_file = fopen(code_file_name, "w");
                    489:        if (code_file == 0)
                    490:            open_error(code_file_name);
                    491:     }
                    492:     else
                    493:        code_file = output_file;
                    494: }
                    495:
                    496:
                    497: int
                    498: main(argc, argv)
                    499: int argc;
                    500: char *argv[];
                    501: {
                    502:     set_signals();
                    503:     getargs(argc, argv);
                    504:     open_files();
                    505:     reader();
                    506:     lr0();
                    507:     lalr();
                    508:     make_parser();
                    509:     verbose();
                    510:     output();
                    511:     done(0);
                    512:     /*NOTREACHED*/
1.12      pvalchev  513:     return (0);
1.1       deraadt   514: }