void MacUndef (const StrBuf* Name, unsigned char Style) /* Undefine the macro with the given name and style. A style mismatch is * treated as if the macro didn't exist. */ { /* Search for the macro */ Macro* M = HT_Find (&MacroTab, Name); /* Don't let the user kid with us */ if (M == 0 || M->Style != Style) { Error ("No such macro: %m%p", Name); return; } if (M->Expansions > 0) { Error ("Cannot delete a macro that is currently expanded"); return; } /* Remove the macro from the macro table */ HT_Remove (&MacroTab, M); /* Free the macro structure */ FreeMacro (M); }
/************************************************************************** * * GetMakeMacros * * SYNOPSIS * LST_LIST *GetMakeMacros (char *filename) * * PURPOSE * Parse a make file and gather it's macros and their tokens into * lists. * * INPUT * * * EFFECTS * * * RETURN VALUE * * * BUGS * * * HISTORY * * * SEE ALSO * */ LST_LIST *GetMakeMacros (char *filename) { FILE *fp; LST_LIST *mlist; MakeMacro *macro; MakeMacro *sub; MakeMacro *oldmac; NameType *name; NameType *last; int status; int cont; int len; int error = FALSE; char linebuff[MAXLINE]; char macroId[MAXLINE]; char *line; char *s; char *w; char c; fp = fopen (filename, "r"); if (!fp) { SetGlobalErr (ERR_FILE_NOT_FOUND); GEprintf1 ("Couldn't open file '%s' as makefile", filename); return NULL; } mlist = LST_CreateList (NULL); if (!mlist) { SetGlobalErr (ERR_OUT_OF_MEMORY); GEprintf ("OOM: allocating macro list"); return NULL; } CurrentType = 1; IgnoreSlash = TRUE; LineFunc = GetNextEnv; LineNumber = 0; while ((status = LineFunc (fp, linebuff)) > 0) { line = TrimWhiteSpace (linebuff); len = strlen (line); s = macroId; cont = FALSE; if (len && *line != '#') { while (*line && (isalnum(*line) || *line == '_')) { *s++ = *line++; } *s = '\0'; while (*line && isspace(*line)) { line++; } if (*line == '=') { line++; strupr (macroId); oldmac = (MakeMacro*)LST_FindName (mlist, macroId); if (oldmac) { if (oldmac->EnvFlag) { LST_Remove (oldmac); FreeMacro (oldmac); } else { printf ("ERROR:Duplicate Macro '%s' at line %d\n", macroId, LineNumber); error = TRUE; } } macro = (MakeMacro*)LST_CreateNode (sizeof (MakeMacro), macroId); if (!macro) { SetGlobalErr (ERR_OUT_OF_MEMORY); GEprintf ("OOM: macro\n"); return NULL; } macro->EnvFlag = CurrentType; LST_InitList (¯o->Names); LST_AddTail (mlist, macro); last = NULL; s = strtok (line, " \t"); if (s) { do { s = TrimWhiteSpace (s); len = strlen (s); if (len && s[len - 1] == '\\' && !IgnoreSlash) { len--; s[len] = '\0'; cont = TRUE; } if (len) { while (*s) { w = s; while (*s && !(*s == '$' && s[1] == '(')) { s++; } c = *s; *s = 0; if (strlen (w)) { name = (NameType*)LST_CreateNode (sizeof (NameType), w); if (!name) { SetGlobalErr (ERR_OUT_OF_MEMORY); GEprintf ("OOM: (2) finishing macro substitution"); return NULL; } LST_AddTail (¯o->Names, name); } *s = c; if (*s == '$' && s[1] == '(') { s += 2; w = s; s = strchr (s, ')'); if (!s) { printf ("ERROR:Macro missing ')' at line %d\n", LineNumber); error = TRUE; } else { *s = 0; s++; strupr (w); sub = (MakeMacro*)LST_FindName (mlist, w); if (!sub) { printf ("Undefined macro '%s' in line %d\n", w, LineNumber); error = TRUE; } else { name = (NameType*)LST_CreateNode (sizeof (NameType), NULL); if (!name) { SetGlobalErr (ERR_OUT_OF_MEMORY); GEprintf ("OOM: (4) finishing macro substitution"); return NULL; } name->Macro = sub; LST_AddTail (¯o->Names, name); } } } } name = (NameType*)LST_CreateNode (sizeof (NameType), NULL); if (!name) { SetGlobalErr (ERR_OUT_OF_MEMORY); GEprintf ("OOM: (6) adding delimiter"); return NULL; } name->Delim = TRUE; last = name; LST_AddTail (¯o->Names, name); } s = strtok (NULL, " \t"); if (!s && cont) { do { status = LineFunc (fp, linebuff); } while (status > 0 && *linebuff == '#'); if (status == 0) { SetGlobalErr (ERR_GENERIC); GEprintf ("EOF: unterminated macro"); return NULL; } else if (status < 0) { SetGlobalErr (ERR_GENERIC); GEprintf1 ("I/O ERROR: reading file '%s'", filename); return NULL; } line = TrimWhiteSpace (linebuff); s = strtok (line, " \t"); } cont = FALSE; } while (s); if (last && last->Delim) { LST_Remove (last); LST_DeleteNode (last); } } } } } /** Exit if error **/ if (status || error) { return NULL; } return mlist; } /* GetMakeMacros */