summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2007-11-25 08:27:00 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2007-11-25 08:27:00 +0000
commit7bf61c63bf10e4618037196968a64cba393bb44e (patch)
tree819d98c5a7b0b43d91001b4baaa1b6e92a50b02d
parent62e4595bdf33e5fe727a6f004a6ba32a4e15288d (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.h7
-rw-r--r--usr.sbin/config/files.c54
-rw-r--r--usr.sbin/config/gram.y9
-rw-r--r--usr.sbin/config/mkmakefile.c58
-rw-r--r--usr.sbin/config/scan.l4
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]*
%%