--- rpm-4.5/rpmio/macro.c.org 2009-08-08 15:42:25.574860247 +0200 +++ rpm-4.5/rpmio/macro.c 2009-08-08 15:47:20.495455961 +0200 @@ -807,6 +807,41 @@ return se; } +/** + * Parse (and execute) macro undefinition. + * @param mc macro context + * @param se macro name to undefine + * @return address to continue parsing + */ +/*@dependent@*/ static const char * +doUnglobal(MacroContext mc, /*@returned@*/ const char * se) + /*@globals rpmGlobalMacroContext @*/ + /*@modifies mc, rpmGlobalMacroContext @*/ +{ + const char *s = se; + char *buf = alloca(_macro_BUFSIZ); + char *n = buf, *ne = n; + int c; + + COPYNAME(ne, s, c); + + /* Move scan over body */ + while (iseol(*s)) + s++; + se = s; + + /* Names must start with alphabetic or _ and be at least 3 chars */ + if (!((c = *n) && (xisalpha(c) || c == '_') && (ne - n) > 2)) { + rpmlog(RPMLOG_ERR, + _("Macro %%%s has illegal name (%%unglobal)\n"), n); + return se; + } + + delMacroAll(mc, n); + + return se; +} + #ifdef DYING static void dumpME(const char * msg, MacroEntry me) @@ -1430,6 +1465,10 @@ s = doUndefine(mb->mc, se); continue; } + if (STREQ("unglobal", f, fn)) { + s = doUnglobal(mb->mc, se); + continue; + } if (STREQ("echo", f, fn) || STREQ("warn", f, fn) || @@ -1984,6 +2023,18 @@ } } +void +delMacroAll(MacroContext mc, const char * n) +{ + MacroEntry * mep; + + if (mc == NULL) mc = rpmGlobalMacroContext; + /* If name exists, pop entry */ + while ((mep = findEntry(mc, n, 0)) != NULL) { + delMacro(mc, n); + } +} + /*@-mustmod@*/ /* LCL: mc is modified through mb->mc, mb is abstract */ int rpmDefineMacro(MacroContext mc, const char * macro, int level)