#include #include "make.h" /* * Macro processing */ /* * Perform macro substitution from 'orig' to 'dest'. * Return number of macro substitutions made. * A macro reference is in one of two forms: * (macro-name) * or * * "" expands to a single '' */ mexpand (orig, dest, destsiz, macchar) char *orig; char *dest; int destsiz; char macchar; { register char *s; register char *d; auto char mname[STRSIZ]; register int di; register int count; /* MACRO *m; */ DBUG_ENTER ("mexpand"); di = count = 0; for (s = orig; *s;) { if (*s == macchar) { if (*++s == macchar) { if (di < destsiz - 1) { dest[di++] = *s++; } continue; } if (!*s) { break; } d = mname; if (*s != '(') { *d++ = *s++; } else { for (++s; *s && *s != ')';) { *d++ = *s++; } if (*s != ')') { puts ("Missed matching ')'"); } else { ++s; } } *d = 0; if ((d = gmacro (mname)) == NULL) { #ifdef VAXVMS || MSDOS /* Preserve old behavior. Someone else can remove it */ /* if desired. The prefered behavior, at least for */ /* unix types, is to simply ignore undefined macros. */ /* Fred Fish, 28-Nov-85 */ fputs ("Undefined macro: ", stderr); fputs (mname, stderr); fputc ('\n', stderr); #endif } else { while (*d && di < (destsiz - 1)) { dest[di++] = *d++; } ++count; } } else if (di < destsiz - 1) { dest[di++] = *s++; } } dest[di] = 0; DBUG_3 ("mac", "expanded %d macros", count); DBUG_RETURN (count); } /* * Define a macro. * Give the macro called 'name' the string expansion 'def'. * Old macro-names are superseded, NOT replaced. */ void defmac (name, def) char *name; char *def; { register MACRO *m; DBUG_ENTER ("defmac"); DBUG_4 ("mdef", "define macro '%s' to be '%s'", name, def); if ((m = (MACRO *) Calloc (1, sizeof (MACRO))) == (MACRO *) NULL) { allerr (); } if ((m -> mname = (char *) Calloc (1, strlen (name) + 1)) == NULL) { allerr (); } if ((m -> mvalue = (char *) Calloc (1, strlen (def) + 1)) == NULL) { allerr (); } strcpy (m -> mname, name); strcpy (m -> mvalue, def); m -> mnext = mroot; mroot = m; DBUG_VOID_RETURN; } /* * undefmac - undefine a macro. * Return 0 if macro was successfully undefined, -1 if not found. */ int undefmac (name) char *name; { register MACRO *m = mroot; register MACRO *prev = (MACRO *) NULL; int result = -1; extern void free (); DBUG_ENTER ("undefmac"); DBUG_3 ("mundef", "undefine macro '%s'", name); while (m != (MACRO *) NULL && !STRSAME (name, m -> mname)) { prev = m; m = m -> mnext; } if (m != (MACRO *) NULL) { result = 0; if (prev == (MACRO *) NULL) { mroot = m -> mnext; } else { prev -> mnext = m -> mnext; } free (m -> mname); free (m -> mvalue); free (m); } DBUG_RETURN (result); } /* * Lookup a macro called 'name'. * Return a pointer to its definition, * or NULL if it does not exist. */ char *gmacro (name) char *name; { register MACRO *m; register char *def = NULL; DBUG_ENTER ("gmacro"); DBUG_3 ("mname", "look up macro '%s'", name); for (m = mroot; m != (MACRO *) NULL; m = m -> mnext) { if (STRSAME (name, m -> mname)) { def = m -> mvalue; DBUG_3 ("mexp", "found expansion '%s'", def); break; } } DBUG_RETURN (def); }