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

Annotation of src/usr.bin/make/lowparse.c, Revision 1.1

1.1     ! espie       1: /*     $OpenBSD$ */
        !             2:
        !             3: /* low-level parsing functions. */
        !             4:
        !             5: /*
        !             6:  * Copyright (c) 1999,2000 Marc Espie.
        !             7:  *
        !             8:  * Extensive code changes for the OpenBSD project.
        !             9:  *
        !            10:  * Redistribution and use in source and binary forms, with or without
        !            11:  * modification, are permitted provided that the following conditions
        !            12:  * are met:
        !            13:  * 1. Redistributions of source code must retain the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer.
        !            15:  * 2. Redistributions in binary form must reproduce the above copyright
        !            16:  *    notice, this list of conditions and the following disclaimer in the
        !            17:  *    documentation and/or other materials provided with the distribution.
        !            18:  *
        !            19:  * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
        !            20:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        !            21:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        !            22:  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OPENBSD
        !            23:  * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        !            24:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        !            25:  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            26:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            27:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            28:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        !            29:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            30:  */
        !            31:
        !            32: #include <stdarg.h>
        !            33: #include <stdio.h>
        !            34: #include <assert.h>
        !            35: #include "make.h"
        !            36: #include "buf.h"
        !            37: #include "lowparse.h"
        !            38:
        !            39: #ifdef CLEANUP
        !            40: static LIST        fileNames;  /* file names to free at end */
        !            41: #endif
        !            42:
        !            43: static LIST     includes;      /* stack of IFiles generated by
        !            44:                                 * #includes */
        !            45:
        !            46: static IFile *new_ifile __P((char *, FILE *));
        !            47: static IFile *new_istring __P((char *, char *, unsigned long));
        !            48: static void free_ifile __P((IFile *));
        !            49: static void ParseVErrorInternal __P((char *, unsigned long, int, char *, va_list));
        !            50: static int skiptoendofline __P((void));
        !            51: static int ParseSkipEmptyLines __P((Buffer));
        !            52: static int         fatals = 0;
        !            53:
        !            54: /*-
        !            55:  * ParseVErrorInternal  --
        !            56:  *     Error message abort function for parsing. Prints out the context
        !            57:  *     of the error (line number and file) as well as the message with
        !            58:  *     two optional arguments.
        !            59:  *
        !            60:  * Side Effects:
        !            61:  *     "fatals" is incremented if the level is PARSE_FATAL.
        !            62:  */
        !            63: /* VARARGS */
        !            64: static void
        !            65: #ifdef __STDC__
        !            66: ParseVErrorInternal(char *cfname, unsigned long clineno, int type, char *fmt,
        !            67:     va_list ap)
        !            68: #else
        !            69: ParseVErrorInternal(va_alist)
        !            70:        va_dcl
        !            71: #endif
        !            72: {
        !            73:        (void)fprintf(stderr, "\"%s\", line %lu: ", cfname, clineno);
        !            74:        if (type == PARSE_WARNING)
        !            75:                (void)fprintf(stderr, "warning: ");
        !            76:        (void)vfprintf(stderr, fmt, ap);
        !            77:        va_end(ap);
        !            78:        (void)fprintf(stderr, "\n");
        !            79:        if (type == PARSE_FATAL)
        !            80:                fatals ++;
        !            81: }
        !            82:
        !            83: /*-
        !            84:  * Parse_Error  --
        !            85:  *     External interface to ParseVErrorInternal; uses the default filename
        !            86:  *     Line number.
        !            87:  */
        !            88: /* VARARGS */
        !            89: void
        !            90: #ifdef __STDC__
        !            91: Parse_Error(int type, char *fmt, ...)
        !            92: #else
        !            93: Parse_Error(va_alist)
        !            94:        va_dcl
        !            95: #endif
        !            96: {
        !            97:        va_list ap;
        !            98: #ifdef __STDC__
        !            99:        va_start(ap, fmt);
        !           100: #else
        !           101:        int type;               /* Error type (PARSE_WARNING, PARSE_FATAL) */
        !           102:        char *fmt;
        !           103:
        !           104:        va_start(ap);
        !           105:        type = va_arg(ap, int);
        !           106:        fmt = va_arg(ap, char *);
        !           107: #endif
        !           108:
        !           109:        ParseVErrorInternal(current->fname, current->lineno, type, fmt, ap);
        !           110: }
        !           111:
        !           112: static IFile *
        !           113: new_ifile(name, stream)
        !           114:     char *name;
        !           115:     FILE *stream;
        !           116: {
        !           117:     IFile *ifile;
        !           118: #ifdef CLEANUP
        !           119:     Lst_AtEnd(&fileNames, name);
        !           120: #endif
        !           121:
        !           122:     ifile = emalloc(sizeof(*ifile));
        !           123:     ifile->fname = name;
        !           124:     /* Naturally enough, we start reading at line 0 */
        !           125:     ifile->lineno = 0;
        !           126:     ifile->F = stream;
        !           127:     ifile->ptr = ifile->end = NULL;
        !           128:     return ifile;
        !           129: }
        !           130:
        !           131: static void
        !           132: free_ifile(ifile)
        !           133:     IFile *ifile;
        !           134: {
        !           135:     if (ifile->F)
        !           136:        (void)fclose(ifile->F);
        !           137:     else
        !           138:        free(ifile->str);
        !           139:     /* Note we can't free the file names yet, as they are embedded in GN for
        !           140:      * error reports. */
        !           141:     free(ifile);
        !           142: }
        !           143:
        !           144: static IFile *
        !           145: new_istring(str, name, lineno)
        !           146:     char *str;
        !           147:     char *name;
        !           148:     unsigned long lineno;
        !           149: {
        !           150:     IFile *ifile;
        !           151:
        !           152:     ifile = emalloc(sizeof(*ifile));
        !           153:     ifile->fname = name;
        !           154:     ifile->F = NULL;
        !           155:     /* Strings are used from for loops... */
        !           156:     ifile->lineno = lineno;
        !           157:     ifile->ptr = ifile->str = str;
        !           158:     ifile->end = str + strlen(str);
        !           159:     return ifile;
        !           160: }
        !           161:
        !           162:
        !           163: /*-
        !           164:  *---------------------------------------------------------------------
        !           165:  * Parse_FromString  --
        !           166:  *     Start Parsing from the given string
        !           167:  *
        !           168:  * Side Effects:
        !           169:  *     A structure is added to the includes Lst and readProc, lineno,
        !           170:  *     fname and curFILE are altered for the new file
        !           171:  *---------------------------------------------------------------------
        !           172:  */
        !           173: void
        !           174: Parse_FromString(str, lineno)
        !           175:     char               *str;
        !           176:     unsigned long      lineno;
        !           177: {
        !           178:     if (DEBUG(FOR))
        !           179:        (void)fprintf(stderr, "%s\n----\n", str);
        !           180:
        !           181:     if (current != NULL)
        !           182:        Lst_AtFront(&includes, current);
        !           183:     current = new_istring(str, current->fname, lineno);
        !           184: }
        !           185:
        !           186:
        !           187: void
        !           188: Parse_FromFile(name, stream)
        !           189:     char               *name;
        !           190:     FILE               *stream;
        !           191: {
        !           192:     if (current != NULL)
        !           193:        Lst_AtFront(&includes, current);
        !           194:     current = new_ifile(name, stream);
        !           195: }
        !           196:
        !           197: /*-
        !           198:  *---------------------------------------------------------------------
        !           199:  * Parse_NextFile --
        !           200:  *     Called when EOF is reached in the current file. If we were reading
        !           201:  *     an include file, the includes stack is popped and things set up
        !           202:  *     to go back to reading the previous file at the previous location.
        !           203:  *
        !           204:  * Results:
        !           205:  *     CONTINUE if there's more to do. DONE if not.
        !           206:  *
        !           207:  * Side Effects:
        !           208:  *     The old curFILE, is closed. The includes list is shortened.
        !           209:  *     lineno, curFILE, and fname are changed if CONTINUE is returned.
        !           210:  *---------------------------------------------------------------------
        !           211:  */
        !           212: Boolean
        !           213: Parse_NextFile()
        !           214: {
        !           215:     IFile *next;
        !           216:
        !           217:     next = (IFile *)Lst_DeQueue(&includes);
        !           218:     if (next != NULL) {
        !           219:        if (current != NULL)
        !           220:            free_ifile(current);
        !           221:        current = next;
        !           222:        return TRUE;
        !           223:     } else
        !           224:        return FALSE;
        !           225: }
        !           226:
        !           227:
        !           228: int
        !           229: newline()
        !           230: {
        !           231:     size_t len;
        !           232:
        !           233:     if (current->F) {
        !           234:        current->ptr = fgetln(current->F, &len);
        !           235:        if (current->ptr) {
        !           236:            current->end = current->ptr + len;
        !           237:            return *current->ptr++;
        !           238:        } else {
        !           239:            current->end = NULL;
        !           240:        }
        !           241:     }
        !           242:     return EOF;
        !           243: }
        !           244:
        !           245: void
        !           246: ParseUnreadc(c)
        !           247:        char c;
        !           248: {
        !           249:        current->ptr--;
        !           250:        *current->ptr = c;
        !           251: }
        !           252:
        !           253: unsigned long
        !           254: Parse_Getlineno()
        !           255: {
        !           256:     return current->lineno;
        !           257: }
        !           258:
        !           259: const char *
        !           260: Parse_Getfilename()
        !           261: {
        !           262:     return current->fname;
        !           263: }
        !           264:
        !           265: #ifdef CLEANUP
        !           266: void
        !           267: LowParse_Init()
        !           268: {
        !           269:     Lst_Init(&includes);
        !           270:     current = NULL;
        !           271: }
        !           272:
        !           273: void
        !           274: LowParse_End()
        !           275: {
        !           276:     Lst_Destroy(&includes, NOFREE);    /* Should be empty now */
        !           277: }
        !           278: #endif
        !           279:
        !           280:
        !           281: void
        !           282: Finish_Errors()
        !           283: {
        !           284:     if (current != NULL) {
        !           285:        free_ifile(current);
        !           286:        current = NULL;
        !           287:     }
        !           288:     if (fatals) {
        !           289:        fprintf(stderr, "Fatal errors encountered -- cannot continue\n");
        !           290:        exit(1);
        !           291:     }
        !           292: }