expand.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/***********************************************************************
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* This software is part of the ast package *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* Copyright (c) 1984-2012 AT&T Intellectual Property *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* and is licensed under the *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* Eclipse Public License, Version 1.0 *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* by AT&T Intellectual Property *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* A copy of the License is available at *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* http://www.eclipse.org/org/documents/epl-v10.html *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* Information and Software Systems Research *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* AT&T Research *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* Florham Park NJ *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* Glenn Fowler <gsf@research.att.com> *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync***********************************************************************/
#include "make.h"
#include "expand.h"
#include <magic.h>
#include <regex.h>
typedef int (*Cmp_f)(const char*, const char*);
istrcmp(const char* a, const char* b)
return strcmp(b, a);
istrcoll(const char* a, const char* b)
return strcoll(b, a);
numcmp(const char* a, const char* b)
char* ea;
char* eb;
inumcmp(const char* a, const char* b)
return numcmp(b, a);
istrpcmp(const char* a, const char* b)
return strpcmp(b, a);
istrvcmp(const char* a, const char* b)
return strvcmp(b, a);
static Cmp_f
Cmp_f f;
f = strcoll;
static Edit_map_t*
while (isspace(*s)) s++;
return mid;
char* tok;
sep = 0;
if (sep)
sep = 0;
if (sep)
register List_t* p;
if (xp)
if (r->mark & c)
if (!(r->mark & m))
r->mark |= m|c;
r->mark &= ~c;
else if (r->mark & m)
r->mark &= ~(m|c);
char* tok;
long pos;
int cycle;
int dot;
int sep;
long pos;
char* tok0;
char* tok1;
sep = 0;
if (dot)
register List_t* p;
register Rule_t* r;
List_t* q;
List_t* x;
char* tok;
canon(s);
r = makerule(s);
s = r->name;
r = makerule(s);
for (x = q; x; x = x->next)
canon(s);
if (r = getrule(s))
if (!(r->mark & M_metarule) && r->name[0] == '.' && r->name[1] == '.' && (!r->name[2] || r->name[2] == '/'))
if (!(r->mark & M_metarule) && r->name[0] == '.' && r->name[1] == '.' && (!r->name[2] || r->name[2] == '/'))
for (p = q; p; p = p->next)
for (p = q; p; p = p->next)
freelist(q);
register List_t* p;
register List_t* q;
register Rule_t* r;
int sep;
List_t* x;
char* tok;
sep = 0;
if (r = getrule(s))
for (q = x; q; q = q->next)
goto next;
next:;
freelist(x);
char* tok;
long rew;
long pre;
long pos;
long brk;
a = BREAKARGS;
if (n != REG_NOMATCH)
if (*pat)
register Rule_t* r;
File_t* f;
char* tok;
int ignorecase;
ignorecase = 0;
r = makerule(s);
dirscan(r);
*v++ = r->name;
if (*pat)
if (!ignorecase)
if (n != REG_NOMATCH)
for (; f; f = f->next)
goto next;
next: ;
goto first;
goto first;
first: ;
if (*pat)
if (ignorecase)
char* tok;
long pos;
switch (sep)
case LT:
case LE:
case EQ:
case NE:
case NOT:
case GE:
case GT:
#if DEBUG
switch (sep)
case LT:
case LE:
case EQ:
case NE:
case NOT:
case GE:
case GT:
#if DEBUG
size_t m;
size_t n;
n = PATH_MAX;
register List_t* p;
register Rule_t* a;
unsigned long here;
unsigned long need;
need = 0;
if (r->prereqs)
a = p->rule;
if (!need)
if (need)
need = 0;
a = p->rule;
r->prereqs = 0;
return mark;
return mark;
mark++;
return mark;
static void order_find(Sfio_t*, Sfio_t*, Sfio_t*, Hash_table_t*, char*, char*, char*, char*, unsigned int);
order_all(Sfio_t* xp, Sfio_t* tmp, Sfio_t* vec, Hash_table_t* tab, Rule_t* d, char* makefiles, char* skip, unsigned int flags)
order_scan(Sfio_t* xp, Sfio_t* tmp, Sfio_t* vec, Hash_table_t* tab, Rule_t* d, Rule_t* r, char* makefiles, char* skip, unsigned int flags)
s = d->name;
if (strneq(s, ORDER_RECURSE, sizeof(ORDER_RECURSE) - 1) && *(s += sizeof(ORDER_RECURSE) - 1) == ':')
order_find(Sfio_t* xp, Sfio_t* tmp, Sfio_t* vec, Hash_table_t* tab, char* dir, char* files, char* makefiles, char* skip, unsigned int flags)
Rule_t* r;
Rule_t* d;
char* tok;
dir = 0;
if (skip)
if (dir)
else if (!(state.questionable & 0x20000000) && !strchr(s, '/') && (t = strrchr(internal.pwd, '/')) && streq(s, t + 1))
if ((flags & ORDER_directory) || (flags & (ORDER_force|ORDER_paths)) == ORDER_force && (d = bindfile(NiL, t, 0)) && !stat(d->name, &st) && S_ISDIR(st.st_mode))
d = makerule(t);
t = makefiles;
if (dir)
d = makerule(t);
order_cmp(const void* a, const void* b)
order_recurse(Sfio_t* xp, char* directories, char* makefiles, char* skip, char* targets, unsigned int flags)
char* tok;
char* lib;
Rule_t* r;
Rule_t* d;
Rule_t** v;
Rule_t** e;
List_t* q;
unsigned long mark;
int var;
var = 0;
lib = 0;
for (t = s; (i = *s) && i != ' ' && i != '\t' && i != '\r' && i != '"' && i != '\'' && i != '\\' && i != ':'; s++)
else if (i == '.' && *(s + 1) != 'c' && *(s + 1) != 'C' && *(s + 1) != 'h' && *(s + 1) != 'H' && t[0] == 'l' && t[1] == 'i' && t[2] == 'b')
if (var)
if (z > d->name)
if (!order)
while (*s && !isspace(*s))
if (isupper(*u))
*u = tolower(*u);
else if (!isalnum(*u))
if (!isalnum(*u))
if (k && ((r = (Rule_t*)hashget(tab, t)) && (r->mark & M_MUST) && r != d || *t++ == 'l' && *t++ == 'i' && *t++ == 'b' && *t && (r = (Rule_t*)hashget(tab, t)) && (r->mark & M_MUST) && r != d))
t = d->name;
u = r->name;
t = d->name;
else if (((s - d->name) != 3 || *(s - 1) != 'b' || *(s - 2) != 'i' || *(s - 3) != 'l') && (*(s + 1) != 'l' || *(s + 2) != 'i' || *(s + 3) != 'b'))
t = s + strlen(s);
mark = 0;
if (targets)
if (order)
else if (!(state.questionable & 0x40000000) && !(flags & ORDER_prereqs) && (r->mark & (M_INIT|M_LHS|M_MUST|M_RHS|M_SKIP)) == M_RHS)
r->complink = 0;
register Rule_t* r;
Rule_t* x;
int chop;
int root;
long pos;
if (r = getrule(s))
s = r->name;
goto view;
sep = 0;
if (((state.questionable & 0x10000000) || !(s = r->uname) || !(t = strrchr(r->name, '/')) || !streq(t+1, s)) && ((t = getbound(r->name)) || (s = r->uname) && (t = getbound(s))))
if ((x = getrule(t)) && (x->dynamic & (D_entries|D_scanned)) == (D_entries|D_scanned) || *t == '/' && !*(t + 1))
x = makerule(t);
if (sep)
#if DEBUG
#if DEBUG
if (sep)
s = unbound(r);
sep = 0;
r = makerule(s);
r = bind(r);
if (chop)
sep = 0;
if (sep)
op++;
op++;
if (!*op)
else if ((!stat(s, &st) && !stat(op, &st1) && st.st_dev == st1.st_dev && st.st_ino == st1.st_ino) == (sep == EQ))
view:
op++;
sep = 0;
goto absolute;
if (sep)
sfputr(xp, t + ((!n++ && !strncmp(t, internal.pwd, internal.pwdlen) && t[internal.pwdlen] == '/') ? (internal.pwdlen + 1) : 0), -1);
root = 0;
s = r->name;
if (n = r->view)
goto absolute;
if (root)
pathcanon(t, 0, 0);
if (sep)
goto absolute;
if (sepcmp(sep, (unsigned long)((r->dynamic & D_global) ? state.maxview : r->view), (unsigned long)n))
op++;
op++;
op++;
if (*op)
for (t = state.view[r->view].path + n; t > state.view[r->view].path && (*t != '/' || --n > 0); t--);
if (*op)
pathcanon(s, 0, 0);
if (*++op)
s = r->name;
op++;
op++;
sfputr(xp, !(r->dynamic & D_alias) || !r->uname || strlen(r->name) >= strlen(r->uname) ? r->name : r->uname, -1);
long pos;
q = dir;
q = DELETE;
if (q == KEEP)
q = bas;
p = s + strlen(s);
if (q == KEEP)
q = suf;
if (*p && q == KEEP)
if (!(n = regexec(re, s, elementsof(match), match, 0)) && !(n = regsubexec(re, s, elementsof(match), match)))
else if (n != REG_NOMATCH)
char* mime;
if (!magic)
register Rule_t* r;
register Rule_t* x;
register Var_t* v;
register int op;
char* ops;
int dobind;
int dounbind;
int dowait;
int force;
int matched;
int tst;
List_t* q;
List_t* z;
dounbind = 0;
while (op = *p)
switch (op)
dowait = 0;
dobind = 0;
ops = p;
switch (op)
switch (*ops)
tst = (!dobind || getrule(s)) && !(nametype(s, NiL) & (NAME_altstate|NAME_staterule|NAME_statevar));
tst = 0;
tst = 0;
tst = 0;
r = makerule(s);
if (dounbind)
if (dobind)
r = bind(r);
ops++;
if (!*r->name)
switch (op)
ops++;
tst = (notfile(r) || !r->time && ((state.questionable & 0x04000000) || !(r->dynamic & D_triggered)) || r->status == IGNORE || state.exec && r->status != NOTYET && (x = staterule(RULE, r, NiL, 0)) && !x->time || (r->dynamic & (D_member|D_membertoo)) == D_member) ? 0 : 'F';
switch (op)
if (*(p = v->value))
op = 0;
if (!op)
if (tmp)
matched = 0;
switch (op)
matched = 0;
if (r->action || (r->property & (P_archive|P_command)) || !(state.questionable & 0x00004000) && (r->dynamic & D_dynamic))
matched = 0;
if (metamatch(stem, unbound(r), z->rule->name) && (!(r->property & P_terminal) || (z->rule->property & P_terminal)) && !(z->rule->property & f) && (x = metainfo('I', z->rule->name, NiL, 0)))
if ((x = metarule(q->rule->name, z->rule->name, 0)) && (!(r->property & P_terminal) || (x->property & P_terminal)) && !(x->property & f))
switch (*ops)
if (!*ops)
for (;; ops++)
switch (*ops)
tst = 0;
ops++;
if (tst)
ops++;
ops++;
if (!op)
switch (op)
if (!*ops)
if (dobind)
x = bind(x);
tm = 0;
switch (*ops++)
ops--;
tm = 0;
ops++;
if (r->active && active(r, r->active) && r->active->parent && !(r->active->parent->target->mark & M_mark) && r->active->parent->parent != r->active->parent)
register Rule_t* r;
register Rule_t* a;
register List_t* p;
Rule_t* x;
Rule_t* y;
Rule_t* z;
r = getrule(s);
s = r->name;
n = r->attribute;
if (x) n |= x->attribute;
if (att)
goto next;
goto next;
else if (hasattribute(r, a, x))
goto next;
att = t;
next: ;
register Rule_t* x;
register List_t* p;
register List_t* q;
if (metamatch(tmpname, name, p->rule->name) && (streq(tmpname, pat) || (b = strrchr(pat, '/')) && streq(tmpname, b + 1)))
Rule_t* y;
Rule_t* z;
List_t* u;
if (!z->uname)
if (metamatch(NiL, u->rule->name, z->uname) && (y = metainfo('S', q->rule->name, u->rule->name, 0)))
metaexpand(xp, stem, z && z->uname && (y = metarule(z->uname, p->rule->name, 0)) && y->action && !*y->action ? z->uname : p->rule->name);
#if _HUH_2000_06_01
n = EDITCONTEXT - n;
register int sep;
register Rule_t* r;
sep = 0;
register int op;
char* dir;
char* bas;
char* suf;
char* val;
char* oldp;
char* newp;
char* eb;
int zer;
int old;
int qual;
int cnt;
int cntlim;
int ctx;
int expall;
int sep;
int tokenize;
long beg;
long ctx_beg;
long cur;
long arg;
unsigned long all;
char* ctx_end;
char* tok;
Rule_t* r;
int out;
out = 0;
if (exp < 0)
all = 0;
if (exp)
qual = 0;
ed++;
ed--;
#if DEBUG
case ED_COPY:
goto copy;
case ED_EDIT:
goto copy;
case ED_OP:
m = *ed;
*ed = 0;
*ed = m;
while (n && n != del)
if (isspace(n))
n = *++ed;
ed++;
case ED_QUAL:
if (ed != s)
copy:
#if DEBUG
tokenize = 0;
sep = 0;
switch (op)
ed--;
s = ed;
if (*ed)
tokenize = 0;
n = op;
switch (op)
if (n = *ed)
ed++;
s = ed;
if (*ed == n)
ed++;
s = ed;
if (*ed)
ed++;
switch (*ed++)
if (*ed)
ed++;
ed++;
else if (*ed)
for (;; ed++)
switch (*ed)
ed++;
if (!sep)
ed++;
if (!sep)
if (cnt)
cnt = 0;
s = ed;
while (isspace(*++s));
if (*s == del)
if (*ed)
*ed++ = 0;
if (!*val)
switch (op)
switch (*ed)
goto parts;
goto parts;
tokenize = 0;
qual = 0;
all = 0;
if (!all)
if (xp)
switch (op)
val = 0;
if (!dir)
ctx = 0;
ctx = 0;
ctx = 0;
switch (op)
ctx = 0;
if (!sep)
switch (op)
n = SORT_first;
n |= SORT_sort;
n &= ~SORT_first;
n |= SORT_qualified;
n |= SORT_force;
if (n = regcomp(&re, val, REG_SHELL|REG_AUGMENTED|REG_LEFT|REG_RIGHT|REG_LENIENT|REG_NOSUB|REG_NULL))
val = 0;
switch (op)
order_recurse(xp, x, getval(external.files, VAL_PRIMARY|VAL_AUXILIARY), getval(external.skip, VAL_PRIMARY|VAL_AUXILIARY), val, ORDER_force|ORDER_prereqs);
order_recurse(xp, x, getval(external.files, VAL_PRIMARY|VAL_AUXILIARY), getval(external.skip, VAL_PRIMARY|VAL_AUXILIARY), val, ORDER_force);
n = SORT_sort;
n |= SORT_invert;
n |= SORT_numeric;
n |= SORT_uniq;
n |= SORT_version;
switch (*val++)
n |= SORT_collate;
n |= SORT_first;
n |= SORT_invert;
n |= SORT_numeric;
n |= SORT_reverse;
n |= SORT_prefix;
n |= SORT_uniq;
n |= SORT_version;
if (!all)
goto breakloop;
if (!tokenize)
else if (all)
goto breakloop;
s = r->name;
s = null;
switch (op)
#if !_drop_this_in_3_2
switch (*val)
if (*val)
while (v = tokread(t))
tokclose(t);
if (cntlim < 0)
switch (sep)
case EQ:
if (!cntlim)
if (s == null)
goto breakloop;
goto nextloop;
goto nextloop;
goto breakloop;
case NOT:
if (!cntlim)
goto nextloop;
case NE:
goto nextloop;
case LT:
goto breakloop;
case LE:
goto breakloop;
case GE:
goto nextloop;
case GT:
goto nextloop;
#if DEBUG
if (ctx_end)
*s = MARK_CONTEXT;
*--s = MARK_CONTEXT;
if (ctx_end)
if (all)
if (pos)
n = all;
lla = n;
exp++;
switch (op)
if (all)
if (out)
int exp;
int op;
int aux;
int ign;
long pos;
#if DEBUG
long beg;
static int level;
level = 0;
#if DEBUG
aux = 0;
if (ed)
ed++;
t = ed;
case ED_AUXILLIARY:
exp = 0;
case ED_LITERAL:
exp = 0;
case ED_PRIMARY:
exp = 0;
ed = t;
switch (*++ed)
ed++;
if (!ign)
#if DEBUG
if (msg)
if (!cvt)
if (!cvt)
if (!ed)
if (!cvt)
exp = 0;
exp++;
if (--nvars <= 0)
while (exp--)
if (*v || --nvars <= 0)
if (ed)
if (!cvt)
if (!val)
tmp = 0;
if (tmp)
#if DEBUG
if (msg)
if (cvt)
if (val)
level--;
int alt;
int del;
int nvars;
long ed;
long var;
if (isspace(*++a))
ed = 0;
if (c == alt)
nvars++;
else if (c == del)
alt = c = 0;
alt = c = 0;
if (!(del = *a++))
ed--;
else if (isspace(c))
if (val)