diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-11-25 08:27:00 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-11-25 08:27:00 +0000 |
commit | 7bf61c63bf10e4618037196968a64cba393bb44e (patch) | |
tree | 819d98c5a7b0b43d91001b4baaa1b6e92a50b02d | |
parent | 62e4595bdf33e5fe727a6f004a6ba32a4e15288d (diff) |
Extend the "file" directive to accept multiple pathnames seperated by '|'.
If more than one path is provided, access() them to choose which one should
be used, while parsing for ${name} expansions... currently limited to
MACHINE_ARCH
ok miod
-rw-r--r-- | usr.sbin/config/config.h | 7 | ||||
-rw-r--r-- | usr.sbin/config/files.c | 54 | ||||
-rw-r--r-- | usr.sbin/config/gram.y | 9 | ||||
-rw-r--r-- | usr.sbin/config/mkmakefile.c | 58 | ||||
-rw-r--r-- | usr.sbin/config/scan.l | 4 |
5 files changed, 103 insertions, 29 deletions
diff --git a/usr.sbin/config/config.h b/usr.sbin/config/config.h index d3b77bef886..373df720c2f 100644 --- a/usr.sbin/config/config.h +++ b/usr.sbin/config/config.h @@ -1,4 +1,4 @@ -/* $OpenBSD: config.h,v 1.22 2006/04/27 18:09:52 espie Exp $ */ +/* $OpenBSD: config.h,v 1.23 2007/11/25 08:26:59 deraadt Exp $ */ /* $NetBSD: config.h,v 1.30 1997/02/02 21:12:30 thorpej Exp $ */ /* @@ -225,8 +225,7 @@ struct files { u_short fi_srcline; /* and the line number */ u_char fi_flags; /* as below */ char fi_lastc; /* last char from path */ - const char *fi_path; /* full file path */ - const char *fi_tail; /* name, i.e., strrchr(fi_path, '/') + 1 */ + struct nvlist *fi_nvpath; /* list of paths */ const char *fi_base; /* tail minus ".c" (or whatever) */ struct nvlist *fi_optx;/* options expression */ struct nvlist *fi_optf;/* flattened version of above, if needed */ @@ -320,7 +319,7 @@ void initfiles(void); void checkfiles(void); int fixfiles(void); /* finalize */ int fixobjects(void); -void addfile(const char *, struct nvlist *, int, const char *, const char *); +void addfile(struct nvlist *, struct nvlist *, int, const char *, const char *); void addobject(const char *, struct nvlist *, int); /* hash.c */ diff --git a/usr.sbin/config/files.c b/usr.sbin/config/files.c index 9f5c53b25c7..02b8da6037d 100644 --- a/usr.sbin/config/files.c +++ b/usr.sbin/config/files.c @@ -1,4 +1,4 @@ -/* $OpenBSD: files.c,v 1.14 2006/04/27 18:09:52 espie Exp $ */ +/* $OpenBSD: files.c,v 1.15 2007/11/25 08:26:59 deraadt Exp $ */ /* $NetBSD: files.c,v 1.6 1996/03/17 13:18:17 cgd Exp $ */ /* @@ -84,11 +84,12 @@ initfiles(void) } void -addfile(const char *path, struct nvlist *optx, int flags, const char *rule, +addfile(struct nvlist *nvpath, struct nvlist *optx, int flags, const char *rule, const char *lintrule) { struct files *fi; - const char *dotp, *tail; + const char *dotp, *dotp1, *tail, *path, *tail1 = NULL; + struct nvlist *nv; size_t baselen; int needc, needf; char base[200]; @@ -105,17 +106,33 @@ addfile(const char *path, struct nvlist *optx, int flags, const char *rule, goto bad; } - /* find last part of pathname, and same without trailing suffix */ - tail = strrchr(path, '/'); - if (tail == NULL) - tail = path; - else - tail++; - dotp = strrchr(tail, '.'); - if (dotp == NULL || dotp[1] == 0 || - (baselen = dotp - tail) >= sizeof(base)) { - error("invalid pathname `%s'", path); - goto bad; + for (nv = nvpath; nv; nv = nv->nv_next) { + path = nv->nv_name; + + /* find last part of pathname, and same without trailing suffix */ + tail = strrchr(path, '/'); + if (tail == NULL) + tail = path; + else + tail++; + dotp = strrchr(tail, '.'); + if (dotp == NULL || dotp[1] == 0 || + (baselen = dotp - tail) >= sizeof(base)) { + error("invalid pathname `%s'", path); + goto bad; + } + + /* + * Ensure all tailnames are identical, because .o + * filenames must be identical too. + */ + if (tail1 && + (dotp - tail != dotp1 - tail1 || + strncmp(tail1, tail, dotp - tail))) + error("different production from %s %s", + nvpath->nv_name, tail); + tail1 = tail; + dotp1 = dotp; } /* @@ -137,8 +154,7 @@ addfile(const char *path, struct nvlist *optx, int flags, const char *rule, fi->fi_srcfile = yyfile; fi->fi_srcline = currentline(); fi->fi_flags = flags; - fi->fi_path = path; - fi->fi_tail = tail; + fi->fi_nvpath = nvpath; fi->fi_base = intern(base); fi->fi_optx = optx; fi->fi_optf = NULL; @@ -258,7 +274,7 @@ fixfiles(void) * If the new file comes from a different source, * allow the new one to override the old one. */ - if (fi->fi_path != ofi->fi_path) { + if (fi->fi_nvpath != ofi->fi_nvpath) { if (ht_replace(basetab, fi->fi_base, fi) != 1) panic("fixfiles ht_replace(%s)", fi->fi_base); @@ -267,10 +283,10 @@ fixfiles(void) } else { xerror(fi->fi_srcfile, fi->fi_srcline, "object file collision on %s.o, from %s", - fi->fi_base, fi->fi_path); + fi->fi_base, fi->fi_nvpath->nv_name); xerror(ofi->fi_srcfile, ofi->fi_srcline, "here is the previous file: %s", - ofi->fi_path); + ofi->fi_nvpath->nv_name); err = 1; } } diff --git a/usr.sbin/config/gram.y b/usr.sbin/config/gram.y index 4118437bcbe..dfc219c393a 100644 --- a/usr.sbin/config/gram.y +++ b/usr.sbin/config/gram.y @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: gram.y,v 1.19 2006/04/27 18:09:52 espie Exp $ */ +/* $OpenBSD: gram.y,v 1.20 2007/11/25 08:26:59 deraadt Exp $ */ /* $NetBSD: gram.y,v 1.14 1997/02/02 21:12:32 thorpej Exp $ */ /* @@ -107,6 +107,7 @@ static void check_maxpart(void); %left '|' %left '&' +%type <list> pathnames %type <list> fopts fexpr fatom %type <val> fflgs fflag oflgs oflag %type <str> rule @@ -166,11 +167,15 @@ machine_spec: dev_eof: ENDFILE { enddefs(); checkfiles(); }; +pathnames: + PATHNAME { $$ = new_nsi($1, NULL, 0); } | + pathnames '|' PATHNAME { ($$ = $1)->nv_next = new_nsi($3, NULL, 0); }; + /* * Various nonterminals shared between the grammars. */ file: - XFILE PATHNAME fopts fflgs rule lintrule { addfile($2, $3, $4, $5, $6); }; + XFILE pathnames fopts fflgs rule lintrule { addfile($2, $3, $4, $5, $6); }; object: XOBJECT PATHNAME fopts oflgs { addobject($2, $3, $4); }; diff --git a/usr.sbin/config/mkmakefile.c b/usr.sbin/config/mkmakefile.c index b0079afaf8c..989838eeaf8 100644 --- a/usr.sbin/config/mkmakefile.c +++ b/usr.sbin/config/mkmakefile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mkmakefile.c,v 1.21 2006/12/06 05:05:16 ray Exp $ */ +/* $OpenBSD: mkmakefile.c,v 1.22 2007/11/25 08:26:59 deraadt Exp $ */ /* $NetBSD: mkmakefile.c,v 1.34 1997/02/02 21:12:36 thorpej Exp $ */ /* @@ -152,7 +152,61 @@ srcpath(struct files *fi) { #if 1 /* Always have source, don't support object dirs for kernel builds. */ - return (fi->fi_path); + struct nvlist *nv, *nv1; + char *source; + + /* Search path list for files we will want to use */ + if (fi->fi_nvpath->nv_next == NULL) { + nv = fi->fi_nvpath; + goto onlyone; + } + + for (nv = fi->fi_nvpath; nv; nv = nv->nv_next) { + char *s, *e; + + s = strchr(nv->nv_name, '$'); + if (s) { + char *expand; + + /* Search for a ${name} to expand */ + if (s[1] != '{') + error("{"); + e = strchr(s + 2, '}'); + if (!e) + error("}"); + if (strncmp(s + 2, "MACHINE_ARCH", + strlen("MACHINE_ARCH")) != 0) + error("variable %*.*s not supported", + e - s - 2, e - s - 2, s + 2); + asprintf(&expand, "%*.*s%s%s", + s - nv->nv_name, s - nv->nv_name, nv->nv_name, + machinearch ? machinearch : machine, e + 1); + source = sourcepath(expand); + free(expand); + } else + source = sourcepath(nv->nv_name); + if (access(source, R_OK) == 0) + break; + free(source); + } + if (nv == NULL) + nv = fi->fi_nvpath; + + /* + * Now that we know which path is right, delete all the + * other filenames to skip the access() checks next time + */ + while ((nv1 = fi->fi_nvpath)) { + nv1 = nv1->nv_next; + if (fi->fi_nvpath != nv) + nvfree(fi->fi_nvpath); + fi->fi_nvpath = nv1; + } + fi->fi_nvpath = nv; + nv->nv_next = NULL; +onlyone: + return (nv->nv_name); + #else static char buf[MAXPATHLEN]; diff --git a/usr.sbin/config/scan.l b/usr.sbin/config/scan.l index 00e58bd186b..343d7772264 100644 --- a/usr.sbin/config/scan.l +++ b/usr.sbin/config/scan.l @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: scan.l,v 1.19 2006/04/27 18:09:52 espie Exp $ */ +/* $OpenBSD: scan.l,v 1.20 2007/11/25 08:26:59 deraadt Exp $ */ /* $NetBSD: scan.l,v 1.13 1997/02/02 21:12:37 thorpej Exp $ */ /* @@ -72,7 +72,7 @@ static int endinclude(void); %} -PATH [A-Za-z_0-9]*[./][-A-Za-z_0-9./]* +PATH [A-Za-z_0-9]*[./][-A-Za-z_0-9./\$\{\}]* WORD [A-Za-z_][-A-Za-z_0-9]* %% |