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

1.31    ! espie       1: /* $OpenBSD: main.c,v 1.30 2020/05/21 16:13:23 espie Exp $      */
1.26      tedu        2: /* $NetBSD: main.c,v 1.5 1996/03/19 03:21:38 jtc Exp $  */
1.3       deraadt     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:
1.26      tedu       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                                        */
1.1       deraadt    79:
                     80: int nitems;
                     81: int nrules;
                     82: int nsyms;
                     83: int ntokens;
                     84: int nvars;
                     85:
1.26      tedu       86: int start_symbol;
                     87: char **symbol_name;
1.1       deraadt    88: short *symbol_value;
                     89: short *symbol_prec;
1.26      tedu       90: char *symbol_assoc;
1.1       deraadt    91:
                     92: short *ritem;
                     93: short *rlhs;
                     94: short *rrhs;
                     95: short *rprec;
1.26      tedu       96: char *rassoc;
1.1       deraadt    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.31    ! espie     106: void cleanup_temp_files(void);
1.13      deraadt   107:
1.12      pvalchev  108: void
1.31    ! espie     109: cleanup_temp_files()
1.1       deraadt   110: {
1.26      tedu      111:        if (action_file)
                    112:                unlink(action_file_name);
                    113:        if (text_file)
                    114:                unlink(text_file_name);
                    115:        if (union_file)
                    116:                unlink(union_file_name);
1.31    ! espie     117: }
        !           118:
        !           119: void
        !           120: done(int k)
        !           121: {
        !           122:        cleanup_temp_files();
1.26      tedu      123:        exit(k);
1.1       deraadt   124: }
                    125:
                    126: void
1.29      tedu      127: onintr(__unused int signo)
1.1       deraadt   128: {
1.31    ! espie     129:        cleanup_temp_files();
        !           130:        _exit(1);
1.1       deraadt   131: }
                    132:
                    133:
1.12      pvalchev  134: void
1.18      pvalchev  135: set_signals(void)
1.1       deraadt   136: {
                    137: #ifdef SIGINT
1.26      tedu      138:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                    139:                signal(SIGINT, onintr);
1.1       deraadt   140: #endif
                    141: #ifdef SIGTERM
1.26      tedu      142:        if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
                    143:                signal(SIGTERM, onintr);
1.1       deraadt   144: #endif
                    145: #ifdef SIGHUP
1.26      tedu      146:        if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                    147:                signal(SIGHUP, onintr);
1.1       deraadt   148: #endif
                    149: }
                    150:
                    151:
1.12      pvalchev  152: void
1.18      pvalchev  153: usage(void)
1.1       deraadt   154: {
1.26      tedu      155:        fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-o output_file] [-p symbol_prefix] file\n", __progname);
                    156:        exit(1);
1.1       deraadt   157: }
                    158:
                    159:
1.12      pvalchev  160: void
1.18      pvalchev  161: getargs(int argc, char *argv[])
1.1       deraadt   162: {
1.26      tedu      163:        int ch;
1.1       deraadt   164:
1.26      tedu      165:        while ((ch = getopt(argc, argv, "b:dlo:p:rtv")) != -1) {
                    166:                switch (ch) {
                    167:                case 'b':
                    168:                        file_prefix = optarg;
                    169:                        break;
                    170:
                    171:                case 'd':
                    172:                        dflag = 1;
                    173:                        break;
                    174:
                    175:                case 'l':
                    176:                        lflag = 1;
                    177:                        break;
                    178:
                    179:                case 'o':
                    180:                        output_file_name = optarg;
                    181:                        explicit_file_name = 1;
                    182:                        break;
                    183:
                    184:                case 'p':
                    185:                        symbol_prefix = optarg;
                    186:                        break;
                    187:
                    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:        }
                    204:        argc -= optind;
                    205:        argv += optind;
1.1       deraadt   206:
1.26      tedu      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:
1.25      millert   216: void *
                    217: allocate(size_t n)
1.1       deraadt   218: {
1.26      tedu      219:        void *v;
1.1       deraadt   220:
1.26      tedu      221:        v = NULL;
                    222:        if (n) {
                    223:                v = calloc(1, n);
                    224:                if (!v)
                    225:                        no_space();
                    226:        }
                    227:        return (v);
1.1       deraadt   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.26      tedu      236:        size_t len;
                    237:        char *tmpdir;
1.1       deraadt   238:
1.28      tedu      239:        tmpdir = _PATH_TMP;
1.1       deraadt   240:
1.26      tedu      241:        len = strlen(tmpdir);
                    242:        if (tmpdir[len - 1] == '/')
                    243:                len--;
                    244:
                    245:        if (TEMPNAME(action_file_name, 'a', tmpdir, len) == -1 ||
                    246:            TEMPNAME(text_file_name, 'r', tmpdir, len) == -1 ||
                    247:            TEMPNAME(union_file_name, 'u', tmpdir, len) == -1)
                    248:                no_space();
                    249:
                    250:        if (output_file_name == NULL) {
                    251:                if (asprintf(&output_file_name, "%s%s", file_prefix, OUTPUT_SUFFIX)
                    252:                    == -1)
                    253:                        no_space();
                    254:        }
                    255:        if (rflag) {
                    256:                if (asprintf(&code_file_name, "%s%s", file_prefix, CODE_SUFFIX) == -1)
                    257:                        no_space();
                    258:        } else
                    259:                code_file_name = output_file_name;
                    260:
                    261:        if (dflag) {
                    262:                if (explicit_file_name) {
                    263:                        char *suffix;
                    264:
                    265:                        defines_file_name = strdup(output_file_name);
                    266:                        if (defines_file_name == 0)
                    267:                                no_space();
                    268:
                    269:                        /* does the output_file_name have a known suffix */
                    270:                        if ((suffix = strrchr(output_file_name, '.')) != 0 &&
                    271:                            (!strcmp(suffix, ".c") ||   /* good, old-fashioned C */
                    272:                             !strcmp(suffix, ".C") ||   /* C++, or C on Windows */
                    273:                             !strcmp(suffix, ".cc") ||  /* C++ */
                    274:                             !strcmp(suffix, ".cxx") || /* C++ */
                    275:                             !strcmp(suffix, ".cpp"))) {/* C++ (Windows) */
                    276:                                strncpy(defines_file_name, output_file_name,
                    277:                                        suffix - output_file_name + 1);
                    278:                                defines_file_name[suffix - output_file_name + 1] = 'h';
                    279:                                defines_file_name[suffix - output_file_name + 2] = '\0';
                    280:                        } else {
                    281:                                fprintf(stderr, "%s: suffix of output file name %s"
                    282:                                 " not recognized, no -d file generated.\n",
                    283:                                        __progname, output_file_name);
                    284:                                dflag = 0;
                    285:                                free(defines_file_name);
                    286:                                defines_file_name = 0;
                    287:                        }
                    288:                } else {
                    289:                        if (asprintf(&defines_file_name, "%s%s", file_prefix,
                    290:                                     DEFINES_SUFFIX) == -1)
                    291:                                no_space();
                    292:                }
1.2       niklas    293:        }
1.26      tedu      294:        if (vflag) {
                    295:                if (asprintf(&verbose_file_name, "%s%s", file_prefix,
                    296:                             VERBOSE_SUFFIX) == -1)
                    297:                        no_space();
1.2       niklas    298:        }
1.1       deraadt   299: }
                    300:
1.4       deraadt   301:
1.12      pvalchev  302: void
1.18      pvalchev  303: open_files(void)
1.1       deraadt   304: {
1.26      tedu      305:        int fd;
1.4       deraadt   306:
1.26      tedu      307:        create_file_names();
1.1       deraadt   308:
1.30      espie     309:        if (input_file == NULL) {
1.26      tedu      310:                input_file = fopen(input_file_name, "r");
1.30      espie     311:                if (input_file == NULL)
1.26      tedu      312:                        open_error(input_file_name);
                    313:        }
                    314:        fd = mkstemp(action_file_name);
                    315:        if (fd == -1 || (action_file = fdopen(fd, "w")) == NULL)
                    316:                open_error(action_file_name);
                    317:
                    318:        fd = mkstemp(text_file_name);
                    319:        if (fd == -1 || (text_file = fdopen(fd, "w")) == NULL)
                    320:                open_error(text_file_name);
                    321:
                    322:        if (vflag) {
                    323:                verbose_file = fopen(verbose_file_name, "w");
1.30      espie     324:                if (verbose_file == NULL)
1.26      tedu      325:                        open_error(verbose_file_name);
                    326:        }
                    327:        if (dflag) {
                    328:                defines_file = fopen(defines_file_name, "w");
                    329:                if (defines_file == NULL)
                    330:                        open_write_error(defines_file_name);
                    331:                fd = mkstemp(union_file_name);
                    332:                if (fd == -1 || (union_file = fdopen(fd, "w")) == NULL)
                    333:                        open_error(union_file_name);
                    334:        }
                    335:        output_file = fopen(output_file_name, "w");
1.30      espie     336:        if (output_file == NULL)
1.26      tedu      337:                open_error(output_file_name);
                    338:
                    339:        if (rflag) {
                    340:                code_file = fopen(code_file_name, "w");
1.30      espie     341:                if (code_file == NULL)
1.26      tedu      342:                        open_error(code_file_name);
                    343:        } else
                    344:                code_file = output_file;
1.1       deraadt   345: }
                    346:
                    347:
                    348: int
1.18      pvalchev  349: main(int argc, char *argv[])
1.1       deraadt   350: {
1.27      deraadt   351:        if (pledge("stdio rpath wpath cpath", NULL) == -1)
                    352:                fatal("pledge: invalid arguments");
                    353:
1.26      tedu      354:        set_signals();
                    355:        getargs(argc, argv);
                    356:        open_files();
                    357:        reader();
                    358:        lr0();
                    359:        lalr();
                    360:        make_parser();
                    361:        verbose();
                    362:        output();
                    363:        done(0);
                    364:        /* NOTREACHED */
                    365:        return (0);
1.1       deraadt   366: }