Module Name: src
Committed By: dholland
Date: Sun Mar 11 08:21:54 UTC 2012
Modified Files:
src/usr.bin/config: defs.h files.c gram.y main.c mkmakefile.c sem.c
sem.h util.c
Log Message:
Create a struct condexpr type to hold condition expressions, instead
of abusing struct nvlist to make trees.
(These are the a|b and a&b constructs.)
To generate a diff of this commit:
cvs rdiff -u -r1.38 -r1.39 src/usr.bin/config/defs.h
cvs rdiff -u -r1.10 -r1.11 src/usr.bin/config/files.c \
src/usr.bin/config/util.c
cvs rdiff -u -r1.33 -r1.34 src/usr.bin/config/gram.y
cvs rdiff -u -r1.44 -r1.45 src/usr.bin/config/main.c
cvs rdiff -u -r1.13 -r1.14 src/usr.bin/config/mkmakefile.c
cvs rdiff -u -r1.39 -r1.40 src/usr.bin/config/sem.c
cvs rdiff -u -r1.8 -r1.9 src/usr.bin/config/sem.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/config/defs.h
diff -u src/usr.bin/config/defs.h:1.38 src/usr.bin/config/defs.h:1.39
--- src/usr.bin/config/defs.h:1.38 Sun Mar 11 07:32:41 2012
+++ src/usr.bin/config/defs.h Sun Mar 11 08:21:53 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: defs.h,v 1.38 2012/03/11 07:32:41 dholland Exp $ */
+/* $NetBSD: defs.h,v 1.39 2012/03/11 08:21:53 dholland Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -317,7 +317,7 @@ struct files {
TAILQ_ENTRY(files) fi_next;
const char *fi_tail; /* name, i.e., strrchr(fi_path, '/') + 1 */
const char *fi_base; /* tail minus ".c" (or whatever) */
- struct nvlist *fi_optx; /* options expression */
+ struct condexpr *fi_optx; /* options expression */
struct nvlist *fi_optf; /* flattened version of above, if needed */
const char *fi_mkrule; /* special make rule, if any */
};
@@ -341,7 +341,7 @@ struct files {
struct objects {
struct filetype oi_fit;
TAILQ_ENTRY(objects) oi_next;
- struct nvlist *oi_optx;/* options expression */
+ struct condexpr *oi_optx; /* condition expression */
struct nvlist *oi_optf;/* flattened version of above, if needed */
};
@@ -356,10 +356,31 @@ struct objects {
#define OI_SEL 0x01 /* selected */
#define OI_NEEDSFLAG 0x02 /* needs-flag */
-#define FX_ATOM 0 /* atom (in nv_name) */
-#define FX_NOT 1 /* NOT expr (subexpression in nv_next) */
-#define FX_AND 2 /* AND expr (lhs in nv_ptr, rhs in nv_next) */
-#define FX_OR 3 /* OR expr (lhs in nv_ptr, rhs in nv_next) */
+/*
+ * Condition expressions.
+ */
+
+enum condexpr_types {
+ CX_ATOM,
+ CX_NOT,
+ CX_AND,
+ CX_OR,
+};
+struct condexpr {
+ enum condexpr_types cx_type;
+ union {
+ const char *atom;
+ struct condexpr *not;
+ struct {
+ struct condexpr *left;
+ struct condexpr *right;
+ } and, or;
+ } cx_u;
+};
+#define cx_atom cx_u.atom
+#define cx_not cx_u.not
+#define cx_and cx_u.and
+#define cx_or cx_u.or
/*
* File/object prefixes. These are arranged in a stack, and affect
@@ -380,7 +401,7 @@ struct devm {
const char *dm_name; /* [bc]devsw name */
devmajor_t dm_cmajor; /* character major */
devmajor_t dm_bmajor; /* block major */
- struct nvlist *dm_opts; /* options */
+ struct condexpr *dm_opts; /* options */
struct nvlist *dm_devnodes; /* information on /dev nodes */
};
@@ -477,10 +498,9 @@ void checkfiles(void);
int fixfiles(void); /* finalize */
int fixobjects(void);
int fixdevsw(void);
-void addfile(const char *, struct nvlist *, int, const char *);
-void addobject(const char *, struct nvlist *, int);
-int expr_eval(struct nvlist *, int (*)(const char *, void *), void *);
-void expr_free(struct nvlist *);
+void addfile(const char *, struct condexpr *, int, const char *);
+void addobject(const char *, struct condexpr *, int);
+int expr_eval(struct condexpr *, int (*)(const char *, void *), void *);
/* hash.c */
struct hashtab *ht_new(void);
@@ -505,7 +525,7 @@ void addoption(const char *, const char
void addfsoption(const char *);
void addmkoption(const char *, const char *);
void appendmkoption(const char *, const char *);
-void appendcondmkoption(struct nvlist *, const char *, const char *);
+void appendcondmkoption(struct condexpr *, const char *, const char *);
void deffilesystem(struct nvlist *, struct nvlist *);
void defoption(const char *, struct nvlist *, struct nvlist *);
void defflag(const char *, struct nvlist *, struct nvlist *, int);
@@ -584,6 +604,8 @@ struct attrlist *attrlist_create(void);
struct attrlist *attrlist_cons(struct attrlist *, struct attr *);
void attrlist_destroy(struct attrlist *);
void attrlist_destroyall(struct attrlist *);
+struct condexpr *condexpr_create(enum condexpr_types);
+void condexpr_destroy(struct condexpr *);
/* liby */
void yyerror(const char *);
Index: src/usr.bin/config/files.c
diff -u src/usr.bin/config/files.c:1.10 src/usr.bin/config/files.c:1.11
--- src/usr.bin/config/files.c:1.10 Fri Mar 13 18:24:41 2009
+++ src/usr.bin/config/files.c Sun Mar 11 08:21:53 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: files.c,v 1.10 2009/03/13 18:24:41 cube Exp $ */
+/* $NetBSD: files.c,v 1.11 2012/03/11 08:21:53 dholland Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -82,7 +82,7 @@ initfiles(void)
}
void
-addfile(const char *path, struct nvlist *optx, int flags, const char *rule)
+addfile(const char *path, struct condexpr *optx, int flags, const char *rule)
{
struct files *fi;
const char *dotp, *tail;
@@ -160,11 +160,11 @@ addfile(const char *path, struct nvlist
TAILQ_INSERT_TAIL(&allfiles, fi, fi_next);
return;
bad:
- expr_free(optx);
+ condexpr_destroy(optx);
}
void
-addobject(const char *path, struct nvlist *optx, int flags)
+addobject(const char *path, struct condexpr *optx, int flags)
{
struct objects *oi;
@@ -494,64 +494,33 @@ fixsel(const char *name, void *context)
* our mixing of C's bitwise & boolean here may give surprises).
*/
int
-expr_eval(struct nvlist *expr, int (*fn)(const char *, void *), void *context)
+expr_eval(struct condexpr *expr, int (*fn)(const char *, void *), void *ctx)
{
int lhs, rhs;
- switch (expr->nv_num) {
+ switch (expr->cx_type) {
- case FX_ATOM:
- return ((*fn)(expr->nv_name, context));
+ case CX_ATOM:
+ return ((*fn)(expr->cx_atom, ctx));
- case FX_NOT:
- return (!expr_eval(expr->nv_next, fn, context));
+ case CX_NOT:
+ return (!expr_eval(expr->cx_not, fn, ctx));
- case FX_AND:
- lhs = expr_eval(expr->nv_ptr, fn, context);
- rhs = expr_eval(expr->nv_next, fn, context);
+ case CX_AND:
+ lhs = expr_eval(expr->cx_and.left, fn, ctx);
+ rhs = expr_eval(expr->cx_and.right, fn, ctx);
return (lhs & rhs);
- case FX_OR:
- lhs = expr_eval(expr->nv_ptr, fn, context);
- rhs = expr_eval(expr->nv_next, fn, context);
+ case CX_OR:
+ lhs = expr_eval(expr->cx_or.left, fn, ctx);
+ rhs = expr_eval(expr->cx_or.right, fn, ctx);
return (lhs | rhs);
}
- panic("expr_eval %lld", expr->nv_num);
+ panic("invalid condexpr type %d", (int)expr->cx_type);
/* NOTREACHED */
return (0);
}
-/*
- * Free an expression tree.
- */
-void
-expr_free(struct nvlist *expr)
-{
- struct nvlist *rhs;
-
- /* This loop traverses down the RHS of each subexpression. */
- for (; expr != NULL; expr = rhs) {
- switch (expr->nv_num) {
-
- /* Atoms and !-exprs have no left hand side. */
- case FX_ATOM:
- case FX_NOT:
- break;
-
- /* For AND and OR nodes, free the LHS. */
- case FX_AND:
- case FX_OR:
- expr_free(expr->nv_ptr);
- break;
-
- default:
- panic("expr_free %lld", expr->nv_num);
- }
- rhs = expr->nv_next;
- nvfree(expr);
- }
-}
-
#ifdef DEBUG
/*
* Print expression tree.
Index: src/usr.bin/config/util.c
diff -u src/usr.bin/config/util.c:1.10 src/usr.bin/config/util.c:1.11
--- src/usr.bin/config/util.c:1.10 Sun Mar 11 07:32:41 2012
+++ src/usr.bin/config/util.c Sun Mar 11 08:21:53 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: util.c,v 1.10 2012/03/11 07:32:41 dholland Exp $ */
+/* $NetBSD: util.c,v 1.11 2012/03/11 08:21:53 dholland Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -233,6 +233,75 @@ attrlist_destroyall(struct attrlist *al)
}
}
+/*
+ * Create an expression node.
+ */
+struct condexpr *
+condexpr_create(enum condexpr_types type)
+{
+ struct condexpr *cx;
+
+ cx = emalloc(sizeof(*cx));
+ cx->cx_type = type;
+ switch (type) {
+
+ case CX_ATOM:
+ cx->cx_atom = NULL;
+ break;
+
+ case CX_NOT:
+ cx->cx_not = NULL;
+ break;
+
+ case CX_AND:
+ cx->cx_and.left = NULL;
+ cx->cx_and.right = NULL;
+ break;
+
+ case CX_OR:
+ cx->cx_or.left = NULL;
+ cx->cx_or.right = NULL;
+ break;
+
+ default:
+ panic("condexpr_create: invalid expr type %d", (int)type);
+ }
+ return cx;
+}
+
+/*
+ * Free an expression tree.
+ */
+void
+condexpr_destroy(struct condexpr *expr)
+{
+ switch (expr->cx_type) {
+
+ case CX_ATOM:
+ /* nothing */
+ break;
+
+ case CX_NOT:
+ condexpr_destroy(expr->cx_not);
+ break;
+
+ case CX_AND:
+ condexpr_destroy(expr->cx_and.left);
+ condexpr_destroy(expr->cx_and.right);
+ break;
+
+ case CX_OR:
+ condexpr_destroy(expr->cx_or.left);
+ condexpr_destroy(expr->cx_or.right);
+ break;
+
+ default:
+ panic("condexpr_destroy: invalid expr type %d",
+ (int)expr->cx_type);
+ }
+ free(expr);
+}
+
void
cfgwarn(const char *fmt, ...)
{
Index: src/usr.bin/config/gram.y
diff -u src/usr.bin/config/gram.y:1.33 src/usr.bin/config/gram.y:1.34
--- src/usr.bin/config/gram.y:1.33 Sun Mar 11 07:46:47 2012
+++ src/usr.bin/config/gram.y Sun Mar 11 08:21:53 2012
@@ -1,5 +1,5 @@
%{
-/* $NetBSD: gram.y,v 1.33 2012/03/11 07:46:47 dholland Exp $ */
+/* $NetBSD: gram.y,v 1.34 2012/03/11 08:21:53 dholland Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -71,6 +71,7 @@ static void wrap_cleanup(void);
*/
#define WRAP_CODE_nvlist 1
#define WRAP_CODE_attrlist 2
+#define WRAP_CODE_condexpr 3
/*
* The allocation wrappers themselves
@@ -79,6 +80,10 @@ static void wrap_cleanup(void);
DECL_ALLOCWRAP(nvlist);
DECL_ALLOCWRAP(attrlist);
+DECL_ALLOCWRAP(condexpr);
+
+/* allow shorter names */
+#define wrap_mk_cx(p) wrap_mk_condexpr(p)
/*
* Macros for allocating new objects
@@ -99,21 +104,24 @@ DECL_ALLOCWRAP(attrlist);
#define new_nsx(n,s,x) new0(n, s, NULL, 0, x)
#define new_i(i) new0(NULL, NULL, NULL, i, NULL)
-#define fx_atom(s) new0(s, NULL, NULL, FX_ATOM, NULL)
-#define fx_not(e) new0(NULL, NULL, NULL, FX_NOT, e)
-#define fx_and(e1, e2) new0(NULL, NULL, e1, FX_AND, e2)
-#define fx_or(e1, e2) new0(NULL, NULL, e1, FX_OR, e2)
-
-/* new style, type-polymorphic */
+/* new style, type-polymorphic; ordinary and for types with multiple flavors */
#define MK0(t) wrap_mk_##t(mk_##t())
#define MK1(t, a0) wrap_mk_##t(mk_##t(a0))
#define MK2(t, a0, a1) wrap_mk_##t(mk_##t(a0, a1))
+#define MKF0(t, f) wrap_mk_##t(mk_##t##_##f())
+#define MKF1(t, f, a0) wrap_mk_##t(mk_##t##_##f(a0))
+#define MKF2(t, f, a0, a1) wrap_mk_##t(mk_##t##_##f(a0, a1))
+
/*
* Data constructors
*/
static struct attrlist *mk_attrlist(struct attrlist *, struct attr *);
+static struct condexpr *mk_cx_atom(const char *);
+static struct condexpr *mk_cx_not(struct condexpr *);
+static struct condexpr *mk_cx_and(struct condexpr *, struct condexpr *);
+static struct condexpr *mk_cx_or(struct condexpr *, struct condexpr *);
/*
* Other private functions
@@ -135,6 +143,7 @@ static struct nvlist *mk_ns(const char *
struct deva *deva;
struct nvlist *list;
struct attrlist *attrlist;
+ struct condexpr *condexpr;
const char *str;
struct numconst num;
int64_t val;
@@ -162,8 +171,9 @@ static struct nvlist *mk_ns(const char *
%token <str> PATHNAME QSTRING WORD EMPTYSTRING
%token ENDDEFS
-%type <list> fopts condexpr condatom
-%type <list> cond_or_expr cond_and_expr cond_prefix_expr cond_base_expr
+%type <condexpr> fopts condexpr condatom
+%type <condexpr> cond_or_expr cond_and_expr cond_prefix_expr
+%type <condexpr> cond_base_expr
%type <str> fs_spec
%type <val> fflgs fflag oflgs oflag
%type <str> rule
@@ -798,29 +808,29 @@ condexpr:
cond_or_expr:
cond_and_expr
- | cond_or_expr '|' cond_and_expr { $$ = fx_or($1, $3); }
+ | cond_or_expr '|' cond_and_expr { $$ = MKF2(cx, or, $1, $3); }
;
cond_and_expr:
cond_prefix_expr
- | cond_and_expr '&' cond_prefix_expr { $$ = fx_and($1, $3); }
+ | cond_and_expr '&' cond_prefix_expr { $$ = MKF2(cx, and, $1, $3); }
;
cond_prefix_expr:
cond_base_expr
/* XXX notyet - need to strengthen downstream first */
-/* | '!' cond_prefix_expr { $$ = fx_not($2); } */
+/* | '!' cond_prefix_expr { $$ = MKF1(cx, not, $2); } */
;
cond_base_expr:
condatom { $$ = $1; }
- | '!' condatom { $$ = fx_not($2); }
+ | '!' condatom { $$ = MKF1(cx, not, $2); }
| '(' condexpr ')' { $$ = $2; }
;
/* basic element of config element expression: a config element */
condatom:
- WORD { $$ = fx_atom($1); }
+ WORD { $$ = MKF1(cx, atom, $1); }
;
/************************************************************/
@@ -989,6 +999,7 @@ wrap_cleanup(void)
DEF_ALLOCWRAP(nvlist);
DEF_ALLOCWRAP(attrlist);
+DEF_ALLOCWRAP(condexpr);
/************************************************************/
@@ -1002,6 +1013,48 @@ mk_attrlist(struct attrlist *next, struc
return attrlist_cons(next, a);
}
+static struct condexpr *
+mk_cx_atom(const char *s)
+{
+ struct condexpr *cx;
+
+ cx = condexpr_create(CX_ATOM);
+ cx->cx_atom = s;
+ return cx;
+}
+
+static struct condexpr *
+mk_cx_not(struct condexpr *sub)
+{
+ struct condexpr *cx;
+
+ cx = condexpr_create(CX_NOT);
+ cx->cx_not = sub;
+ return cx;
+}
+
+static struct condexpr *
+mk_cx_and(struct condexpr *left, struct condexpr *right)
+{
+ struct condexpr *cx;
+
+ cx = condexpr_create(CX_AND);
+ cx->cx_and.left = left;
+ cx->cx_and.right = right;
+ return cx;
+}
+
+static struct condexpr *
+mk_cx_or(struct condexpr *left, struct condexpr *right)
+{
+ struct condexpr *cx;
+
+ cx = condexpr_create(CX_OR);
+ cx->cx_or.left = left;
+ cx->cx_or.right = right;
+ return cx;
+}
+
/************************************************************/
static void
Index: src/usr.bin/config/main.c
diff -u src/usr.bin/config/main.c:1.44 src/usr.bin/config/main.c:1.45
--- src/usr.bin/config/main.c:1.44 Sun Mar 11 07:32:41 2012
+++ src/usr.bin/config/main.c Sun Mar 11 08:21:53 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.44 2012/03/11 07:32:41 dholland Exp $ */
+/* $NetBSD: main.c,v 1.45 2012/03/11 08:21:53 dholland Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -951,11 +951,11 @@ appendmkoption(const char *name, const c
* Add a conditional appending "make" option.
*/
void
-appendcondmkoption(struct nvlist *cnd, const char *name, const char *value)
+appendcondmkoption(struct condexpr *cond, const char *name, const char *value)
{
struct nvlist *nv;
- nv = newnv(name, value, cnd, 0, NULL);
+ nv = newnv(name, value, cond, 0, NULL);
*nextcndmkopt = nv;
nextcndmkopt = &nv->nv_next;
}
Index: src/usr.bin/config/mkmakefile.c
diff -u src/usr.bin/config/mkmakefile.c:1.13 src/usr.bin/config/mkmakefile.c:1.14
--- src/usr.bin/config/mkmakefile.c:1.13 Sat Apr 11 12:41:10 2009
+++ src/usr.bin/config/mkmakefile.c Sun Mar 11 08:21:53 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: mkmakefile.c,v 1.13 2009/04/11 12:41:10 lukem Exp $ */
+/* $NetBSD: mkmakefile.c,v 1.14 2012/03/11 08:21:53 dholland Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -551,15 +551,17 @@ static void
emitappmkoptions(FILE *fp)
{
struct nvlist *nv;
+ struct condexpr *cond;
for (nv = appmkoptions; nv != NULL; nv = nv->nv_next)
fprintf(fp, "%s+=%s\n", nv->nv_name, nv->nv_str);
- for (nv = condmkoptions; nv != NULL; nv = nv->nv_next)
- {
- if (expr_eval(nv->nv_ptr, selectopt, NULL))
+ for (nv = condmkoptions; nv != NULL; nv = nv->nv_next) {
+ cond = nv->nv_ptr;
+ if (expr_eval(cond, selectopt, NULL))
fprintf(fp, "%s+=%s\n", nv->nv_name, nv->nv_str);
- expr_free(nv->nv_ptr);
+ condexpr_destroy(cond);
+ nv->nv_ptr = NULL;
}
}
Index: src/usr.bin/config/sem.c
diff -u src/usr.bin/config/sem.c:1.39 src/usr.bin/config/sem.c:1.40
--- src/usr.bin/config/sem.c:1.39 Sun Mar 11 07:32:41 2012
+++ src/usr.bin/config/sem.c Sun Mar 11 08:21:53 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: sem.c,v 1.39 2012/03/11 07:32:41 dholland Exp $ */
+/* $NetBSD: sem.c,v 1.40 2012/03/11 08:21:53 dholland Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -1551,26 +1551,26 @@ delpseudo(const char *name)
void
adddevm(const char *name, devmajor_t cmajor, devmajor_t bmajor,
- struct nvlist *nv_opts, struct nvlist *nv_nodes)
+ struct condexpr *cond, struct nvlist *nv_nodes)
{
struct devm *dm;
if (cmajor != NODEVMAJOR && (cmajor < 0 || cmajor >= 4096)) {
cfgerror("character major %d is invalid", cmajor);
- nvfreel(nv_opts);
+ condexpr_destroy(cond);
nvfreel(nv_nodes);
return;
}
if (bmajor != NODEVMAJOR && (bmajor < 0 || bmajor >= 4096)) {
cfgerror("block major %d is invalid", bmajor);
- nvfreel(nv_opts);
+ condexpr_destroy(cond);
nvfreel(nv_nodes);
return;
}
if (cmajor == NODEVMAJOR && bmajor == NODEVMAJOR) {
cfgerror("both character/block majors are not specified");
- nvfreel(nv_opts);
+ condexpr_destroy(cond);
nvfreel(nv_nodes);
return;
}
@@ -1581,7 +1581,7 @@ adddevm(const char *name, devmajor_t cma
dm->dm_name = name;
dm->dm_cmajor = cmajor;
dm->dm_bmajor = bmajor;
- dm->dm_opts = nv_opts;
+ dm->dm_opts = cond;
dm->dm_devnodes = nv_nodes;
TAILQ_INSERT_TAIL(&alldevms, dm, dm_next);
Index: src/usr.bin/config/sem.h
diff -u src/usr.bin/config/sem.h:1.8 src/usr.bin/config/sem.h:1.9
--- src/usr.bin/config/sem.h:1.8 Sun Mar 11 07:32:41 2012
+++ src/usr.bin/config/sem.h Sun Mar 11 08:21:53 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: sem.h,v 1.8 2012/03/11 07:32:41 dholland Exp $ */
+/* $NetBSD: sem.h,v 1.9 2012/03/11 08:21:53 dholland Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -68,7 +68,7 @@ void addpseudo(const char *, int);
void delpseudo(const char *);
void addpseudoroot(const char *);
void adddevm(const char *, int, int,
- struct nvlist *, struct nvlist *);
+ struct condexpr *, struct nvlist *);
int fixdevis(void);
const char *ref(const char *);
const char *starref(const char *);