|
|
researchv9-SUN3(old)
/*
* $Header: /var/lib/cvsd/repos/research/researchv9/X11/src/X.V11R1/util/makedepend/parse.c,v 1.1.1.1 2018/04/24 17:22:00 root Exp $
*
* $Log: parse.c,v $
* Revision 1.1.1.1 2018/04/24 17:22:00 root
* researchv9-SUN3(old)
*
* Revision 1.1 87/09/11 08:13:35 toddb
* Initial revision
*
* Revision 1.1 87/04/08 16:40:53 rich
* Initial revision
*
* Revision 1.3 86/09/13 10:14:25 toddb
* Previous fix could cause problems if the number of defines in a
* file was an integral multiple of SYMTABINC: there would be no
* s_name = NULL at the end.
*
* Revision 1.2 86/09/04 12:45:35 toddb
* The way that define() allocated new define slots, every tenth entry had
* a null s_name and s_value. The effect was that slookup() only checked
* the first ten defines in any file.
*
* Revision 1.1 86/04/15 08:34:40 toddb
* Initial revision
*
*/
#include "def.h"
#include <sys/signal.h>
extern char *directives[];
extern struct symtab deflist[];
find_includes(filep, file, file_red, recursion)
struct filepointer *filep;
struct inclist *file, *file_red;
int recursion;
{
register char *line;
register int type;
while (line = getline(filep)) {
switch(type = deftype(line, filep, file_red, file, TRUE)) {
case IF:
type = find_includes(filep, file,
file_red, recursion+1);
if (type == ELSE)
gobble(filep, file, file_red);
break;
case IFFALSE:
type = gobble(filep, file, file_red);
if (type == ELSE)
find_includes(filep, file,
file_red, recursion+1);
break;
case IFDEF:
case IFNDEF:
if ((type == IFDEF && defined(line, file_red))
|| (type == IFNDEF && !defined(line, file_red))) {
debug1(type == IFNDEF ?
"line %d: %s !def'd in %s via %s%s\n" : "",
filep->f_line, line,
file->i_file, file_red->i_file, ": doit");
type = find_includes(filep, file,
file_red, recursion+1);
if (type == ELSE)
gobble(filep, file, file_red);
}
else {
debug1(type == IFDEF ?
"line %d: %s !def'd in %s via %s%s\n" : "",
filep->f_line, line,
file->i_file, file_red->i_file, ": gobble");
type = gobble(filep, file, file_red);
if (type == ELSE)
find_includes(filep, file,
file_red, recursion+1);
}
break;
case ELSE:
if (!recursion)
gobble(filep, file, file_red);
case ENDIF:
if (recursion)
return(type);
case DEFINE:
define(line, file);
break;
case UNDEF:
break;
case INCLUDE:
add_include(file, file_red, line, FALSE);
break;
case INCLUDEDOT:
add_include(file, file_red, line, TRUE);
break;
case -1:
log("%s, line %d: unknown directive == \"%s\"\n",
file_red->i_file, filep->f_line, line);
break;
case -2:
log("%s, line %d: incomplete include == \"%s\"\n",
file_red->i_file, filep->f_line, line);
break;
}
}
return(-1);
}
gobble(filep, file, file_red)
register struct filepointer *filep;
struct inclist *file, *file_red;
{
register char *line;
register int type;
while (line = getline(filep)) {
switch(type = deftype(line, filep, file_red, file, FALSE)) {
case IF:
case IFFALSE:
case IFDEF:
case IFNDEF:
type = gobble(filep, file, file_red);
if (type == ELSE)
type = gobble(filep, file, file_red);
break;
case ELSE:
case ENDIF:
debug0("%s, line %d: #%s\n",
file->i_file, filep->f_line,
directives[type]);
return(type);
case DEFINE:
case UNDEF:
case INCLUDE:
case INCLUDEDOT:
break;
case -1:
log("%s, line %d: unknown directive == \"%s\"\n",
file_red->i_file, filep->f_line, line);
break;
}
}
return(-1);
}
/*
* Decide what type of # directive this line is.
*/
deftype(line, filep, file_red, file, parse_it)
register char *line;
register struct filepointer *filep;
register struct inclist *file_red, *file;
int parse_it;
{
register char *p;
char *directive, savechar;
register int ret;
/*
* Parse the directive...
*/
directive=line+1;
while (*directive == ' ' || *directive == '\t')
directive++;
p = directive;
while (*p >= 'a' && *p <= 'z')
p++;
savechar = *p;
*p = '\0';
ret = match(directive, directives);
*p = savechar;
/*
* If we don't recognize this compiler directive or we happen
* to just be gobbling up text while waiting for an #endif or
* a #else, then we don't need to parse this line.
*/
if (ret < 0 || ! parse_it)
return(ret);
/*
* now decide how to parse the directive, and do it.
*/
while (*p == ' ' || *p == '\t')
p++;
switch (ret) {
case IF:
/*
* parse an expression.
*/
debug0("%s, line %d: #if %s\n",
file->i_file, filep->f_line, p);
if (zero_value(p, filep, file_red))
ret = IFFALSE;
break;
case IFDEF:
case IFNDEF:
debug0("%s, line %d: #%s %s\n",
file->i_file, filep->f_line, directives[ret], p);
case UNDEF:
/*
* separate the name of a single symbol.
*/
while (isalnum(*p) || *p == '_')
*line++ = *p++;
*line = '\0';
break;
case INCLUDE:
debug2("%s, line %d: #include %s\n",
file->i_file, filep->f_line, p);
/*
* Separate the name of the include file.
*/
while (*p && *p != '"' && *p != '<')
p++;
if (! *p)
return(-2);
if (*p++ == '"') {
ret = INCLUDEDOT;
while (*p && *p != '"')
*line++ = *p++;
} else
while (*p && *p != '>')
*line++ = *p++;
*line = '\0';
break;
case DEFINE:
/*
* copy the definition back to the beginning of the line.
*/
strcpy (line, p);
break;
case ELSE:
case ENDIF:
debug0("%s, line %d: #%s\n",
file->i_file, filep->f_line, directives[ret]);
/*
* nothing to do.
*/
break;
}
return(ret);
}
struct symtab *defined(symbol, file)
register char *symbol;
struct inclist *file;
{
register struct symtab *val;
if (val = slookup(symbol, deflist)) {
debug1("%s defined on command line\n", symbol);
return(val);
}
if (val = fdefined(symbol, file))
return(val);
debug1("%s not defined in %s\n", symbol, file->i_file);
return(NULL);
}
struct symtab *fdefined(symbol, file)
register char *symbol;
struct inclist *file;
{
register struct inclist **ip;
register struct symtab *val;
register int i;
static int recurse_lvl = 0;
if (file->i_defchecked)
return(NULL);
file->i_defchecked = TRUE;
if (val = slookup(symbol, file->i_defs))
debug1("%s defined in %s\n", symbol, file->i_file);
if (val == NULL && file->i_list)
for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++)
if (val = fdefined(symbol, *ip)) {
debug1("%s defined in %s\n",
symbol, (*ip)->i_file);
break;
}
recurse_lvl--;
file->i_defchecked = FALSE;
return(val);
}
struct symtab *slookup(symbol, stab)
register char *symbol;
register struct symtab *stab;
{
if (stab)
for (; stab->s_name; stab++)
if (strcmp(symbol, stab->s_name) == 0)
return(stab);
return(NULL);
}
/*
* Return true if the #if expression evaluates to 0
*/
zero_value(exp, filep, file_red)
register char *exp;
register struct filepointer *filep;
register struct inclist *file_red;
{
#ifdef CPP
return (cppsetup(exp, filep, file_red) == 0);
#else CPP
return(TRUE);
#endif CPP
}
define(def, file)
register char *def;
register struct inclist *file;
{
register char *p;
struct symtab *sp = file->i_lastdef++;
register int i;
/*
* If we are out of space, allocate some more.
*/
if (file->i_defs == NULL
|| file->i_lastdef == file->i_defs + file->i_deflen) {
if (file->i_defs)
file->i_defs = (struct symtab *) realloc(file->i_defs,
sizeof(struct symtab)*(file->i_deflen+SYMTABINC));
else
file->i_defs = (struct symtab *)
malloc(sizeof (struct symtab) * SYMTABINC);
i=file->i_deflen;
file->i_deflen += SYMTABINC;
while (i < file->i_deflen)
file->i_defs[ i++ ].s_name = NULL;
file->i_lastdef = file->i_defs + file->i_deflen - SYMTABINC;
if (sp) /* be sure we use last cell in previous group */
file->i_lastdef--;
sp = file->i_lastdef++;
}
else if (file->i_lastdef > file->i_defs + file->i_deflen)
log_fatal("define() botch\n");
/*
* copy the symbol being defined.
*/
p = def;
while (isalnum(*p) || *p == '_')
p++;
if (*p)
*p++ = '\0';
sp->s_name = copy(def);
/*
* And copy its value.
*/
while (*p == ' ' && *p == '\t')
p++;
sp->s_value = copy(p);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.