add BSDI-style expression support to optional file specifiers. Code mostly
taken from the parts of BSDI's 'config' which are freely-distributable (under the LBL/UC Regents license), and adjusted to fit into our version.
This commit is contained in:
parent
50b3b61ea3
commit
3ac7667c57
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: config.h,v 1.22 1996/03/17 11:50:09 cgd Exp $ */
|
||||
/* $NetBSD: config.h,v 1.23 1996/03/17 13:18:15 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -187,7 +187,16 @@ struct devi {
|
||||
|
||||
/*
|
||||
* Files. Each file is either standard (always included) or optional,
|
||||
* depending on whether it has names on which to *be* optional.
|
||||
* depending on whether it has names on which to *be* optional. The
|
||||
* options field (fi_optx) is actually an expression tree, with nodes
|
||||
* for OR, AND, and NOT, as well as atoms (words) representing some
|
||||
* particular option. The node type is stored in the nv_int field.
|
||||
* Subexpressions appear in the `next' field; for the binary operators
|
||||
* AND and OR, the left subexpression is first stored in the nv_ptr field.
|
||||
*
|
||||
* For any file marked as needs-count or needs-flag, fixfiles() will
|
||||
* build fi_optf, a `flat list' of the options with nv_int fields that
|
||||
* contain counts or `need' flags; this is used in mkheaders().
|
||||
*/
|
||||
struct files {
|
||||
struct files *fi_next; /* linked list */
|
||||
@ -198,9 +207,14 @@ struct files {
|
||||
const char *fi_path; /* full file path */
|
||||
const char *fi_tail; /* name, i.e., rindex(fi_path, '/') + 1 */
|
||||
const char *fi_base; /* tail minus ".c" (or whatever) */
|
||||
struct nvlist *fi_opt; /* optional on ... */
|
||||
struct nvlist *fi_optx;/* options expression */
|
||||
struct nvlist *fi_optf;/* flattened version of above, if needed */
|
||||
const char *fi_mkrule; /* special make rule, if any */
|
||||
};
|
||||
#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) */
|
||||
|
||||
/* flags */
|
||||
#define FI_SEL 0x01 /* selected */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: files.c,v 1.5 1996/03/17 06:29:22 cgd Exp $ */
|
||||
/* $NetBSD: files.c,v 1.6 1996/03/17 13:18:17 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -65,6 +65,14 @@ static struct hashtab *pathtab; /* full path names */
|
||||
static struct files **nextfile;
|
||||
static struct files **unchecked;
|
||||
|
||||
static int checkaux __P((const char *, void *));
|
||||
static int fixcount __P((const char *, void *));
|
||||
static int fixfsel __P((const char *, void *));
|
||||
static int fixsel __P((const char *, void *));
|
||||
static int expr_eval __P((struct nvlist *,
|
||||
int (*)(const char *, void *), void *));
|
||||
static void expr_free __P((struct nvlist *));
|
||||
|
||||
void
|
||||
initfiles()
|
||||
{
|
||||
@ -87,17 +95,17 @@ showprev(pref, fi)
|
||||
}
|
||||
|
||||
void
|
||||
addfile(path, opts, flags, rule)
|
||||
addfile(path, optx, flags, rule)
|
||||
const char *path;
|
||||
struct nvlist *opts;
|
||||
struct nvlist *optx;
|
||||
int flags;
|
||||
const char *rule;
|
||||
{
|
||||
struct files *fi;
|
||||
const char *base, *dotp, *tail;
|
||||
const char *dotp, *tail;
|
||||
size_t baselen;
|
||||
int needc, needf;
|
||||
char buf[200];
|
||||
char base[200];
|
||||
|
||||
/* check various errors */
|
||||
needc = flags & FI_NEEDSCOUNT;
|
||||
@ -106,15 +114,10 @@ addfile(path, opts, flags, rule)
|
||||
error("cannot mix needs-count and needs-flag");
|
||||
goto bad;
|
||||
}
|
||||
if (opts == NULL && (needc || needf)) {
|
||||
if (optx == NULL && (needc || needf)) {
|
||||
error("nothing to %s for %s", needc ? "count" : "flag", path);
|
||||
goto bad;
|
||||
}
|
||||
if ((fi = ht_lookup(pathtab, path)) != NULL) {
|
||||
showprev("", fi);
|
||||
error("file %s listed again", path);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* find last part of pathname, and same without trailing suffix */
|
||||
tail = rindex(path, '/');
|
||||
@ -124,57 +127,41 @@ addfile(path, opts, flags, rule)
|
||||
tail++;
|
||||
dotp = rindex(tail, '.');
|
||||
if (dotp == NULL || dotp[1] == 0 ||
|
||||
(baselen = dotp - tail) >= sizeof(buf)) {
|
||||
(baselen = dotp - tail) >= sizeof(base)) {
|
||||
error("invalid pathname `%s'", path);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a copy of the path without the .c/.s/whatever suffix.
|
||||
* This must be unique per "files" file (e.g., a specific
|
||||
* file can override a standard file, but no standard file
|
||||
* can override another standard file). This is not perfect
|
||||
* but should catch any major errors.
|
||||
*/
|
||||
bcopy(tail, buf, baselen);
|
||||
buf[baselen] = 0;
|
||||
base = intern(buf);
|
||||
if ((fi = ht_lookup(basetab, base)) != NULL) {
|
||||
if (fi->fi_srcfile != yyfile) {
|
||||
showprev("note: ", fi);
|
||||
error("is overridden by %s", path);
|
||||
errors--; /* take it away */
|
||||
fi->fi_flags |= FI_HIDDEN;
|
||||
} else {
|
||||
showprev("", fi);
|
||||
error("collides with %s (both make %s.o)",
|
||||
path, base);
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Commit this file to memory.
|
||||
* Commit this file to memory. We will decide later whether it
|
||||
* will be used after all.
|
||||
*/
|
||||
fi = emalloc(sizeof *fi);
|
||||
if (ht_insert(pathtab, path, fi)) {
|
||||
free(fi);
|
||||
if ((fi = ht_lookup(pathtab, path)) == NULL)
|
||||
panic("addfile: ht_lookup(%s)", path);
|
||||
error("duplicate file %s", path);
|
||||
xerror(fi->fi_srcfile, fi->fi_srcline,
|
||||
"here is the original definition");
|
||||
}
|
||||
memcpy(base, tail, baselen);
|
||||
base[baselen] = 0;
|
||||
fi->fi_next = NULL;
|
||||
fi->fi_srcfile = yyfile;
|
||||
fi->fi_srcline = currentline();
|
||||
fi->fi_flags = flags;
|
||||
fi->fi_lastc = dotp[strlen(dotp) - 1];
|
||||
fi->fi_path = path;
|
||||
fi->fi_tail = tail;
|
||||
fi->fi_base = base;
|
||||
fi->fi_opt = opts;
|
||||
fi->fi_base = intern(base);
|
||||
fi->fi_optx = optx;
|
||||
fi->fi_optf = NULL;
|
||||
fi->fi_mkrule = rule;
|
||||
if (ht_insert(pathtab, path, fi))
|
||||
panic("addfile: ht_insert(%s)", path);
|
||||
(void)ht_replace(basetab, base, fi);
|
||||
*nextfile = fi;
|
||||
nextfile = &fi->fi_next;
|
||||
return;
|
||||
bad:
|
||||
nvfreel(opts);
|
||||
expr_free(optx);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -190,73 +177,265 @@ checkfiles()
|
||||
register struct nvlist *nv;
|
||||
|
||||
last = NULL;
|
||||
for (fi = *unchecked; fi != NULL; last = fi, fi = fi->fi_next) {
|
||||
if ((fi->fi_flags & FI_NEEDSCOUNT) == 0)
|
||||
continue;
|
||||
for (nv = fi->fi_opt; nv != NULL; nv = nv->nv_next)
|
||||
if (ht_lookup(devbasetab, nv->nv_name) == NULL) {
|
||||
xerror(fi->fi_srcfile, fi->fi_srcline,
|
||||
"`%s' is not a countable device",
|
||||
nv->nv_name);
|
||||
/* keep fixfiles() from complaining again */
|
||||
fi->fi_flags |= FI_HIDDEN;
|
||||
}
|
||||
}
|
||||
for (fi = *unchecked; fi != NULL; last = fi, fi = fi->fi_next)
|
||||
if ((fi->fi_flags & FI_NEEDSCOUNT) != 0)
|
||||
(void)expr_eval(fi->fi_optx, checkaux, fi);
|
||||
if (last != NULL)
|
||||
unchecked = &last->fi_next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Auxiliary function for checkfiles, called from expr_eval.
|
||||
* We are not actually interested in the expression's value.
|
||||
*/
|
||||
static int
|
||||
checkaux(name, context)
|
||||
const char *name;
|
||||
void *context;
|
||||
{
|
||||
register struct files *fi = context;
|
||||
|
||||
if (ht_lookup(devbasetab, name) == NULL) {
|
||||
xerror(fi->fi_srcfile, fi->fi_srcline,
|
||||
"`%s' is not a countable device",
|
||||
name);
|
||||
/* keep fixfiles() from complaining again */
|
||||
fi->fi_flags |= FI_HIDDEN;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* We have finished reading everything. Tack the files down: calculate
|
||||
* selection and counts as needed.
|
||||
* selection and counts as needed. Check that the object files built
|
||||
* from the selected sources do not collide.
|
||||
*/
|
||||
int
|
||||
fixfiles()
|
||||
{
|
||||
register struct files *fi;
|
||||
register struct nvlist *nv;
|
||||
register struct devbase *dev;
|
||||
int sel, err;
|
||||
register struct files *fi, *ofi;
|
||||
struct nvlist *flathead, **flatp;
|
||||
int err, sel;
|
||||
|
||||
err = 0;
|
||||
for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
|
||||
/* Skip files that generated counted-device complaints. */
|
||||
if (fi->fi_flags & FI_HIDDEN)
|
||||
continue;
|
||||
if ((nv = fi->fi_opt) == NULL) { /* standard */
|
||||
fi->fi_flags |= FI_SEL;
|
||||
continue;
|
||||
if (fi->fi_optx != NULL) {
|
||||
/* Optional: see if it is to be included. */
|
||||
flathead = NULL;
|
||||
flatp = &flathead;
|
||||
sel = expr_eval(fi->fi_optx,
|
||||
fi->fi_flags & FI_NEEDSCOUNT ? fixcount :
|
||||
fi->fi_flags & FI_NEEDSFLAG ? fixfsel :
|
||||
fixsel,
|
||||
&flatp);
|
||||
fi->fi_optf = flathead;
|
||||
if (!sel)
|
||||
continue;
|
||||
}
|
||||
/* figure out whether it is selected */
|
||||
sel = 0;
|
||||
if (fi->fi_flags & FI_NEEDSCOUNT) {
|
||||
/* ... and compute counts too */
|
||||
do {
|
||||
dev = ht_lookup(devbasetab, nv->nv_name);
|
||||
if (dev == NULL) {
|
||||
xerror(fi->fi_srcfile, fi->fi_srcline,
|
||||
"`%s' is not a countable device",
|
||||
nv->nv_name);
|
||||
err = 1;
|
||||
} else {
|
||||
if (dev->d_umax)
|
||||
sel = 1;
|
||||
nv->nv_int = dev->d_umax;
|
||||
(void)ht_insert(needcnttab,
|
||||
nv->nv_name, nv);
|
||||
}
|
||||
} while ((nv = nv->nv_next) != NULL);
|
||||
} else {
|
||||
do {
|
||||
if (ht_lookup(selecttab, nv->nv_name)) {
|
||||
sel = 1;
|
||||
if (fi->fi_flags & FI_NEEDSFLAG)
|
||||
nv->nv_int = 1;
|
||||
}
|
||||
} while ((nv = nv->nv_next) != NULL);
|
||||
|
||||
/* We like this file. Make sure it generates a unique .o. */
|
||||
if (ht_insert(basetab, fi->fi_base, fi)) {
|
||||
if ((ofi = ht_lookup(basetab, fi->fi_base)) == NULL)
|
||||
panic("fixfiles ht_lookup(%s)", fi->fi_base);
|
||||
/*
|
||||
* 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 (ht_replace(basetab, fi->fi_base, fi) != 1)
|
||||
panic("fixfiles ht_replace(%s)",
|
||||
fi->fi_base);
|
||||
ofi->fi_flags &= ~FI_SEL;
|
||||
ofi->fi_flags |= FI_HIDDEN;
|
||||
} else {
|
||||
xerror(fi->fi_srcfile, fi->fi_srcline,
|
||||
"object file collision on %s.o, from %s",
|
||||
fi->fi_base, fi->fi_path);
|
||||
xerror(ofi->fi_srcfile, ofi->fi_srcline,
|
||||
"here is the previous file: %s",
|
||||
ofi->fi_path);
|
||||
err = 1;
|
||||
}
|
||||
}
|
||||
/* if selected, we are go */
|
||||
if (sel)
|
||||
fi->fi_flags |= FI_SEL;
|
||||
fi->fi_flags |= FI_SEL;
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when evaluating a needs-count expression. Make sure the
|
||||
* atom is a countable device. The expression succeeds iff there
|
||||
* is at least one of them (note that while `xx*' will not always
|
||||
* set xx's d_umax > 0, you cannot mix '*' and needs-count). The
|
||||
* mkheaders() routine wants a flattened, in-order list of the
|
||||
* atoms for `#define name value' lines, so we build that as we
|
||||
* are called to eval each atom.
|
||||
*/
|
||||
static int
|
||||
fixcount(name, context)
|
||||
register const char *name;
|
||||
void *context;
|
||||
{
|
||||
register struct nvlist ***p = context;
|
||||
register struct devbase *dev;
|
||||
register struct nvlist *nv;
|
||||
|
||||
dev = ht_lookup(devbasetab, name);
|
||||
if (dev == NULL) /* cannot occur here; we checked earlier */
|
||||
panic("fixcount(%s)", name);
|
||||
nv = newnv(name, NULL, NULL, dev->d_umax, NULL);
|
||||
**p = nv;
|
||||
*p = &nv->nv_next;
|
||||
(void)ht_insert(needcnttab, name, nv);
|
||||
return (dev->d_umax != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from fixfiles when eval'ing a selection expression for a
|
||||
* file that will generate a .h with flags. We will need the flat list.
|
||||
*/
|
||||
static int
|
||||
fixfsel(name, context)
|
||||
const char *name;
|
||||
void *context;
|
||||
{
|
||||
register struct nvlist ***p = context;
|
||||
register struct nvlist *nv;
|
||||
register int sel;
|
||||
|
||||
sel = ht_lookup(selecttab, name) != NULL;
|
||||
nv = newnv(name, NULL, NULL, sel, NULL);
|
||||
**p = nv;
|
||||
*p = &nv->nv_next;
|
||||
return (sel);
|
||||
}
|
||||
|
||||
/*
|
||||
* As for fixfsel above, but we do not need the flat list.
|
||||
*/
|
||||
static int
|
||||
fixsel(name, context)
|
||||
const char *name;
|
||||
void *context;
|
||||
{
|
||||
|
||||
return (ht_lookup(selecttab, name) != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Eval an expression tree. Calls the given function on each node,
|
||||
* passing it the given context & the name; return value is &/|/! of
|
||||
* results of evaluating atoms.
|
||||
*
|
||||
* No short circuiting ever occurs. fn must return 0 or 1 (otherwise
|
||||
* our mixing of C's bitwise & boolean here may give surprises).
|
||||
*/
|
||||
static int
|
||||
expr_eval(expr, fn, context)
|
||||
register struct nvlist *expr;
|
||||
register int (*fn) __P((const char *, void *));
|
||||
register void *context;
|
||||
{
|
||||
int lhs, rhs;
|
||||
|
||||
switch (expr->nv_int) {
|
||||
|
||||
case FX_ATOM:
|
||||
return ((*fn)(expr->nv_name, context));
|
||||
|
||||
case FX_NOT:
|
||||
return (!expr_eval(expr->nv_next, fn, context));
|
||||
|
||||
case FX_AND:
|
||||
lhs = expr_eval(expr->nv_ptr, fn, context);
|
||||
rhs = expr_eval(expr->nv_next, fn, context);
|
||||
return (lhs & rhs);
|
||||
|
||||
case FX_OR:
|
||||
lhs = expr_eval(expr->nv_ptr, fn, context);
|
||||
rhs = expr_eval(expr->nv_next, fn, context);
|
||||
return (lhs | rhs);
|
||||
}
|
||||
panic("expr_eval %d", expr->nv_int);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Free an expression tree.
|
||||
*/
|
||||
static void
|
||||
expr_free(expr)
|
||||
register struct nvlist *expr;
|
||||
{
|
||||
register struct nvlist *rhs;
|
||||
|
||||
/* This loop traverses down the RHS of each subexpression. */
|
||||
for (; expr != NULL; expr = rhs) {
|
||||
switch (expr->nv_int) {
|
||||
|
||||
/* 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 %d", expr->nv_int);
|
||||
}
|
||||
rhs = expr->nv_next;
|
||||
nvfree(expr);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Print expression tree.
|
||||
*/
|
||||
void
|
||||
prexpr(expr)
|
||||
struct nvlist *expr;
|
||||
{
|
||||
static void pr0();
|
||||
|
||||
printf("expr =");
|
||||
pr0(expr);
|
||||
printf("\n");
|
||||
(void)fflush(stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
pr0(e)
|
||||
register struct nvlist *e;
|
||||
{
|
||||
|
||||
switch (e->nv_int) {
|
||||
case FX_ATOM:
|
||||
printf(" %s", e->nv_name);
|
||||
return;
|
||||
case FX_NOT:
|
||||
printf(" (!");
|
||||
break;
|
||||
case FX_AND:
|
||||
printf(" (&");
|
||||
break;
|
||||
case FX_OR:
|
||||
printf(" (|");
|
||||
break;
|
||||
default:
|
||||
printf(" (?%d?", e->nv_int);
|
||||
break;
|
||||
}
|
||||
if (e->nv_ptr)
|
||||
pr0(e->nv_ptr);
|
||||
pr0(e->nv_next);
|
||||
printf(")");
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
%{
|
||||
/* $NetBSD: gram.y,v 1.6 1996/03/17 11:50:11 cgd Exp $ */
|
||||
/* $NetBSD: gram.y,v 1.7 1996/03/17 13:18:18 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -79,6 +79,11 @@ static int adepth;
|
||||
#define new_p(p) new0(NULL, NULL, p, 0, NULL)
|
||||
#define new_px(p, x) new0(NULL, NULL, p, 0, x)
|
||||
|
||||
#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)
|
||||
|
||||
static void cleanup __P((void));
|
||||
static void setmachine __P((const char *, const char *));
|
||||
static void setmaxpartitions __P((int));
|
||||
@ -100,7 +105,7 @@ static void setmaxpartitions __P((int));
|
||||
%token <val> FFLAG NUMBER
|
||||
%token <str> PATHNAME WORD
|
||||
|
||||
%type <list> fopts
|
||||
%type <list> fopts fexpr fatom
|
||||
%type <val> fflgs
|
||||
%type <str> rule
|
||||
%type <attr> attr
|
||||
@ -167,9 +172,19 @@ file:
|
||||
|
||||
/* order of options is important, must use right recursion */
|
||||
fopts:
|
||||
WORD fopts = { $$ = new_nx($1, $2); } |
|
||||
fexpr = { $$ = $1; } |
|
||||
/* empty */ = { $$ = NULL; };
|
||||
|
||||
fexpr:
|
||||
fatom = { $$ = $1; } |
|
||||
'!' fatom = { $$ = fx_not($2); } |
|
||||
fexpr '&' fexpr = { $$ = fx_and($1, $3); } |
|
||||
fexpr '|' fexpr = { $$ = fx_or($1, $3); } |
|
||||
'(' fexpr ')' = { $$ = $2; };
|
||||
|
||||
fatom:
|
||||
WORD = { $$ = fx_atom($1); };
|
||||
|
||||
fflgs:
|
||||
fflgs FFLAG = { $$ = $1 | $2; } |
|
||||
/* empty */ = { $$ = 0; };
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hash.c,v 1.2 1996/03/03 17:28:15 thorpej Exp $ */
|
||||
/* $NetBSD: hash.c,v 1.3 1996/03/17 13:18:20 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -261,6 +261,8 @@ ht_insrep(ht, nam, val, replace)
|
||||
}
|
||||
*hpp = hp = newhashent(nam, h);
|
||||
hp->h_value = val;
|
||||
if (++ht->ht_used > ht->ht_lim)
|
||||
ht_expand(ht);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mkheaders.c,v 1.9 1996/03/17 06:29:25 cgd Exp $ */
|
||||
/* $NetBSD: mkheaders.c,v 1.10 1996/03/17 13:18:21 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -68,7 +68,7 @@ mkheaders()
|
||||
if (fi->fi_flags & FI_HIDDEN)
|
||||
continue;
|
||||
if (fi->fi_flags & (FI_NEEDSCOUNT | FI_NEEDSFLAG) &&
|
||||
emitcnt(fi->fi_opt))
|
||||
emitcnt(fi->fi_optf))
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mkmakefile.c,v 1.28 1996/03/17 06:29:30 cgd Exp $ */
|
||||
/* $NetBSD: mkmakefile.c,v 1.29 1996/03/17 13:18:23 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -52,15 +52,19 @@
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "sem.h"
|
||||
|
||||
/*
|
||||
* Make the Makefile.
|
||||
*/
|
||||
|
||||
static const char *srcpath __P((struct files *));
|
||||
|
||||
static int emitdefs __P((FILE *));
|
||||
static int emitfiles __P((FILE *, int));
|
||||
|
||||
static int emitobjs __P((FILE *));
|
||||
static int emitcfiles __P((FILE *));
|
||||
static int emitsfiles __P((FILE *));
|
||||
static int emitfiles __P((FILE *, int));
|
||||
static int emitrules __P((FILE *));
|
||||
static int emitload __P((FILE *));
|
||||
|
||||
@ -141,6 +145,33 @@ bad:
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return (possibly in a static buffer) the name of the `source' for a
|
||||
* file. If we have `options source', or if the file is marked `always
|
||||
* source', this is always the path from the `file' line; otherwise we
|
||||
* get the .o from the obj-directory.
|
||||
*/
|
||||
static const char *
|
||||
srcpath(fi)
|
||||
register struct files *fi;
|
||||
{
|
||||
#if 1
|
||||
/* Always have source, don't support object dirs for kernel builds. */
|
||||
return (fi->fi_path);
|
||||
#else
|
||||
static char buf[MAXPATHLEN];
|
||||
|
||||
if (have_source || (fi->fi_flags & FI_ALWAYSSRC) != 0)
|
||||
return (fi->fi_path);
|
||||
if (objpath == NULL) {
|
||||
error("obj-directory not set");
|
||||
return (NULL);
|
||||
}
|
||||
(void)snprintf(buf, sizeof buf, "%s/%s.o", objpath, fi->fi_base);
|
||||
return (buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
emitdefs(fp)
|
||||
register FILE *fp;
|
||||
@ -224,6 +255,7 @@ emitfiles(fp, suffix)
|
||||
register struct files *fi;
|
||||
register struct config *cf;
|
||||
register int lpos, len, sp;
|
||||
register const char *fpath;
|
||||
char swapname[100];
|
||||
|
||||
if (fprintf(fp, "%cFILES=", toupper(suffix)) < 0)
|
||||
@ -233,10 +265,12 @@ emitfiles(fp, suffix)
|
||||
for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
|
||||
if ((fi->fi_flags & FI_SEL) == 0)
|
||||
continue;
|
||||
len = strlen(fi->fi_path);
|
||||
if (fi->fi_path[len - 1] != suffix)
|
||||
if ((fpath = srcpath(fi)) == NULL)
|
||||
return (1);
|
||||
len = strlen(fpath);
|
||||
if (fpath[len - 1] != suffix)
|
||||
continue;
|
||||
if (*fi->fi_path != '/')
|
||||
if (*fpath != '/')
|
||||
len += 3; /* "$S/" */
|
||||
if (lpos + len > 72) {
|
||||
if (fputs(" \\\n", fp) < 0)
|
||||
@ -244,8 +278,8 @@ emitfiles(fp, suffix)
|
||||
sp = '\t';
|
||||
lpos = 7;
|
||||
}
|
||||
if (fprintf(fp, "%c%s%s", sp, *fi->fi_path != '/' ? "$S/" : "",
|
||||
fi->fi_path) < 0)
|
||||
if (fprintf(fp, "%c%s%s", sp, *fpath != '/' ? "$S/" : "",
|
||||
fpath) < 0)
|
||||
return (1);
|
||||
lpos += len + 1;
|
||||
sp = ' ';
|
||||
@ -290,19 +324,21 @@ emitrules(fp)
|
||||
register FILE *fp;
|
||||
{
|
||||
register struct files *fi;
|
||||
register const char *cp;
|
||||
register const char *cp, *fpath;
|
||||
int ch;
|
||||
char buf[200];
|
||||
|
||||
for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
|
||||
if ((fi->fi_flags & FI_SEL) == 0)
|
||||
continue;
|
||||
if ((fpath = srcpath(fi)) == NULL)
|
||||
return (1);
|
||||
if (fprintf(fp, "%s.o: %s%s\n", fi->fi_base,
|
||||
*fi->fi_path != '/' ? "$S/" : "", fi->fi_path) < 0)
|
||||
*fpath != '/' ? "$S/" : "", fpath) < 0)
|
||||
return (1);
|
||||
if ((cp = fi->fi_mkrule) == NULL) {
|
||||
cp = fi->fi_flags & FI_DRIVER ? "DRIVER" : "NORMAL";
|
||||
ch = fi->fi_lastc;
|
||||
ch = fpath[strlen(fpath) - 1];
|
||||
if (islower(ch))
|
||||
ch = toupper(ch);
|
||||
(void)sprintf(buf, "${%s_%c%s}", cp, ch,
|
||||
|
Loading…
Reference in New Issue
Block a user