#define SKIPSPACE(s) { while (*(s) && risspace(*(s))) (s)++; }
#define SKIPNONSPACE(s) { while (*(s) && !risspace(*(s))) (s)++; }
-/* XXX FIXME: strlen for these is calculated at runtime, preventing const */
-static struct PartRec {
+#define LEN_AND_STR(_tag) (sizeof(_tag)-1), (_tag)
+
+static const struct PartRec {
int part;
size_t len;
const char * token;
-} partList[] = {
- { PART_PREAMBLE, 0, "%package"},
- { PART_PREP, 0, "%prep"},
- { PART_BUILD, 0, "%build"},
- { PART_INSTALL, 0, "%install"},
- { PART_CHECK, 0, "%check"},
- { PART_CLEAN, 0, "%clean"},
- { PART_PREUN, 0, "%preun"},
- { PART_POSTUN, 0, "%postun"},
- { PART_PRETRANS, 0, "%pretrans"},
- { PART_POSTTRANS, 0, "%posttrans"},
- { PART_PRE, 0, "%pre"},
- { PART_POST, 0, "%post"},
- { PART_FILES, 0, "%files"},
- { PART_CHANGELOG, 0, "%changelog"},
- { PART_DESCRIPTION, 0, "%description"},
- { PART_TRIGGERPOSTUN, 0, "%triggerpostun"},
- { PART_TRIGGERPREIN, 0, "%triggerprein"},
- { PART_TRIGGERUN, 0, "%triggerun"},
- { PART_TRIGGERIN, 0, "%triggerin"},
- { PART_TRIGGERIN, 0, "%trigger"},
- { PART_VERIFYSCRIPT, 0, "%verifyscript"},
+} const partList[] = {
+ { PART_PREAMBLE, LEN_AND_STR("%package")},
+ { PART_PREP, LEN_AND_STR("%prep")},
+ { PART_BUILD, LEN_AND_STR("%build")},
+ { PART_INSTALL, LEN_AND_STR("%install")},
+ { PART_CHECK, LEN_AND_STR("%check")},
+ { PART_CLEAN, LEN_AND_STR("%clean")},
+ { PART_PREUN, LEN_AND_STR("%preun")},
+ { PART_POSTUN, LEN_AND_STR("%postun")},
+ { PART_PRETRANS, LEN_AND_STR("%pretrans")},
+ { PART_POSTTRANS, LEN_AND_STR("%posttrans")},
+ { PART_PRE, LEN_AND_STR("%pre")},
+ { PART_POST, LEN_AND_STR("%post")},
+ { PART_FILES, LEN_AND_STR("%files")},
+ { PART_CHANGELOG, LEN_AND_STR("%changelog")},
+ { PART_DESCRIPTION, LEN_AND_STR("%description")},
+ { PART_TRIGGERPOSTUN, LEN_AND_STR("%triggerpostun")},
+ { PART_TRIGGERPREIN, LEN_AND_STR("%triggerprein")},
+ { PART_TRIGGERUN, LEN_AND_STR("%triggerun")},
+ { PART_TRIGGERIN, LEN_AND_STR("%triggerin")},
+ { PART_TRIGGERIN, LEN_AND_STR("%trigger")},
+ { PART_VERIFYSCRIPT, LEN_AND_STR("%verifyscript")},
{0, 0, 0}
};
-/**
- */
-static inline void initParts(struct PartRec *p)
-{
- for (; p->token != NULL; p++)
- p->len = strlen(p->token);
-}
-
rpmParseState isPart(const char *line)
{
- struct PartRec *p;
+ const struct PartRec *p;
- if (partList[0].len == 0)
- initParts(partList);
-
for (p = partList; p->token != NULL; p++) {
char c;
if (rstrncasecmp(line, p->token, p->len))
to = spec->lbufPtr ? spec->lbufPtr : spec->lbuf;
from = ofi->readPtr;
ch = ' ';
- while (*from && ch != '\n')
+ while (from && *from && ch != '\n')
ch = *to++ = *from++;
spec->lbufPtr = to;
*to++ = '\0';
SKIPSPACE(s);
match = -1;
- if (!spec->readStack->reading && !strncmp("%if", s, sizeof("%if")-1)) {
+ if (!spec->readStack->reading && rstreqn("%if", s, sizeof("%if")-1)) {
match = 0;
- } else if (! strncmp("%ifarch", s, sizeof("%ifarch")-1)) {
+ } else if (rstreqn("%ifarch", s, sizeof("%ifarch")-1)) {
char *arch = rpmExpand("%{_target_cpu}", NULL);
s += 7;
match = matchTok(arch, s);
arch = _free(arch);
- } else if (! strncmp("%ifnarch", s, sizeof("%ifnarch")-1)) {
+ } else if (rstreqn("%ifnarch", s, sizeof("%ifnarch")-1)) {
char *arch = rpmExpand("%{_target_cpu}", NULL);
s += 8;
match = !matchTok(arch, s);
arch = _free(arch);
- } else if (! strncmp("%ifos", s, sizeof("%ifos")-1)) {
+ } else if (rstreqn("%ifos", s, sizeof("%ifos")-1)) {
char *os = rpmExpand("%{_target_os}", NULL);
s += 5;
match = matchTok(os, s);
os = _free(os);
- } else if (! strncmp("%ifnos", s, sizeof("%ifnos")-1)) {
+ } else if (rstreqn("%ifnos", s, sizeof("%ifnos")-1)) {
char *os = rpmExpand("%{_target_os}", NULL);
s += 6;
match = !matchTok(os, s);
os = _free(os);
- } else if (! strncmp("%if", s, sizeof("%if")-1)) {
+ } else if (rstreqn("%if", s, sizeof("%if")-1)) {
s += 3;
match = parseExpressionBoolean(spec, s);
if (match < 0) {
ofi->fileName, ofi->lineNum, match);
return PART_ERROR;
}
- } else if (! strncmp("%else", s, sizeof("%else")-1)) {
+ } else if (rstreqn("%else", s, sizeof("%else")-1)) {
s += 5;
if (! spec->readStack->next) {
/* Got an else with no %if ! */
spec->readStack->reading =
spec->readStack->next->reading && ! spec->readStack->reading;
spec->line[0] = '\0';
- } else if (! strncmp("%endif", s, sizeof("%endif")-1)) {
+ } else if (rstreqn("%endif", s, sizeof("%endif")-1)) {
s += 6;
if (! spec->readStack->next) {
/* Got an end with no %if ! */
spec->readStack = spec->readStack->next;
free(rl);
spec->line[0] = '\0';
- } else if (! strncmp("%include", s, sizeof("%include")-1)) {
+ } else if (rstreqn("%include", s, sizeof("%include")-1)) {
char *fileName, *endFileName, *p;
s += 8;
/* Set up a new Spec structure with no packages. */
spec = newSpec();
- /*
- * Note: rpmGetPath should guarantee a "canonical" path. That means
- * that the following pathologies should be weeded out:
- * //bin//sh
- * //usr//bin/
- * /.././../usr/../bin//./sh (XXX FIXME: dots not handled yet)
- */
spec->specFile = rpmGetPath(specFile, NULL);
spec->fileStack = newOpenFileInfo();
spec->fileStack->fileName = xstrdup(spec->specFile);
+ /* If buildRoot not specified, use default %{buildroot} */
if (buildRoot) {
- if (*buildRoot == '\0') {
- rpmlog(RPMLOG_ERR, _("BuildRoot couldn't be empty\n"));
- goto errxit;
- }
- if (!strcmp(buildRoot, "/")) {
- rpmlog(RPMLOG_ERR, _("BuildRoot can not be \"/\"\n"));
- goto errxit;
- }
- spec->gotBuildRoot = 1;
spec->buildRoot = xstrdup(buildRoot);
- addMacro(spec->macros, "buildroot", NULL, buildRoot, RMIL_SPEC);
+ } else {
+ spec->buildRoot = rpmGetPath("%{?buildroot:%{buildroot}}", NULL);
}
addMacro(NULL, "_docdir", NULL, "%{_defaultdocdir}", RMIL_SPEC);
spec->recursing = recursing;
/* in the spec's line buffer. Except for parsePreamble(), */
/* which handles the initial entry into a spec file. */
- /* LCL: parsePart is modified @*/
while (parsePart != PART_NONE) {
int goterror = 0;
switch (parsePart) {
closeSpec(spec);
- /* LCL: sizeof(spec->BASpecs[0]) -nullderef whine here */
spec->BASpecs = xcalloc(spec->BACount, sizeof(*spec->BASpecs));
index = 0;
if (spec->BANames != NULL)
return 0;
}
}
- /* LCL: parsePart is modified @*/
+
+ if (spec->clean == NULL) {
+ char *body = rpmExpand("%{?buildroot: %{__rm} -rf %{buildroot}}", NULL);
+ spec->clean = newStringBuf();
+ appendLineStringBuf(spec->clean, body);
+ free(body);
+ }
/* Check for description in each package and add arch and os */
{
for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
if (!headerIsEntry(pkg->header, RPMTAG_DESCRIPTION)) {
- const char * name;
- (void) headerNVR(pkg->header, &name, NULL, NULL);
- rpmlog(RPMLOG_ERR, _("Package has no %%description: %s\n"), name);
+ rpmlog(RPMLOG_ERR, _("Package has no %%description: %s\n"),
+ headerGetString(pkg->header, RPMTAG_NAME));
goto errxit;
}
headerPutString(pkg->header, RPMTAG_OS, os);
- headerPutString(pkg->header, RPMTAG_ARCH, arch);
+ /* noarch subpackages already have arch set here, leave it alone */
+ if (!headerIsEntry(pkg->header, RPMTAG_ARCH)) {
+ headerPutString(pkg->header, RPMTAG_ARCH, arch);
+ }
headerPutString(pkg->header, RPMTAG_PLATFORM, platform);
pkg->ds = rpmdsThis(pkg->header, RPMTAG_REQUIRENAME, RPMSENSE_EQUAL);