/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1984-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Glenn Fowler
* AT&T Research
*
* make support routines
*/
#include "make.h"
/*
* stat() that checks for read access
* if res!=0 then resolve(name,fd,mode) must be called
*/
int
{
Time_t t;
{
}
{
{
{
{
{
{
/*
* not in this or any lower view
*/
return -1;
}
}
}
goto found;
}
return -1;
}
}
return -1;
return -1;
#if _WINIX
{
}
#endif
if (!tmxgetmtime(st))
{
}
{
t = CURTIME;
tmxsetmtime(st, t);
}
return 0;
}
/*
* allocate a chunk of units
* free units linked onto head
*/
void*
{
#else
register char* p;
register char* e;
register char** x;
int n;
void* v;
v = p = newof(0, char, n, 0);
e = p + n - unit;
x = head;
while (((char*)(x = (char**)(*x = p += unit))) < e);
return v;
#endif
}
/*
* append a list q onto the end of list p
* list p is surgically modified
*/
{
register List_t* t;
if (t = p)
{
if (q)
{
while (t->next)
t = t->next;
t->next = q;
}
return p;
}
else return q;
}
/*
* add rule r onto the front of list p
* list p is not modified
*/
{
register List_t* q;
newlist(q);
q->next = p;
q->rule = r;
return q;
}
/*
* construct and return a copy of list p
* the items in the list are not copied
*/
{
register List_t* q;
register List_t* r;
register List_t* t;
if (!p)
return 0;
newlist(r);
q = r;
while (p)
{
if (p = p->next)
{
newlist(t);
q = q->next = t;
}
}
q->next = 0;
return r;
}
/*
* format time or convert to number
*/
char*
{
if (!t)
t = 0;
else if (t == NOTIME)
t = 100000000;
else if (t == OLDTIME)
t = 200000000;
{
t = 300000000;
else
t = 400000000;
}
else
}
/*
* convert numeric string time to Time_t
*/
timenum(const char* s, char** p)
{
Time_t t;
unsigned long n;
unsigned long m;
char* e;
{
if (p)
*p = (char*)s;
return TMX_NOTIME;
}
n = 0;
if (*e == '.')
{
m = 1000000000;
while (isdigit(*++e))
n += (*e - '0') * (m /= 10);
}
if (p)
*p = e;
return tmxsns(t, n);
}
/*
* convert time t to a string for tracing
*/
char*
{
if (!t)
return "not found";
else if (t == NOTIME)
return "not checked";
else if (t == OLDTIME)
return "really old";
return fmttmx("%?%K.%6N", t);
return "recent";
else
return "current";
}
/*
* printext() value types
*/
#if _ast_intmax_long
#endif
typedef union Value_u
{
char** p;
char* s;
intmax_t q;
unsigned long u;
long l;
int i;
short h;
char c;
double d;
} Value_t;
typedef struct Fmt_s
{
char* arg;
int all;
} Fmt_t;
/*
* printf %! extension function
*/
static int
{
register char* s;
char* txt;
char* e;
{
}
return -1;
{
}
else
txt = 0;
{
case 'C':
/*FALLTHROUGH*/
case 'c':
value->c = *s;
break;
case 'd':
break;
case 'F':
/*FALLTHROUGH*/
case 'a':
case 'A':
case 'e':
case 'E':
case 'f':
case 'g':
case 'G':
break;
case 'o':
case 'u':
case 'x':
case 'X':
break;
case 'p':
break;
case 'S':
/*FALLTHROUGH*/
case 's':
value->s = s;
if (txt)
{
{
*s++ = '_';
for (; *s; s++)
*s = '_';
}
{
for (; *s; s++)
if (isupper(*s))
*s = tolower(*s);
else if (islower(*s))
*s = toupper(*s);
}
{
for (; *s; s++)
if (isupper(*s))
*s = tolower(*s);
}
{
for (; *s; s++)
if (islower(*s))
*s = toupper(*s);
}
{
for (; *s; s++)
*s = '.';
}
}
break;
case 't':
case 'T':
if (*e || tm == TMX_NOTIME)
break;
case 'Z':
value->c = 0;
break;
case '.':
break;
default:
tmpname[1] = 0;
break;
}
return 0;
}
/*
* printf from args in argp into sp
* all!=0 if %s gets all of argp
* term is an sfputr terminator
*/
int
{
int n;
int i;
n = 0;
{
n += i;
break;
}
if (term != -1)
{
n++;
}
sfstrclose(tp);
return n;
}
/*
* return next (possibly quoted) space-separated arg in *buf
* *buf points past end of arg on return
* the contents of buf are modified
* if flags!=0 then it is set with metarule specific A_* flags
*/
char*
{
register char* s;
register char* t;
register int c;
char* a;
char* q;
int paren;
if (flags)
{
{
for (s += 2; isspace(*s); s++);
*flags |= A_nooptions;
}
else
}
if (!*(a = t = s))
return 0;
paren = 0;
for (;;)
{
switch (c = *s++)
{
case '\\':
if (*s)
{
*t++ = c;
c = *s++;
}
break;
case '(':
paren++;
if (flags)
break;
case ')':
paren--;
break;
case '"':
case '\'':
if (!paren)
{
for (q = t; *s && *s != c; *t++ = *s++)
if (*s == '\\' && *(s + 1))
*t++ = *s++;
if (*s)
s++;
*t = 0;
t = q + stresc(q);
continue;
}
break;
case '%':
*flags |= A_metarule;
break;
case '=':
break;
case ',':
if (flags)
break;
default:
break;
/*FALLTHROUGH*/
case 0:
*t = 0;
if (!c)
s--;
*buf = s;
*flags |= A_nooptions;
return a;
}
*t++ = c;
}
}
/*
* list explanation
*/
void
{
}