home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bsd / src / make / make-amiga / var.c < prev   
C/C++ Source or Header  |  1993-09-23  |  53KB  |  1,880 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[] = "@(#)var.c    5.7 (Berkeley) 6/1/90";
  41. #endif /* not lint */
  42.  
  43. /*-
  44.  * var.c --
  45.  *    Variable-handling functions
  46.  *
  47.  * Interface:
  48.  *    Var_Set              Set the value of a variable in the given
  49.  *                      context. The variable is created if it doesn't
  50.  *                      yet exist. The value and variable name need not
  51.  *                      be preserved.
  52.  *
  53.  *    Var_Append        Append more characters to an existing variable
  54.  *                      in the given context. The variable needn't
  55.  *                      exist already -- it will be created if it doesn't.
  56.  *                      A space is placed between the old value and the
  57.  *                      new one.
  58.  *
  59.  *    Var_Exists        See if a variable exists.
  60.  *
  61.  *    Var_Value         Return the value of a variable in a context or
  62.  *                      NULL if the variable is undefined.
  63.  *
  64.  *    Var_Subst         Substitute for all variables in a string using
  65.  *                      the given context as the top-most one. If the
  66.  *                      third argument is non-zero, Parse_Error is
  67.  *                      called if any variables are undefined.
  68.  *
  69.  *    Var_Parse         Parse a variable expansion from a string and
  70.  *                      return the result and the number of characters
  71.  *                      consumed.
  72.  *
  73.  *    Var_Delete        Delete a variable in a context.
  74.  *
  75.  *    Var_Init          Initialize this module.
  76.  *
  77.  * Debugging:
  78.  *    Var_Dump          Print out all variables defined in the given
  79.  *                      context.
  80.  *
  81.  * XXX: There's a lot of duplication in these functions.
  82.  */
  83.  
  84. #include    <ctype.h>
  85. #include    "make.h"
  86. #include    "buf.h"
  87. extern char *getenv();
  88.  
  89. /*
  90.  * This is a harmless return value for Var_Parse that can be used by Var_Subst
  91.  * to determine if there was an error in parsing -- easier than returning
  92.  * a flag, as things outside this module don't give a hoot.
  93.  */
  94. char     var_Error[] = "";
  95.  
  96. /*
  97.  * Similar to var_Error, but returned when the 'err' flag for Var_Parse is
  98.  * set false. Why not just use a constant? Well, gcc likes to condense
  99.  * identical string instances...
  100.  */
  101. char    varNoError[] = "";
  102.  
  103. /*
  104.  * Internally, variables are contained in four different contexts.
  105.  *    1) the environment. They may not be changed. If an environment
  106.  *        variable is appended-to, the result is placed in the global
  107.  *        context.
  108.  *    2) the global context. Variables set in the Makefile are located in
  109.  *        the global context. It is the penultimate context searched when
  110.  *        substituting.
  111.  *    3) the command-line context. All variables set on the command line
  112.  *       are placed in this context. They are UNALTERABLE once placed here.
  113.  *    4) the local context. Each target has associated with it a context
  114.  *       list. On this list are located the structures describing such
  115.  *       local variables as $(@) and $(*)
  116.  * The four contexts are searched in the reverse order from which they are
  117.  * listed.
  118.  */
  119. GNode          *VAR_GLOBAL;   /* variables from the makefile */
  120. GNode          *VAR_CMD;      /* variables defined on the command-line */
  121.  
  122. #define FIND_CMD    0x1   /* look in VAR_CMD when searching */
  123. #define FIND_GLOBAL    0x2   /* look in VAR_GLOBAL as well */
  124. #define FIND_ENV      0x4   /* look in the environment also */
  125.  
  126. typedef struct Var {
  127.     char          *name;    /* the variable's name */
  128.     Buffer      val;            /* its value */
  129.     int              flags;        /* miscellaneous status flags */
  130. #define VAR_IN_USE    1           /* Variable's value currently being used.
  131.                      * Used to avoid recursion */
  132. #define VAR_FROM_ENV    2           /* Variable comes from the environment */
  133. #define VAR_JUNK      4           /* Variable is a junk variable that
  134.                      * should be destroyed when done with
  135.                      * it. Used by Var_Parse for undefined,
  136.                      * modified variables */
  137. }  Var;
  138.  
  139. /*-
  140.  *-----------------------------------------------------------------------
  141.  * VarCmp  --
  142.  *    See if the given variable matches the named one. Called from
  143.  *    Lst_Find when searching for a variable of a given name.
  144.  *
  145.  * Results:
  146.  *    0 if they match. non-zero otherwise.
  147.  *
  148.  * Side Effects:
  149.  *    none
  150.  *-----------------------------------------------------------------------
  151.  */
  152. static int
  153. VarCmp (v, name)
  154.     Var            *v;        /* VAR structure to compare */
  155.     char           *name;    /* name to look for */
  156. {
  157.     return (strcmp (name, v->name));
  158. }
  159.  
  160. /*-
  161.  *-----------------------------------------------------------------------
  162.  * VarFind --
  163.  *    Find the given variable in the given context and any other contexts
  164.  *    indicated.
  165.  *
  166.  * Results:
  167.  *    A pointer to the structure describing the desired variable or
  168.  *    NIL if the variable does not exist.
  169.  *
  170.  * Side Effects:
  171.  *    None
  172.  *-----------------------------------------------------------------------
  173.  */
  174. static Var *
  175. VarFind (name, ctxt, flags)
  176.     char               *name;    /* name to find */
  177.     GNode              *ctxt;    /* context in which to find it */
  178.     int                 flags;    /* FIND_GLOBAL set means to look in the
  179.                  * VAR_GLOBAL context as well.
  180.                  * FIND_CMD set means to look in the VAR_CMD
  181.                  * context also.
  182.                  * FIND_ENV set means to look in the
  183.                  * environment */
  184. {
  185.     LstNode             var;
  186.     Var              *v;
  187.  
  188.     /*
  189.      * If the variable name begins with a '.', it could very well be one of
  190.      * the local ones.  We check the name against all the local variables
  191.      * and substitute the short version in for 'name' if it matches one of
  192.      * them.
  193.      */
  194.     if (*name == '.' && isupper(name[1]))
  195.         switch (name[1]) {
  196.         case 'A':
  197.             if (!strcmp(name, ".ALLSRC"))
  198.                 name = ALLSRC;
  199.             if (!strcmp(name, ".ARCHIVE"))
  200.                 name = ARCHIVE;
  201.             break;
  202.         case 'I':
  203.             if (!strcmp(name, ".IMPSRC"))
  204.                 name = IMPSRC;
  205.             break;
  206.         case 'M':
  207.             if (!strcmp(name, ".MEMBER"))
  208.                 name = MEMBER;
  209.             break;
  210.         case 'O':
  211.             if (!strcmp(name, ".OODATE"))
  212.                 name = OODATE;
  213.             break;
  214.         case 'P':
  215.             if (!strcmp(name, ".PREFIX"))
  216.                 name = PREFIX;
  217.             break;
  218.         case 'T':
  219.             if (!strcmp(name, ".TARGET"))
  220.                 name = TARGET;
  221.             break;
  222.         }
  223.     /*
  224.      * First look for the variable in the given context. If it's not there,
  225.      * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
  226.      * depending on the FIND_* flags in 'flags'
  227.      */
  228.     var = Lst_Find (ctxt->context, (ClientData)name, VarCmp);
  229.  
  230.     if ((var == NILLNODE) && (flags & FIND_C