diff options
Diffstat (limited to 'contrib/bmake/parse.c')
-rw-r--r-- | contrib/bmake/parse.c | 130 |
1 files changed, 94 insertions, 36 deletions
diff --git a/contrib/bmake/parse.c b/contrib/bmake/parse.c index c2ecdbe875bf..3193543f56bf 100644 --- a/contrib/bmake/parse.c +++ b/contrib/bmake/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.681 2022/07/24 20:25:23 rillig Exp $ */ +/* $NetBSD: parse.c,v 1.692 2023/01/24 00:24:02 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -121,7 +121,7 @@ #include "pathnames.h" /* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: parse.c,v 1.681 2022/07/24 20:25:23 rillig Exp $"); +MAKE_RCSID("$NetBSD: parse.c,v 1.692 2023/01/24 00:24:02 sjg Exp $"); /* * A file being read. @@ -135,7 +135,8 @@ typedef struct IncludedFile { unsigned forBodyReadLines; /* the number of physical lines that have * been read from the file above the body of * the .for loop */ - unsigned int cond_depth; /* 'if' nesting when file opened */ + unsigned int condMinDepth; /* depth of nested 'if' directives, at the + * beginning of the file */ bool depending; /* state of doing_depend on EOF */ Buffer buf; /* the file's content or the body of the .for @@ -164,6 +165,7 @@ typedef enum ParseSpecial { SP_NOMETA, /* .NOMETA */ SP_NOMETA_CMP, /* .NOMETA_CMP */ SP_NOPATH, /* .NOPATH */ + SP_NOREADONLY, /* .NOREADONLY */ SP_NOT, /* Not special */ SP_NOTPARALLEL, /* .NOTPARALLEL or .NO_PARALLEL */ SP_NULL, /* .NULL; not mentioned in the manual page */ @@ -176,11 +178,13 @@ typedef enum ParseSpecial { SP_POSIX, /* .POSIX; not mentioned in the manual page */ #endif SP_PRECIOUS, /* .PRECIOUS */ + SP_READONLY, /* .READONLY */ SP_SHELL, /* .SHELL */ SP_SILENT, /* .SILENT */ SP_SINGLESHELL, /* .SINGLESHELL; not mentioned in the manual page */ SP_STALE, /* .STALE */ SP_SUFFIXES, /* .SUFFIXES */ + SP_SYSPATH, /* .SYSPATH */ SP_WAIT /* .WAIT */ } ParseSpecial; @@ -284,6 +288,7 @@ static const struct { { ".NOMETA", SP_NOMETA, OP_NOMETA }, { ".NOMETA_CMP", SP_NOMETA_CMP, OP_NOMETA_CMP }, { ".NOPATH", SP_NOPATH, OP_NOPATH }, + { ".NOREADONLY", SP_NOREADONLY, OP_NONE }, { ".NOTMAIN", SP_ATTRIBUTE, OP_NOTMAIN }, { ".NOTPARALLEL", SP_NOTPARALLEL, OP_NONE }, { ".NO_PARALLEL", SP_NOTPARALLEL, OP_NONE }, @@ -298,12 +303,14 @@ static const struct { { ".POSIX", SP_POSIX, OP_NONE }, #endif { ".PRECIOUS", SP_PRECIOUS, OP_PRECIOUS }, + { ".READONLY", SP_READONLY, OP_NONE }, { ".RECURSIVE", SP_ATTRIBUTE, OP_MAKE }, { ".SHELL", SP_SHELL, OP_NONE }, { ".SILENT", SP_SILENT, OP_SILENT }, { ".SINGLESHELL", SP_SINGLESHELL, OP_NONE }, { ".STALE", SP_STALE, OP_NONE }, { ".SUFFIXES", SP_SUFFIXES, OP_NONE }, + { ".SYSPATH", SP_SYSPATH, OP_NONE }, { ".USE", SP_ATTRIBUTE, OP_USE }, { ".USEBEFORE", SP_ATTRIBUTE, OP_USEBEFORE }, { ".WAIT", SP_WAIT, OP_NONE }, @@ -314,6 +321,7 @@ enum PosixState posix_state = PS_NOT_YET; static IncludedFile * GetInclude(size_t i) { + assert(i < includes.len); return Vector_Get(&includes, i); } @@ -324,6 +332,12 @@ CurFile(void) return GetInclude(includes.len - 1); } +unsigned int +CurFile_CondMinDepth(void) +{ + return CurFile()->condMinDepth; +} + static Buffer LoadFile(const char *path, int fd) { @@ -376,11 +390,11 @@ PrintStackTrace(bool includingInnermost) const IncludedFile *entries; size_t i, n; - entries = GetInclude(0); n = includes.len; if (n == 0) return; + entries = GetInclude(0); if (!includingInnermost && entries[n - 1].forLoop == NULL) n--; /* already in the diagnostic */ @@ -661,7 +675,7 @@ TryApplyDependencyOperator(GNode *gn, GNodeType op) * Propagate copied bits to the initial node. They'll be * propagated back to the rest of the cohorts later. */ - gn->type |= op & ~OP_OPMASK; + gn->type |= op & (unsigned)~OP_OPMASK; cohort = Targ_NewInternalNode(gn->name); if (doing_depend) @@ -927,6 +941,11 @@ HandleDependencyTargetSpecial(const char *targetName, *inout_paths = Lst_New(); Lst_Append(*inout_paths, &dirSearchPath); break; + case SP_SYSPATH: + if (*inout_paths == NULL) + *inout_paths = Lst_New(); + Lst_Append(*inout_paths, sysIncPath); + break; case SP_MAIN: /* * Allow targets from the command line to override the @@ -1080,8 +1099,12 @@ SkipExtraTargets(char **pp, const char *lstart) warning = true; p++; } - if (warning) - Parse_Error(PARSE_WARNING, "Extra target ignored"); + if (warning) { + const char *start = *pp; + cpp_skip_whitespace(&start); + Parse_Error(PARSE_WARNING, "Extra target '%.*s' ignored", + (int)(p - start), start); + } *pp += p - *pp; } @@ -1129,15 +1152,17 @@ ParseDependencyOp(char **pp) } static void -ClearPaths(SearchPathList *paths) +ClearPaths(ParseSpecial special, SearchPathList *paths) { if (paths != NULL) { SearchPathListNode *ln; for (ln = paths->first; ln != NULL; ln = ln->next) SearchPath_Clear(ln->datum); } - - Dir_SetPATH(); + if (special == SP_SYSPATH) + Dir_SetSYSPATH(); + else + Dir_SetPATH(); } static char * @@ -1258,7 +1283,8 @@ HandleDependencySourcesEmpty(ParseSpecial special, SearchPathList *paths) opts.silent = true; break; case SP_PATH: - ClearPaths(paths); + case SP_SYSPATH: + ClearPaths(special, paths); break; #ifdef POSIX case SP_POSIX: @@ -1310,12 +1336,21 @@ ParseDependencySourceSpecial(ParseSpecial special, const char *word, case SP_LIBS: Suff_AddLib(word); break; + case SP_NOREADONLY: + Var_ReadOnly(word, false); + break; case SP_NULL: Suff_SetNull(word); break; case SP_OBJDIR: Main_SetObjdir(false, "%s", word); break; + case SP_READONLY: + Var_ReadOnly(word, true); + break; + case SP_SYSPATH: + AddToPaths(word, paths); + break; default: break; } @@ -1343,26 +1378,26 @@ ApplyDependencyTarget(char *name, char *nameEnd, ParseSpecial *inout_special, } static bool -ParseDependencyTargets(char **inout_cp, +ParseDependencyTargets(char **pp, const char *lstart, ParseSpecial *inout_special, GNodeType *inout_targetAttr, SearchPathList **inout_paths) { - char *cp = *inout_cp; + char *p = *pp; for (;;) { - char *tgt = cp; + char *tgt = p; - ParseDependencyTargetWord(&cp, lstart); + ParseDependencyTargetWord(&p, lstart); /* * If the word is followed by a left parenthesis, it's the * name of one or more files inside an archive. */ - if (!IsEscaped(lstart, cp) && *cp == '(') { - cp = tgt; - if (!Arch_ParseArchive(&cp, targets, SCOPE_CMDLINE)) { + if (!IsEscaped(lstart, p) && *p == '(') { + p = tgt; + if (!Arch_ParseArchive(&p, targets, SCOPE_CMDLINE)) { Parse_Error(PARSE_FATAL, "Error in archive specification: \"%s\"", tgt); @@ -1371,27 +1406,27 @@ ParseDependencyTargets(char **inout_cp, continue; } - if (*cp == '\0') { + if (*p == '\0') { InvalidLineType(lstart); return false; } - if (!ApplyDependencyTarget(tgt, cp, inout_special, + if (!ApplyDependencyTarget(tgt, p, inout_special, inout_targetAttr, inout_paths)) return false; if (*inout_special != SP_NOT && *inout_special != SP_PATH) - SkipExtraTargets(&cp, lstart); + SkipExtraTargets(&p, lstart); else - pp_skip_whitespace(&cp); + pp_skip_whitespace(&p); - if (*cp == '\0') + if (*p == '\0') break; - if ((*cp == '!' || *cp == ':') && !IsEscaped(lstart, cp)) + if ((*p == '!' || *p == ':') && !IsEscaped(lstart, p)) break; } - *inout_cp = cp; + *pp = p; return true; } @@ -1528,9 +1563,16 @@ ParseDependencySources(char *p, GNodeType targetAttr, } /* Now go for the sources. */ - if (special == SP_SUFFIXES || special == SP_PATH || - special == SP_INCLUDES || special == SP_LIBS || - special == SP_NULL || special == SP_OBJDIR) { + switch (special) { + case SP_INCLUDES: + case SP_LIBS: + case SP_NOREADONLY: + case SP_NULL: + case SP_OBJDIR: + case SP_PATH: + case SP_READONLY: + case SP_SUFFIXES: + case SP_SYSPATH: ParseDependencySourcesSpecial(p, special, *inout_paths); if (*inout_paths != NULL) { Lst_Free(*inout_paths); @@ -1538,10 +1580,14 @@ ParseDependencySources(char *p, GNodeType targetAttr, } if (special == SP_PATH) Dir_SetPATH(); - } else { + if (special == SP_SYSPATH) + Dir_SetSYSPATH(); + break; + default: assert(*inout_paths == NULL); if (!ParseDependencySourcesMundane(p, special, targetAttr)) return; + break; } MaybeUpdateMainTarget(); @@ -2155,7 +2201,7 @@ Parse_PushInput(const char *name, unsigned lineno, unsigned readLines, curFile->buf_ptr = curFile->buf.data; curFile->buf_end = curFile->buf.data + curFile->buf.len; - curFile->cond_depth = Cond_save_depth(); + curFile->condMinDepth = cond_depth; SetParseFile(name); } @@ -2288,11 +2334,7 @@ ParseEOF(void) return true; } - /* - * Ensure the makefile (or .for loop) didn't have mismatched - * conditionals. - */ - Cond_restore_depth(curFile->cond_depth); + Cond_EndFile(); FStr_Done(&curFile->name); Buf_Done(&curFile->buf); @@ -2677,6 +2719,20 @@ ParseLine_ShellCommand(const char *p) } } +static void +HandleBreak(void) +{ + IncludedFile *curFile = CurFile(); + + if (curFile->forLoop != NULL) { + /* pretend we reached EOF */ + For_Break(curFile->forLoop); + cond_depth = CurFile_CondMinDepth(); + ParseEOF(); + } else + Parse_Error(PARSE_FATAL, "break outside of for loop"); +} + /* * See if the line starts with one of the known directives, and if so, handle * the directive. @@ -2705,7 +2761,9 @@ ParseDirective(char *line) pp_skip_whitespace(&cp); arg = cp; - if (Substring_Equals(dir, "undef")) + if (Substring_Equals(dir, "break")) + HandleBreak(); + else if (Substring_Equals(dir, "undef")) Var_Undef(arg); else if (Substring_Equals(dir, "export")) Var_Export(VEM_PLAIN, arg); |