home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
PAMAKE18.ZIP
/
INPUT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-08-31
|
12KB
|
431 lines
/*************************************************************************
| |
| INPUT.C 31.08.89 |
| PAMAKE Utility: parse a makefile |
| |
*************************************************************************/
#ifdef VMS
#include stdio
#include string
#include stdlib
#include ctype
#include "h.h"
#else
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "h.h"
#endif
struct name namehead;
struct name * firstname;
char str1[LZ]; /* general store */
char str2[LZ];
/***** intern a name - return a pointer to the name struct */
struct name *
newname(name)
char * name;
{
struct name * rp;
struct name * rrp;
char * cp;
register int i;
register char * q;
static char namerr[] = {"Cannot allocate memory for name"};
for
(
rp = namehead.n_next, rrp = &namehead;
rp;
rp = rp->n_next, rrp = rrp->n_next
)
{
i = 0;
q = rp->n_name;
while (name[i] == *(q+i))
if (name[i++] == '\0') return rp;
}
if ((rp = (struct name *)malloc(sizeof(struct name))) == (struct name *)0)
fatal(namerr);
rrp->n_next = rp;
rp->n_next = (struct name *)0;
if ((cp = malloc(strlen(name)+1)) == (char *)0) fatal(namerr);
strcpy(cp, name);
rp->n_name = cp;
rp->n_line = (struct line *)0;
rp->n_time = (long)0;
rp->n_flag = 0;
return rp;
}
/***** add a dependant to the end of the supplied list of dependants */
/***** return the new head pointer for that list */
struct depend *
newdep(np, dp)
struct name * np;
struct depend * dp;
{
register struct depend *rp;
register struct depend *rrp;
static char deperr[] = {"Cannot allocate memory for dependant"};
if ((rp = (struct depend *)malloc(sizeof(struct depend)))
== (struct depend *)0)
fatal(deperr);
rp->d_next = (struct depend *)0;
rp->d_name = np;
if (dp == (struct depend *)0)
return rp;
for (rrp = dp; rrp->d_next; rrp = rrp->d_next)
;
rrp->d_next = rp;
return dp;
}
/***** add a command to the end of the supplied list of commands */
/***** return the new head pointer for that list, and save the */
/***** actual command structure created in case lif lines are found */
struct cmd *
newcmd(str, cp, crp)
char * str;
struct cmd * cp;
struct cmd * * crp;
{
register struct cmd * rp;
register struct cmd * rrp;
register char * rcp;
static char comerr[] = {"Cannot allocate memory for command"};
if ((rcp = strrchr(str, '\n')) != (char *)0) *rcp = '\0'; /* lose nl */
while (pspace(*str)) str++;
if (*str == '\0') /* if nothing left, then exit */
{
*crp = (struct cmd *)0;
return cp;
}
if ((rp = (struct cmd *)malloc(sizeof(struct cmd))) == (struct cmd *)0)
fatal(comerr);
rp->c_next = (struct cmd *)0;
if ((rcp = malloc(strlen(str)+1)) == (char *)0) fatal(comerr);
strcpy(rcp, str);
rp->c_cmd = rcp;
rp->c_lif = (struct lif *)0;
*crp = rp;
if (cp == (struct cmd *)0) return rp;
for (rrp = cp; rrp->c_next; rrp = rrp->c_next)
;
rrp->c_next = rp;
return cp;
}
/***** add a lif line to the end of the supplied list of lif lines */
/***** return the new head pointer for that list */
struct lif *
newlif(str, lp)
char * str;
struct lif * lp;
{
register struct lif * rp;
register struct lif * rrp;
register char * rlp;
static char liferr[] = {"Cannot allocate memory for local input file"};
if ((rlp = strrchr(str, '\n')) != (char *)0) *rlp = '\0'; /* lose nl */
if (*str == '\0') return lp; /* if nothing left, then exit */
if ((rp = (struct lif *)malloc(sizeof(struct lif))) == (struct lif *)0)
fatal(liferr);
rp->f_next = (struct lif *)0;
if ((rlp = malloc(strlen(str)+1)) == (char *)0) fatal(liferr);
strcpy(rlp, str);
rp->f_lif = rlp;
if (lp == (struct lif *)0) return rp;
for (rrp = lp; rrp->f_next; rrp = rrp->f_next)
;
rrp->f_next = rp;
return lp;
}
/***** add a new 'line' of stuff to a target */
/***** check to see if commands already exist for the target */
void
newline(np, dp, cp, flag)
struct name * np;
struct depend * dp;
struct cmd * cp;
int flag;
{
bool hascmds = FALSE; /* Target has commands */
register struct line * rp;
register struct line * rrp;
static char linerr[] = {"Cannot allocate memory for line"};
if ( (!dp && !cp && !strcmp(np->n_name,".SUFFIXES")))
{
for (rp = np->n_line; rp; rp = rrp)
{
rrp = rp->l_next;
free(rp);
}
np->n_line = (struct line *)0;
np->n_flag &= ~N_TARG;
return;
}
for
(
rp = np->n_line, rrp = (struct line *)0;
rp;
rrp = rp, rp = rp->l_next
)
if (rp->l_cmd)
hascmds = TRUE;
/***** handle the implicit rules redefinition case */
if (hascmds && cp && !(np->n_flag & N_DOUBLE))
if (np->n_name[0] == '.' && dp == (struct depend *)0)
{
np->n_line->l_cmd = cp;
return;
}
else
error("Multiple sets of commands for target %s", np->n_name);
if (np->n_flag & N_TARG)
if (!(np->n_flag & N_DOUBLE) != !flag) /* like xor */
error("Inconsistent rules for target %s", np->n_name);
if ((rp = (struct line *)malloc(sizeof (struct line)))
== (struct line *)0)
fatal(linerr);
rp->l_next = (struct line *)0;
rp->l_dep = dp;
rp->l_cmd = cp;
if (rrp)
rrp->l_next = rp;
else
np->n_line = rp;
np->n_flag |= N_TARG;
if (flag)
np->n_flag |= N_DOUBLE;
}
/***** check for the presence of a local input file */
void
checklif(cp)
struct cmd * cp;
{
register struct lif * lp;
lp = (struct lif *)0;
if (pstrstr(str2,"$-")) /* lif follows */
{
for (;;)
{
if (getline(str2))
fatal("Unterminated local input file");
if (str2[0] == '<') break;
lp = newlif(&str2[0],lp);
}
}
if (cp) cp->c_lif = lp;
}
/* expand $* in dependencies, by creating a new dep for each */
void
expast(struct name * np)
{
register struct depend *dp;
register struct line * lp;
struct name * nnp;
struct depend * * dpp;
char * p;
char * q;
char * r;
char * rr;
char * suff;
char expb[64];
static char experr[] = {"Unable to expand $*"};
for (lp = np->n_line; lp; lp = lp->l_next)
{
for (dp = lp->l_dep; dp; dp = dp->d_next)
{
rr = (char *)0;
p = r = dp->d_name->n_name;
while (*p)
{
if ( ((*p & 0xff) == 0244) && ((*(p + 1) & 0xff) == 0244) )
{
rr = p;
break;
}
p++;
}
if (rr != (char *)0)
{
q = np->n_name; /* get target name */
if ((strlen(q) + strlen(r)) > 60) fatal(experr);
p = expb;
while (r < rr) *p++ = *r++;
suff = suffix(q);
while (q < suff) *p++ = *q++;
r += 2; /* skip special marker */
while (*r) *p++ = *r++;
*p = '\0';
nnp = newname(expb); /* make a new dependent */
for (dpp = &(lp->l_dep); *dpp; dpp = &((*dpp)->d_next))
{
if (*dpp == dp)
{
*dpp = (struct depend *)malloc(sizeof(struct depend));
if (*dpp == (struct depend *)0) fatal(experr);
(*dpp)->d_next = dp->d_next;
(*dpp)->d_name = nnp;
}
}
}
}
}
}
/***** parse input from the makefile, and construct a tree structure of it */
void
input()
{
char * p; /* General */
char * q;
struct name * np;
struct depend * dp;
struct cmd * cp;
struct cmd * crp;
bool dbl;
if (getline(str1)) return; /* read the first line */
setmacro("*","\244\244"); /* special marker for $* */
for(;;)
{
if (*str1 == '\t') /* rules without targets */
error("Command found with no target/dependancy line");
p = str1;
while (pspace(*p)) p++; /* find first target */
while (((q = strchr(p, '=')) != (char *)0) &&
(p != q) && (q[-1] == '\\')) /* Find value */
{
register char * a;
a = q - 1; /* del \ chr; move rest back */
p = q;
while ((*a++ = *q++) != '\0')
;
}
if (q != (char *)0)
{
register char * a;
*q++ = '\0'; /* separate name and val */
while (pspace(*q)) q++;
if ((p = strrchr(q, '\n')) != (char *)0) *p = '\0';
p = str1;
if ((a = gettok(&p)) == (char *)0)
error("Macro definition without macro name");
setmacro(a, q);
if (getline(str1)) return;
continue;
}
expand(str1);
p = str1;
while (((q = strchr(p, ':')) != (char *)0) &&
(p != q) && (q[-1] == '\\')) /* Find dependents */
{
register char * a;
a = q - 1; /* del \ chr; move rest back */
p = q;
while ((*a++ = *q++) != '\0')
;
}
if (q == (char *)0) error("Cannot find any targets");
*q++ = '\0'; /* separate targets and dependents */
if (*q == ':') /* double colon */
{
dbl = 1;
q++;
}
else
dbl = 0;
for (dp = (struct depend *)0; ((p = gettok(&q)) != (char *)0);)
{ /* get list of dep's */
np = newname(p); /* intern name */
dp = newdep(np, dp); /* add to dep list */
}
*((q = str1) + strlen(str1) + 1) = '\0'; /* two nulls for gettok */
cp = (struct cmd *)0;
if (getline(str2) == FALSE) /* get commands */
{
while (*str2 == '\t')
{
cp = newcmd(&str2[0], cp, &crp);
checklif(crp);
if (getline(str2)) break;
}
}
while ((p = gettok(&q)) != (char *)0) /* get list of targ's */
{
np = newname(p); /* intern name */
newline(np, dp, cp, dbl);
expast(np); /* expand $* in dep */
if (!firstname && p[0] != '.') firstname = np;
}
if (nestlvl < 0) return; /* eof? */
strcpy(str1, str2);
}
}