From 5682d91f286aacbe0b26e0dab03e8d413a450461 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 31 Mar 1997 14:13:21 +0000 Subject: [PATCH] Initial revision CVS patchset: 1509 CVS date: 1997/03/31 14:13:21 --- build/macro.c | 295 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ build/macro.h | 8 ++ 2 files changed, 303 insertions(+) create mode 100644 build/macro.c create mode 100644 build/macro.h diff --git a/build/macro.c b/build/macro.c new file mode 100644 index 0000000..f080920 --- /dev/null +++ b/build/macro.c @@ -0,0 +1,295 @@ +/* macro.c - %macro handling */ + +#include +#include +#include +#include "macro.h" + +#ifdef DEBUG +#include +#define rpmError fprintf +#define RPMERR_BADSPEC stderr +static void dumpTable(void); +#else +#include "rpmlib.h" +#endif + +static void expandMacroTable(void); +static int compareMacros(const void *ap, const void *bp); +static struct macroEntry *findEntry(char *name); +static int handleDefine(char *buf); +static int parseMacro(char *p, char **macro, char **next); + +/* This should be a hash table, but I doubt anyone will ever notice */ + +#define MACRO_CHUNK_SIZE 16 + +struct macroEntry { + char *name; + char *expansion; +}; + +static struct macroEntry *macroTable = NULL; +static int macrosAllocated = 0; +static int firstFree = 0; + +/*************************************************************************/ +/* */ +/* Parsing routines */ +/* */ +/*************************************************************************/ + +int expandMacros(char *buf) +{ + char bufA[1024]; + char *copyTo, *copyFrom; + char *name, *rest; + struct macroEntry *p; + + if (! buf) { + return 0; + } + + copyFrom = buf; + copyTo = bufA; + + while (*copyFrom) { + if (*copyFrom != '%') { + *copyTo++ = *copyFrom++; + } else { + if (parseMacro(copyFrom+1, &name, &rest)) { + return 1; + } + if (!strcasecmp(name, "define")) { + if (handleDefine(rest)) { + return 1; + } + /* result is empty */ + *buf = '\0'; + return 0; + } + if (!strcmp(name, "%")) { + *copyTo++ = '%'; + copyFrom = rest; + } else { + /* a real live macro! */ + p = findEntry(name); + if (! p) { + /* undefined - just leave it */ + *copyTo++ = '%'; + copyFrom = name; + } else { + copyFrom = p->expansion; + } + while (*copyFrom) { + *copyTo++ = *copyFrom++; + } + copyFrom = rest; + } + } + } + *copyTo = '\0'; + strcpy(buf, bufA); + return 0; +} + +static int parseMacro(char *p, char **macro, char **next) +{ + /* This static var is gross, but we can get away with it */ + /* because the result is used immediately, even when we */ + /* are recursing. */ + + static char macroBuf[1024]; + char save; + + /* Find end of macro, handling %{...} construct */ + + if (! p) { + /* empty macro name */ + rpmError(RPMERR_BADSPEC, "Empty macro name\n"); + return 2; + } + + if (*p == '{') { + *next = index(p, '}'); + if (! *next) { + /* unterminated */ + rpmError(RPMERR_BADSPEC, "Unterminated {: %s\n", p); + return 1; + } + **next = '\0'; + *macro = strtok(p+1, " \n\t"); + if (! *macro) { + /* empty macro name */ + rpmError(RPMERR_BADSPEC, "Empty macro name\n"); + return 2; + } + (*next)++; + return 0; + } + + if (*p == '%') { + *next = p + 1; + *macro = "%"; + return 0; + } + + if (isspace(*p) || ! *p) { + /* illegal % syntax */ + rpmError(RPMERR_BADSPEC, "Illegal %% syntax: %s\n", p); + return 3; + } + + *next = *macro = p; + while (**next && (isalnum(**next) || **next == '_')) { + (*next)++; + } + if (! **next) { + return 0; + } + save = **next; + **next = '\0'; + strcpy(macroBuf, *macro); + **next = save; + *macro = macroBuf; + return 0; +} + +static int handleDefine(char *buf) +{ + char *last, *name, *expansion; + + /* get the name */ + + name = buf; + while (*name && isspace(*name)) { + name++; + } + if (! *name) { + /* missing macro name */ + rpmError(RPMERR_BADSPEC, "Unfinished %%define\n"); + return 1; + } + expansion = name; + while (*expansion && !isspace(*expansion)) { + expansion++; + } + if (*expansion) { + *expansion++ = '\0'; + } + + /* get the expansion */ + + while (*expansion && isspace(*expansion)) { + expansion++; + } + if (*expansion) { + /* strip blanks from end */ + last = expansion + strlen(expansion) - 1; + while (isspace(*last)) { + *last-- = '\0'; + } + } + + expandMacros(expansion); + addMacro(name, expansion); + + return 0; +} + +#ifdef DEBUG +static void dumpTable() +{ + int i; + + for (i = 0; i < firstFree; i++) { + printf("%s->%s.\n", macroTable[i].name, + macroTable[i].expansion); + } +} + +void main(void) +{ + char buf[1024]; + int x; + + while(gets(buf)) { + x = expandMacros(buf); + printf("%d->%s<-\n", x, buf); + } +} +#endif + +/*************************************************************************/ +/* */ +/* Table handling routines */ +/* */ +/*************************************************************************/ + +void resetMacros(void) +{ + int i; + + if (! macrosAllocated) { + expandMacroTable(); + return; + } + + for (i = 0; i < firstFree; i++) { + free(macroTable[i].name); + free(macroTable[i].expansion); + } +} + +void addMacro(char *name, char *expansion) +{ + struct macroEntry *p; + + p = findEntry(name); + if (p) { + free(p->expansion); + p->expansion = strdup(expansion); + return; + } + + if (firstFree == macrosAllocated) { + expandMacroTable(); + } + + p = macroTable + firstFree++; + p->name = strdup(name); + p->expansion = strdup(expansion); + + qsort(macroTable, firstFree, sizeof(*macroTable), compareMacros); +} + +static struct macroEntry *findEntry(char *name) +{ + struct macroEntry key; + + if (! firstFree) { + return NULL; + } + + key.name = name; + return bsearch(&key, macroTable, firstFree, + sizeof(*macroTable), compareMacros); +} + +static int compareMacros(const void *ap, const void *bp) +{ + return strcasecmp(((struct macroEntry *)ap)->name, + ((struct macroEntry *)bp)->name); +} + +static void expandMacroTable() +{ + macrosAllocated += MACRO_CHUNK_SIZE; + if (! macrosAllocated) { + macroTable = malloc(sizeof(*macroTable) * macrosAllocated); + firstFree = 0; + } else { + macroTable = realloc(macroTable, + sizeof(*macroTable) * macrosAllocated); + } +} diff --git a/build/macro.h b/build/macro.h new file mode 100644 index 0000000..ad9b352 --- /dev/null +++ b/build/macro.h @@ -0,0 +1,8 @@ +/* macro.h - %macro handling */ + +void resetMacros(void); + +void addMacro(char *name, char *expansion); + +/* Expand all macros in buf, in place */ +int expandMacros(char *buf); -- 2.7.4