minix/commands/make/macro.c
2005-04-21 14:53:53 +00:00

198 lines
4.1 KiB
C
Executable file

/*************************************************************************
*
* m a k e : m a c r o . c
*
* Macro control for make
*========================================================================
* Edition history
*
* # Date Comments By
* --- -------- ---------------------------------------------------- ---
* 1 ?? ??
* 2 23.08.89 Error message corrected RAL
* 3 30.08.89 macro flags added, indention ch. PSH,RAL
* 4 03.09.89 fixed LZ eliminated, doexp(...) changed RAL
* 5 06.09.89 M_MAKE added, setDFmacro added RAL
* 6 20.09.89 work around for Minix PC ACK bug BE,RAL
* ------------ Version 2.0 released ------------------------------- RAL
*
*************************************************************************/
#include "h.h"
static char buf[256];
struct macro *getmp(name)
char *name;
{
register struct macro *rp;
for (rp = macrohead; rp; rp = rp->m_next)
if (strcmp(name, rp->m_name) == 0)
return rp;
return (struct macro *)0;
}
char *getmacro(name)
char *name;
{
struct macro *mp;
if (mp = getmp(name))
return mp->m_val;
/* else*/
return "";
}
struct macro *setmacro(name, val)
char *name;
char *val;
{
register struct macro *rp;
register char *cp;
/* Replace macro definition if it exists */
for (rp = macrohead; rp; rp = rp->m_next)
if (strcmp(name, rp->m_name) == 0) {
if(rp->m_flag & M_OVERRIDE) return rp; /* mustn't change */
free(rp->m_val); /* Free space from old */
break;
}
if (!rp) /* If not defined, allocate space for new */
{
if ((rp = (struct macro *)malloc(sizeof (struct macro)))
== (struct macro *)0)
fatal("No memory for macro",(char *)0,0);
rp->m_next = macrohead;
macrohead = rp;
rp->m_flag = FALSE;
if ((cp = (char *) malloc(strlen(name)+1)) == (char *)0)
fatal("No memory for macro",(char *)0,0);
strcpy(cp, name);
rp->m_name = cp;
}
if ((cp = (char *) malloc(strlen(val)+1)) == (char *)0)
fatal("No memory for macro",(char *)0,0);
strcpy(cp, val); /* Copy in new value */
rp->m_val = cp;
return rp;
}
void setDFmacro(name, val)
char *name;
char *val;
{
char *c,*tmp;
int len;
static char filename[]="@F";
static char dirname[] ="@D";
setmacro(name,val);
*filename = *name;
*dirname = *name;
/* Null string -- not defined macro */
if ( !(*val)) {
setmacro(filename,"");
setmacro(dirname,"");
return;
}
if (!(c = strrchr(val,(int)'/'))) {
setmacro(filename,val);
setmacro(dirname,"./");
return;
}
setmacro(filename,c+1);
len = c - val + 1;
if((tmp = (char *) malloc(len + 1)) == (char *) 0)
fatal("No memory for tmp",(char *)0,0);
strncpy(tmp,val,len);
tmp[len] = '\0';
setmacro(dirname,tmp);
free(tmp);
return;
}
/*
* Do the dirty work for expand
*/
void doexp(to, from)
struct str *to;
char *from;
{
register char *rp;
register char *p;
char *q;
struct macro *mp;
rp = from;
p = &(*to->ptr)[to->pos];
while (*rp) {
if (*rp != '$') {
*p++ = *rp++;
to->pos++;
}
else {
q = buf;
if (*++rp == '{')
while (*++rp && *rp != '}')
*q++ = *rp;
else if (*rp == '(')
while (*++rp && *rp != ')')
*q++ = *rp;
else if (!*rp) {
*p++ = '$';
to->pos++;
goto bail;
}
else
*q++ = *rp;
*q = '\0';
if (*rp)
rp++;
if (!(mp = getmp(buf)))
mp = setmacro(buf, "");
if (mp->m_flag & M_MARK)
fatal("Infinitely recursive macro %s", mp->m_name,0);
mp->m_flag |= M_MARK;
if ( mp->m_flag & M_MAKE) expmake = TRUE;
doexp(to, mp->m_val);
p = &(*to->ptr)[to->pos];
mp->m_flag &= ~M_MARK;
}
bail:
if (to->pos >= to->len) {
strrealloc(to);
p = &(*to->ptr)[to->pos];
}
}
*p = '\0';
}
/*
* Expand any macros in str.
*/
void expand(strs)
struct str *strs;
{
char *a;
if ((a = (char *) malloc(strlen(*strs->ptr)+1)) == (char *)0)
fatal("No memory for temporary string",(char *)0,0);
strcpy(a, *strs->ptr);
strs->pos = 0;
doexp(strs, a);
free(a);
}