diff options
Diffstat (limited to 'build/parseSpec.c')
-rw-r--r-- | build/parseSpec.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/build/parseSpec.c b/build/parseSpec.c new file mode 100644 index 000000000..a3badbb18 --- /dev/null +++ b/build/parseSpec.c @@ -0,0 +1,186 @@ +#include <ctype.h> +#include <unistd.h> +#include <string.h> +#include <malloc.h> + +#include "header.h" +#include "rpmlib.h" +#include "part.h" +#include "spec.h" +#include "parse.h" +#include "read.h" +#include "misc.h" + +static void setStandardMacros(Spec spec, char *arch, char *os); + +int parseSpec(Spec *specp, char *specFile, char *buildRoot, + int inBuildArch, char *passPhrase, char *cookie) +{ + int parsePart = PART_PREAMBLE; + int initialPackage = 1; + char *name, *arch, *os; + Package pkg; + int x, index; + Spec spec; + + /* Set up a new Spec structure with no packages. */ + spec = newSpec(); + + spec->specFile = strdup(specFile); + if (buildRoot) { + spec->gotBuildRoot = 1; + spec->buildRoot = strdup(buildRoot); + } + spec->docDir = strdup(rpmGetVar(RPMVAR_DEFAULTDOCDIR)); + spec->inBuildArchitectures = inBuildArch; + if (passPhrase) { + spec->passPhrase = strdup(passPhrase); + } + if (cookie) { + spec->cookie = strdup(cookie); + } + + if (rpmGetVar(RPMVAR_TIMECHECK)) { + if (parseNum(rpmGetVar(RPMVAR_TIMECHECK), &(spec->timeCheck))) { + rpmError(RPMERR_BADSPEC, "Timecheck value must be an integer: %s", + rpmGetVar(RPMVAR_TIMECHECK)); + freeSpec(spec); + return RPMERR_BADSPEC; + } + } else { + spec->timeCheck = 0; + } + + /* Add some standard macros */ + rpmGetArchInfo(&arch, NULL); + rpmGetOsInfo(&os, NULL); + setStandardMacros(spec, arch, os); + + /* All the parse*() functions expect to have a line pre-read */ + /* in the spec's line buffer. Except for parsePreamble(), */ + /* which handles the initial entry into a spec file. */ + + while (parsePart != PART_NONE) { + switch (parsePart) { + case PART_PREAMBLE: + parsePart = parsePreamble(spec, initialPackage); + initialPackage = 0; + break; + case PART_PREP: + parsePart = parsePrep(spec); + break; + case PART_BUILD: + case PART_INSTALL: + case PART_CLEAN: + parsePart = parseBuildInstallClean(spec, parsePart); + break; + case PART_CHANGELOG: + parsePart = parseChangelog(spec); + break; + case PART_DESCRIPTION: + parsePart = parseDescription(spec); + break; + case PART_PRE: + case PART_POST: + case PART_PREUN: + case PART_POSTUN: + case PART_VERIFYSCRIPT: + parsePart = parseScript(spec, parsePart); + break; + + case PART_FILES: + parsePart = parseFiles(spec); + break; + + case PART_TRIGGERIN: + case PART_TRIGGERUN: + printf("Triggers are not supported yet.\n"); + exit(1); + /*parsePart = parseTrigger(spec, parsePart);*/ + break; + } + + if (parsePart < 0) { + freeSpec(spec); + return parsePart; + } + + if (parsePart == PART_BUILDARCHITECTURES) { + spec->buildArchitectureSpecs = + malloc(sizeof(Spec) * spec->buildArchitectureCount); + x = 0; + index = 0; + while (x < spec->buildArchitectureCount) { + if (rpmMachineScore(RPM_MACHTABLE_BUILDARCH, + spec->buildArchitectures[x])) { + rpmSetMachine(spec->buildArchitectures[x], NULL); + if (parseSpec(&(spec->buildArchitectureSpecs[index]), + specFile, buildRoot, 1, + passPhrase, cookie)) { + spec->buildArchitectureCount = index; + freeSpec(spec); + return RPMERR_BADSPEC; + } + index++; + } + x++; + } + spec->buildArchitectureCount = index; + if (! index) { + freeSpec(spec); + rpmError(RPMERR_BADSPEC, "No buildable architectures"); + return RPMERR_BADSPEC; + } + closeSpec(spec); + *specp = spec; + return 0; + } + } + + /* Check for description in each package and add arch and os */ + pkg = spec->packages; + while (pkg) { + headerGetEntry(pkg->header, RPMTAG_NAME, NULL, (void **) &name, NULL); + if (!headerIsEntry(pkg->header, RPMTAG_DESCRIPTION)) { + rpmError(RPMERR_BADSPEC, "Package has no %%description: %s", name); + freeSpec(spec); + return RPMERR_BADSPEC; + } + + headerAddEntry(pkg->header, RPMTAG_OS, RPM_STRING_TYPE, os, 1); + headerAddEntry(pkg->header, RPMTAG_ARCH, RPM_STRING_TYPE, arch, 1); + + pkg = pkg->next; + } + + closeSpec(spec); + *specp = spec; + return 0; +} + +static void setStandardMacros(Spec spec, char *arch, char *os) +{ + char buf[BUFSIZ]; + int x; + + addMacro(&spec->macros, "sourcedir", rpmGetVar(RPMVAR_SOURCEDIR)); + addMacro(&spec->macros, "builddir", rpmGetVar(RPMVAR_BUILDDIR)); + addMacro(&spec->macros, "optflags", rpmGetVar(RPMVAR_OPTFLAGS)); + addMacro(&spec->macros, "buildarch", arch); + addMacro(&spec->macros, "buildos", os); + + x = 0; + while (arch[x]) { + buf[x] = tolower(arch[x]); + x++; + } + buf[x] = '\0'; + addMacro(&spec->macros, "buildarch_lc", buf); + x = 0; + while (os[x]) { + buf[x] = tolower(os[x]); + x++; + } + buf[x] = '\0'; + addMacro(&spec->macros, "buildos_lc", buf); +} |