home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bsd / src / make / make-amiga / parse.c < prev    next >
C/C++ Source or Header  |  1993-09-23  |  60KB  |  2,213 lines

  1. /*
  2.  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
  3.  * Copyright (c) 1988, 1989 by Adam de Boor
  4.  * Copyright (c) 1989 by Berkeley Softworks
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Adam de Boor.
  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.  * 3. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  *    This product includes software developed by the University of
  21.  *    California, Berkeley and its contributors.
  22.  * 4. Neither the name of the University nor the names of its contributors
  23.  *    may be used to endorse or promote products derived from this software
  24.  *    without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  */
  38.  
  39. #ifndef lint
  40. static char sccsid[] = "@(#)parse.c    5.18 (Berkeley) 2/19/91";
  41. #endif /* not lint */
  42.  
  43. /*-
  44.  * parse.c --
  45.  *    Functions to parse a makefile.
  46.  *
  47.  *    One function, Parse_Init, must be called before any functions
  48.  *    in this module are used. After that, the function Parse_File is the
  49.  *    main entry point and controls most of the other functions in this
  50.  *    module.
  51.  *
  52.  *    Most important structures are kept in Lsts. Directories for
  53.  *    the #include "..." function are kept in the 'parseIncPath' Lst, while
  54.  *    those for the #include <...> are kept in the 'sysIncPath' Lst. The
  55.  *    targets currently being defined are kept in the 'targets' Lst.
  56.  *
  57.  *    The variables 'fname' and 'lineno' are used to track the name
  58.  *    of the current file and the line number in that file so that error
  59.  *    messages can be more meaningful.
  60.  *
  61.  * Interface:
  62.  *    Parse_Init                Initialization function which must be
  63.  *                              called before anything else in this module
  64.  *                              is used.
  65.  *
  66.  *    Parse_File                Function used to parse a makefile. It must
  67.  *                              be given the name of the file, which should
  68.  *                              already have been opened, and a function
  69.  *                              to call to read a character from the file.
  70.  *
  71.  *    Parse_IsVar                Returns TRUE if the given line is a
  72.  *                              variable assignment. Used by MainParseArgs
  73.  *                              to determine if an argument is a target
  74.  *                              or a variable assignment. Used internally
  75.  *                              for pretty much the same thing...
  76.  *
  77.  *    Parse_Error                Function called when an error occurs in
  78.  *                              parsing. Used by the variable and
  79.  *                              conditional modules.
  80.  *    Parse_MainName                Returns a Lst of the main target to create.
  81.  */
  82.  
  83. #include <varargs.h>
  84. #include <stdio.h>
  85. #include <ctype.h>
  86. #include "make.h"
  87. #include "buf.h"
  88. #include "pathnames.h"
  89.  
  90. /*
  91.  * These values are returned by ParseEOF to tell Parse_File whether to
  92.  * CONTINUE parsing, i.e. it had only reached the end of an include file,
  93.  * or if it's DONE.
  94.  */
  95. #define    CONTINUE    1
  96. #define    DONE        0
  97. static int         ParseEOF();
  98.  
  99. static Lst             targets;    /* targets we're working on */
  100. static Boolean        inLine;    /* true if currently in a dependency
  101.                  * line or its commands */
  102.  
  103. static char            *fname;    /* name of current file (for errors) */
  104. static int          lineno;    /* line number in current file */
  105. static FILE           *curFILE;     /* current makefile */
  106.  
  107. static int        fatals = 0;
  108.  
  109. static GNode        *mainNode;    /* The main target to create. This is the
  110.                  * first target on the first dependency
  111.                  * line in the first makefile */
  112. /*
  113.  * Definitions for handling #include specifications
  114.  */
  115. typedef struct IFile {
  116.     char           *fname;        /* name of previous file */
  117.     int             lineno;        /* saved line number */
  118.     FILE *       F;            /* the open stream */
  119. }                    IFile;
  120.  
  121. static Lst      includes;      /* stack of IFiles generated by
  122.                  * #includes */
  123. Lst             parseIncPath;    /* list of directories for "..." includes */
  124. Lst             sysIncPath;    /* list of directories for <...> includes */
  125.  
  126. /*-
  127.  * specType contains the SPECial TYPE of the current target. It is
  128.  * Not if the target is unspecial. If it *is* special, however, the children
  129.  * are linked as children of the parent but not vice versa. This variable is
  130.  * set in ParseDoDependency
  131.  */
  132. typedef enum {
  133.     Begin,          /* .BEGIN */
  134.     Default,        /* .DEFAULT */
  135.     End,            /* .END */
  136.     Ignore,        /* .IGNORE */
  137.     Includes,        /* .INCLUDES */
  138.     Interrupt,        /* .INTERRUPT */
  139.     Libs,        /* .LIBS */
  140.     MFlags,        /* .MFLAGS or .MAKEFLAGS */
  141.     Main,        /* .MAIN and we don't have anything user-specified to
  142.              * make */
  143.     Not,        /* Not special */
  144.     NotParallel,    /* .NOTPARALELL */
  145.     Null,           /* .NULL */
  146.     Order,          /* .ORDER */
  147.     Path,        /* .PATH */
  148.     Precious,        /* .PRECIOUS */
  149.     Shell,        /* .SHELL */
  150.     Silent,        /* .SILENT */
  151.     SingleShell,    /* .SINGLESHELL */
  152.     Suffixes,        /* .SUFFIXES */
  153.     Attribute,        /* Generic attribute */
  154. } ParseSpecial;
  155.  
  156. ParseSpecial specType;
  157.  
  158. /*
  159.  * Predecessor node for handling .ORDER. Initialized to NILGNODE when .ORDER
  160.  * seen, then set to each successive source on the line.
  161.  */
  162. static GNode    *predecessor;
  163.  
  164. /*
  165.  * The parseKeywords table is searched using binary search when deciding
  166.  * if a target or source is special. The 'spec' field is the ParseSpecial
  167.  * type of the keyword ("Not" if the keyword isn't special as a target) while
  168.  * the 'op' field is the operator to apply to the list of targets if the
  169.  * keyword is used as a source ("0" if the keyword isn't special as a source)
  170.  */
  171. static struct {
  172.     char          *name;        /* Name of keyword */
  173.     ParseSpecial  spec;            /* Type when used as a target */
  174.     int              op;            /* Operator when used as a source */
  175. } parseKeywords[] = {
  176. { ".BEGIN",       Begin,        0 },
  177. { ".DEFAULT",      Default,      0 },
  178. { ".OPTIONAL",      Attribute,       OP_OPTIONAL },
  179. { ".END",         End,            0 },
  180. { ".EXEC",      Attribute,       OP_EXEC },
  181. { ".IGNORE",      Ignore,       OP_IGNORE },
  182. { ".INCLUDES",      Includes,     0 },
  183. { ".INTERRUPT",      Interrupt,    0 },
  184. { ".INVISIBLE",      Attribute,       OP_INVISIBLE },
  185. { ".JOIN",        Attribute,       OP_JOIN },
  186. { ".LIBS",        Libs,            0 },
  187. { ".MAIN",      Main,        0 },
  188. { ".MAKE",        Attribute,       OP_MAKE },
  189. { ".MAKEFLAGS",      MFlags,       0 },
  190. { ".MFLAGS",      MFlags,       0 },
  191. { ".NOTMAIN",      Attribute,       OP_NOTMAIN },
  192. { ".NOTPARALLEL", NotParallel,    0 },
  193. { ".NULL",        Null,            0 },
  194. { ".ORDER",       Order,        0 },
  195. { ".PATH",      Path,        0 },
  196. { ".PRECIOUS",      Precious,     OP_PRECIOUS },
  197. { ".RECURSIVE",      Attribute,    OP_MAKE },
  198. { ".SHELL",       Shell,        0 },
  199. { ".SILENT",      Silent,       OP_SILENT },
  200. { ".SINGLESHELL", SingleShell,    0 },
  201. { ".SUFFIXES",      Suffixes,     0 },
  202. { ".USE",         Attribute,       OP_USE },
  203. };
  204.  
  205. /*-
  206.  *----------------------------------------------------------------------
  207.  * ParseFindKeyword --
  208.  *    Look in the table of keywords for one matching the given string.
  209.  *
  210.  * Results:
  211.  *    The index of the keyword, or -1 if it isn't there.
  212.  *
  213.  * Side Effects:
  214.  *    None
  215.  *------------------