diff options
Diffstat (limited to 'usr.bin/make/parse.c')
-rw-r--r-- | usr.bin/make/parse.c | 203 |
1 files changed, 127 insertions, 76 deletions
diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c index a6a085a..b1c63a6 100644 --- a/usr.bin/make/parse.c +++ b/usr.bin/make/parse.c @@ -63,6 +63,8 @@ static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94"; * called before anything else in this module * is used. * + * Parse_End Cleanup the module + * * Parse_File Function used to parse a makefile. It must * be given the name of the file, which should * already have been opened, and a function @@ -104,6 +106,7 @@ static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94"; #define CONTINUE 1 #define DONE 0 static Lst targets; /* targets we're working on */ +static Lst targCmds; /* command lines for targets */ static Boolean inLine; /* true if currently in a dependency * line or its commands */ typedef struct { @@ -218,17 +221,17 @@ static struct { }; static int ParseFindKeyword __P((char *)); -static int ParseLinkSrc __P((GNode *, GNode *)); -static int ParseDoOp __P((GNode *, int)); +static int ParseLinkSrc __P((ClientData, ClientData)); +static int ParseDoOp __P((ClientData, ClientData)); static void ParseDoSrc __P((int, char *)); -static int ParseFindMain __P((GNode *)); -static int ParseAddDir __P((Lst, char *)); -static int ParseClearPath __P((Lst)); +static int ParseFindMain __P((ClientData, ClientData)); +static int ParseAddDir __P((ClientData, ClientData)); +static int ParseClearPath __P((ClientData, ClientData)); static void ParseDoDependency __P((char *)); -static int ParseAddCmd __P((GNode *, char *)); +static int ParseAddCmd __P((ClientData, ClientData)); static int ParseReadc __P((void)); static void ParseUnreadc __P((int)); -static int ParseHasCommands __P((GNode *)); +static void ParseHasCommands __P((ClientData)); static void ParseDoInclude __P((char *)); #ifdef SYSVINCLUDE static void ParseTraditionalInclude __P((char *)); @@ -292,7 +295,7 @@ ParseFindKeyword (str) /* VARARGS */ void #if __STDC__ -Parse_Error(int type, const char *fmt, ...) +Parse_Error(int type, char *fmt, ...) #else Parse_Error(va_alist) va_dcl @@ -338,10 +341,12 @@ Parse_Error(va_alist) *--------------------------------------------------------------------- */ static int -ParseLinkSrc (pgn, cgn) - GNode *pgn; /* The parent node */ - GNode *cgn; /* The child node */ +ParseLinkSrc (pgnp, cgnp) + ClientData pgnp; /* The parent node */ + ClientData cgnp; /* The child node */ { + GNode *pgn = (GNode *) pgnp; + GNode *cgn = (GNode *) cgnp; if (Lst_Member (pgn->children, (ClientData)cgn) == NILLNODE) { (void)Lst_AtEnd (pgn->children, (ClientData)cgn); if (specType == Not) { @@ -369,11 +374,13 @@ ParseLinkSrc (pgn, cgn) *--------------------------------------------------------------------- */ static int -ParseDoOp (gn, op) - GNode *gn; /* The node to which the operator is to be +ParseDoOp (gnp, opp) + ClientData gnp; /* The node to which the operator is to be * applied */ - int op; /* The operator to apply */ + ClientData opp; /* The operator to apply */ { + GNode *gn = (GNode *) gnp; + int op = *(int *) opp; /* * If the dependency mask of the operator and the node don't match and * the node has actually had an operator applied to it before, and @@ -461,7 +468,7 @@ ParseDoSrc (tOp, src) } } if (op != 0) { - Lst_ForEach (targets, ParseDoOp, (ClientData)op); + Lst_ForEach (targets, ParseDoOp, (ClientData)&op); } else if (specType == Main) { /* * If we have noted the existence of a .MAIN, it means we need @@ -541,15 +548,17 @@ ParseDoSrc (tOp, src) *----------------------------------------------------------------------- */ static int -ParseFindMain(gn) - GNode *gn; /* Node to examine */ +ParseFindMain(gnp, dummy) + ClientData gnp; /* Node to examine */ + ClientData dummy; { + GNode *gn = (GNode *) gnp; if ((gn->type & (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM)) == 0) { mainNode = gn; Targ_SetMain(gn); - return (1); + return (dummy ? 1 : 1); } else { - return (0); + return (dummy ? 0 : 0); } } @@ -568,10 +577,10 @@ ParseFindMain(gn) */ static int ParseAddDir(path, name) - Lst path; - char *name; + ClientData path; + ClientData name; { - Dir_AddDir(path, name); + Dir_AddDir((Lst) path, (char *) name); return(0); } @@ -589,11 +598,12 @@ ParseAddDir(path, name) *----------------------------------------------------------------------- */ static int -ParseClearPath(path) - Lst path; +ParseClearPath(path, dummy) + ClientData path; + ClientData dummy; { - Dir_ClearPath(path); - return(0); + Dir_ClearPath((Lst) path); + return(dummy ? 0 : 0); } /*- @@ -634,9 +644,9 @@ static void ParseDoDependency (line) char *line; /* the line to parse */ { - register char *cp; /* our current position */ - register GNode *gn; /* a general purpose temporary node */ - register int op; /* the operator on the line */ + char *cp; /* our current position */ + GNode *gn; /* a general purpose temporary node */ + int op; /* the operator on the line */ char savec; /* a place to save a character */ Lst paths; /* List of search paths to alter when parsing * a list of .PATH targets */ @@ -931,7 +941,7 @@ ParseDoDependency (line) cp++; /* Advance beyond operator */ - Lst_ForEach (targets, ParseDoOp, (ClientData)op); + Lst_ForEach (targets, ParseDoOp, (ClientData)&op); /* * Get to the first source @@ -1225,20 +1235,20 @@ Parse_DoVar (line, ctxt) * assignment. This reduces error checks */ GNode *ctxt; /* Context in which to do the assignment */ { - char *cp; /* pointer into line */ + char *cp; /* pointer into line */ enum { VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL } type; /* Type of assignment */ char *opc; /* ptr to operator character to * null-terminate the variable name */ - /* + /* * Avoid clobbered variable warnings by forcing the compiler * to ``unregister'' variables - */ + */ #if __GNUC__ - (void) &cp; - (void) &line; -#endif + (void) &cp; + (void) &line; +#endif /* * Skip to variable name @@ -1328,13 +1338,14 @@ Parse_DoVar (line, ctxt) Boolean freeCmd; /* TRUE if the command needs to be freed, i.e. * if any variable expansion was performed */ - /* + /* * Avoid clobbered variable warnings by forcing the compiler * to ``unregister'' variables - */ + */ #if __GNUC__ (void) &freeCmd; -#endif +#endif + /* * Set up arguments for shell */ @@ -1402,7 +1413,7 @@ Parse_DoVar (line, ctxt) char result[BUFSIZ]; cc = read(fds[0], result, sizeof(result)); if (cc > 0) - Buf_AddBytes(buf, cc, (unsigned char *) result); + Buf_AddBytes(buf, cc, (Byte *) result); } while (cc > 0 || (cc == -1 && errno == EINTR)); @@ -1481,14 +1492,15 @@ Parse_DoVar (line, ctxt) * A new element is added to the commands list of the node. */ static int -ParseAddCmd(gn, cmd) - GNode *gn; /* the node to which the command is to be added */ - char *cmd; /* the command to add */ +ParseAddCmd(gnp, cmd) + ClientData gnp; /* the node to which the command is to be added */ + ClientData cmd; /* the command to add */ { - /* if target already supplied, ignore commands */ - if (!(gn->type & OP_HAS_COMMANDS)) - (void)Lst_AtEnd(gn->commands, (ClientData)cmd); - return(0); + GNode *gn = (GNode *) gnp; + /* if target already supplied, ignore commands */ + if (!(gn->type & OP_HAS_COMMANDS)) + (void)Lst_AtEnd(gn->commands, cmd); + return(0); } /*- @@ -1500,21 +1512,21 @@ ParseAddCmd(gn, cmd) * on multiple dependency lines. * * Results: - * Always 0. + * None * * Side Effects: * OP_HAS_COMMANDS may be set for the target. * *----------------------------------------------------------------------- */ -static int -ParseHasCommands(gn) - GNode *gn; /* Node to examine */ +static void +ParseHasCommands(gnp) + ClientData gnp; /* Node to examine */ { + GNode *gn = (GNode *) gnp; if (!Lst_IsEmpty(gn->commands)) { gn->type |= OP_HAS_COMMANDS; } - return(0); } /*- @@ -1633,7 +1645,10 @@ ParseDoInclude (file) char *newName; *prefEnd = '\0'; - newName = str_concat (fname, file, STR_ADDSLASH); + if (file[0] == '/') + newName = strdup(file); + else + newName = str_concat (fname, file, STR_ADDSLASH); fullname = Dir_FindFile (newName, parseIncPath); if (fullname == (char *)NULL) { fullname = Dir_FindFile(newName, dirSearchPath); @@ -1674,6 +1689,8 @@ ParseDoInclude (file) return; } + free(file); + /* * Once we find the absolute path to the file, we get to save all the * state from the current file before we can start reading this @@ -2071,7 +2088,8 @@ ParseReadLine () * for the purposes of setting semiNL */ Boolean ignComment; /* TRUE if should ignore comments (in a * shell command */ - char *line; /* Result */ + char *line; /* Result */ + char *ep; /* to strip trailing blanks */ int lineLength; /* Length of result */ semiNL = FALSE; @@ -2181,7 +2199,7 @@ test_char: break; case '#': if (!ignComment) { - if (compatMake || (lastc != '\\')) { + if (compatMake && (lastc != '\\')) { /* * If the character is a hash mark and it isn't escaped * (or we're being compatible), the thing is a comment. @@ -2229,6 +2247,21 @@ test_char: Buf_AddByte (buf, (Byte)'\0'); line = (char *)Buf_GetAll (buf, &lineLength); Buf_Destroy (buf, FALSE); + + /* + * Strip trailing blanks and tabs from the line. + * Do not strip a blank or tab that is preceeded by + * a '\' + */ + ep = line; + while (*ep) + ++ep; + while (ep > line && (ep[-1] == ' ' || ep[-1] == '\t')) { + if (ep > line + 1 && ep[-2] == '\\') + break; + --ep; + } + *ep = 0; if (line[0] == '.') { /* @@ -2302,11 +2335,10 @@ test_char: static void ParseFinishLine() { - extern int Suff_EndTransform(); - if (inLine) { Lst_ForEach(targets, Suff_EndTransform, (ClientData)NULL); Lst_Destroy (targets, ParseHasCommands); + targets = NULL; inLine = FALSE; } } @@ -2356,11 +2388,12 @@ Parse_File(name, stream) goto nextLine; } else if (strncmp(cp, "undef", 5) == 0) { char *cp2; - for (cp += 5; isspace(*cp); cp++) { + for (cp += 5; isspace((unsigned char) *cp); cp++) { continue; } - for (cp2 = cp; !isspace(*cp2) && (*cp2 != '\0'); cp2++) { + for (cp2 = cp; !isspace((unsigned char) *cp2) && + (*cp2 != '\0'); cp2++) { continue; } @@ -2375,17 +2408,14 @@ Parse_File(name, stream) goto nextLine; } - if (*line == '\t' -#ifdef POSIX - || *line == ' ' -#endif - ) - { + if (*line == '\t') { /* - * If a line starts with a tab (or space in POSIX-land), it - * can only hope to be a creation command. + * If a line starts with a tab, it can only hope to be + * a creation command. */ +#ifndef POSIX shellCommand: +#endif for (cp = line + 1; isspace (*cp); cp++) { continue; } @@ -2396,7 +2426,8 @@ Parse_File(name, stream) * in a dependency spec, add the command to the list of * commands of all targets in the dependency spec */ - Lst_ForEach (targets, ParseAddCmd, (ClientData)cp); + Lst_ForEach (targets, ParseAddCmd, cp); + Lst_AtEnd(targCmds, (ClientData) line); continue; } else { Parse_Error (PARSE_FATAL, @@ -2426,24 +2457,28 @@ Parse_File(name, stream) * If it doesn't have an operator and we're in a dependency * line's script, we assume it's actually a shell command * and add it to the current list of targets. - * - * Note that POSIX declares all lines that start with - * whitespace are shell commands, so there's no need to check - * here... */ +#ifndef POSIX Boolean nonSpace = FALSE; +#endif cp = line; + if (isspace((unsigned char) line[0])) { + while ((*cp != '\0') && isspace((unsigned char) *cp)) { + cp++; + } + if (*cp == '\0') { + goto nextLine; + } #ifndef POSIX - if (line[0] == ' ') { while ((*cp != ':') && (*cp != '!') && (*cp != '\0')) { - if (!isspace(*cp)) { - nonSpace = TRUE; - } + nonSpace = TRUE; cp++; } +#endif } +#ifndef POSIX if (*cp == '\0') { if (inLine) { Parse_Error (PARSE_WARNING, @@ -2463,6 +2498,9 @@ Parse_File(name, stream) /* * Need a non-circular list for the target nodes */ + if (targets) + Lst_Destroy(targets, NOFREE); + targets = Lst_Init (FALSE); inLine = TRUE; @@ -2515,6 +2553,7 @@ Parse_Init () parseIncPath = Lst_Init (FALSE); sysIncPath = Lst_Init (FALSE); includes = Lst_Init (FALSE); + targCmds = Lst_Init (FALSE); /* * Add the directories from the DEFSYSPATH (more than one may be given @@ -2532,6 +2571,18 @@ Parse_Init () } } +void +Parse_End() +{ + Lst_Destroy(targCmds, (void (*) __P((ClientData))) free); + if (targets) + Lst_Destroy(targets, NOFREE); + Lst_Destroy(sysIncPath, Dir_Destroy); + Lst_Destroy(parseIncPath, Dir_Destroy); + Lst_Destroy(includes, NOFREE); /* Should be empty now */ +} + + /*- *----------------------------------------------------------------------- * Parse_MainName -- |