void parse( const std::string& value ) { Decimal d( 0 ); YesNo e = YesNo::no; if ( value.find_first_not_of( "-.0123456789" ) != std::string::npos ) { if ( value.find_first_not_of( "yesno" ) == std::string::npos ) { /* it must be an enum if it has non numeric characters */ e = parseYesNo( value ); this->setValue( e ); } } else { /* if it contains only numeric characters it must be a number */ d.parse( value ); this->setValue( d ); } }
static bool parseYesNo(const ConfigSection::value_type& option, const std::string& sectionName) { return parseYesNo(option.second, option.first, sectionName); }
static rpmRC handlePreambleTag(Spec spec, Package pkg, rpmTag tag, const char *macro, const char *lang) /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ /*@modifies spec->macros, spec->st, spec->sources, spec->numSources, spec->noSource, spec->sourceHeader, spec->BANames, spec->BACount, spec->line, pkg->header, pkg->autoProv, pkg->autoReq, pkg->noarch, rpmGlobalMacroContext, fileSystem, internalState @*/ { HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); char * field = spec->line; char * end; int multiToken = 0; rpmsenseFlags tagflags; int len; rpmuint32_t num; int rc; int xx; if (field == NULL) return RPMRC_FAIL; /* XXX can't happen */ /* Find the start of the "field" and strip trailing space */ while ((*field) && (*field != ':')) field++; if (*field != ':') { rpmlog(RPMLOG_ERR, _("line %d: Malformed tag: %s\n"), spec->lineNum, spec->line); return RPMRC_FAIL; } field++; SKIPSPACE(field); if (!*field) { /* Empty field */ rpmlog(RPMLOG_ERR, _("line %d: Empty tag: %s\n"), spec->lineNum, spec->line); return RPMRC_FAIL; } end = findLastChar(field); /* Validate tag data content. */ if (tagValidate(spec, tag, field) != RPMRC_OK) return RPMRC_FAIL; /* See if this is multi-token */ end = field; SKIPNONSPACE(end); if (*end != '\0') multiToken = 1; switch (tag) { case RPMTAG_NAME: case RPMTAG_VERSION: case RPMTAG_RELEASE: case RPMTAG_DISTEPOCH: case RPMTAG_URL: case RPMTAG_DISTTAG: case RPMTAG_REPOTAG: case RPMTAG_CVSID: case RPMTAG_BUGURL: SINGLE_TOKEN_ONLY; /* These macros are for backward compatibility */ if (tag == RPMTAG_VERSION) { if (strchr(field, '-') != NULL) { rpmlog(RPMLOG_ERR, _("line %d: Illegal char '-' in %s: %s\n"), spec->lineNum, "version", spec->line); return RPMRC_FAIL; } addMacro(spec->macros, "PACKAGE_VERSION", NULL, field, RMIL_OLDSPEC); } else if (tag == RPMTAG_RELEASE) { if (strchr(field, '-') != NULL) { rpmlog(RPMLOG_ERR, _("line %d: Illegal char '-' in %s: %s\n"), spec->lineNum, "release", spec->line); return RPMRC_FAIL; } addMacro(spec->macros, "PACKAGE_RELEASE", NULL, field, RMIL_OLDSPEC-1); } he->tag = tag; he->t = RPM_STRING_TYPE; he->p.str = field; he->c = 1; xx = headerPut(pkg->header, he, 0); break; case RPMTAG_GROUP: case RPMTAG_SUMMARY: #if defined(RPM_VENDOR_OPENPKG) /* make-class-available-as-macro */ case RPMTAG_CLASS: #endif (void) stashSt(spec, pkg->header, tag, lang); /*@fallthrough@*/ case RPMTAG_DISTRIBUTION: case RPMTAG_VENDOR: case RPMTAG_LICENSE: case RPMTAG_PACKAGER: if (!*lang) { he->tag = tag; he->t = RPM_STRING_TYPE; he->p.str = field; he->c = 1; xx = headerPut(pkg->header, he, 0); } else if (!(noLang && strcmp(lang, RPMBUILD_DEFAULT_LANG))) { (void) headerAddI18NString(pkg->header, tag, field, lang); } break; /* XXX silently ignore BuildRoot: */ case RPMTAG_BUILDROOT: SINGLE_TOKEN_ONLY; macro = NULL; #ifdef DYING buildRootURL = rpmGenPath(spec->rootURL, "%{?buildroot}", NULL); (void) urlPath(buildRootURL, &buildRoot); if (*buildRoot == '\0') buildRoot = "/"; if (!strcmp(buildRoot, "/")) { rpmlog(RPMLOG_ERR, _("BuildRoot can not be \"/\": %s\n"), spec->buildRootURL); buildRootURL = _free(buildRootURL); return RPMRC_FAIL; } buildRootURL = _free(buildRootURL); #endif break; case RPMTAG_KEYWORDS: case RPMTAG_VARIANTS: case RPMTAG_PREFIXES: addOrAppendListEntry(pkg->header, tag, field); he->tag = tag; xx = headerGet(pkg->header, he, 0); if (tag == RPMTAG_PREFIXES) while (he->c--) { if (he->p.argv[he->c][0] != '/') { rpmlog(RPMLOG_ERR, _("line %d: Prefixes must begin with \"/\": %s\n"), spec->lineNum, spec->line); he->p.ptr = _free(he->p.ptr); return RPMRC_FAIL; } len = (int)strlen(he->p.argv[he->c]); if (he->p.argv[he->c][len - 1] == '/' && len > 1) { rpmlog(RPMLOG_ERR, _("line %d: Prefixes must not end with \"/\": %s\n"), spec->lineNum, spec->line); he->p.ptr = _free(he->p.ptr); return RPMRC_FAIL; } } he->p.ptr = _free(he->p.ptr); break; case RPMTAG_DOCDIR: SINGLE_TOKEN_ONLY; if (field[0] != '/') { rpmlog(RPMLOG_ERR, _("line %d: Docdir must begin with '/': %s\n"), spec->lineNum, spec->line); return RPMRC_FAIL; } macro = NULL; delMacro(NULL, "_docdir"); addMacro(NULL, "_docdir", NULL, field, RMIL_SPEC); break; case RPMTAG_XMAJOR: case RPMTAG_XMINOR: case RPMTAG_EPOCH: SINGLE_TOKEN_ONLY; if (parseNum(field, &num)) { rpmlog(RPMLOG_ERR, _("line %d: %s takes an integer value: %s\n"), spec->lineNum, tagName(tag), spec->line); return RPMRC_FAIL; } he->tag = tag; he->t = RPM_UINT32_TYPE; he->p.ui32p = # he->c = 1; xx = headerPut(pkg->header, he, 0); break; case RPMTAG_AUTOREQPROV: pkg->autoReq = parseYesNo(field); pkg->autoProv = pkg->autoReq; break; case RPMTAG_AUTOREQ: pkg->autoReq = parseYesNo(field); break; case RPMTAG_AUTOPROV: pkg->autoProv = parseYesNo(field); break; case RPMTAG_SOURCE: case RPMTAG_PATCH: SINGLE_TOKEN_ONLY; macro = NULL; if ((rc = addSource(spec, pkg, field, tag))) return rc; break; case RPMTAG_ICON: SINGLE_TOKEN_ONLY; macro = NULL; if ((rc = addSource(spec, pkg, field, tag))) return rc; /* XXX the fetch/load of icon needs to be elsewhere. */ if ((rc = doIcon(spec, pkg->header))) return rc; break; case RPMTAG_NOSOURCE: case RPMTAG_NOPATCH: spec->noSource = 1; if ((rc = parseNoSource(spec, field, tag))) return rc; break; case RPMTAG_BUILDPREREQ: case RPMTAG_BUILDREQUIRES: if ((rc = parseBits(lang, buildScriptBits, &tagflags))) { rpmlog(RPMLOG_ERR, _("line %d: Bad %s: qualifiers: %s\n"), spec->lineNum, tagName(tag), spec->line); return rc; } if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags))) return rc; break; case RPMTAG_PREREQ: case RPMTAG_REQUIREFLAGS: if ((rc = parseBits(lang, installScriptBits, &tagflags))) { rpmlog(RPMLOG_ERR, _("line %d: Bad %s: qualifiers: %s\n"), spec->lineNum, tagName(tag), spec->line); return rc; } if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags))) return rc; break; /* Aliases for BuildRequires(hint): */ case RPMTAG_BUILDSUGGESTS: case RPMTAG_BUILDENHANCES: tagflags = RPMSENSE_MISSINGOK; if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags))) return rc; break; /* Aliases for Requires(hint): */ case RPMTAG_SUGGESTSFLAGS: case RPMTAG_ENHANCESFLAGS: tag = RPMTAG_REQUIREFLAGS; tagflags = RPMSENSE_MISSINGOK; if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags))) return rc; break; case RPMTAG_BUILDOBSOLETES: case RPMTAG_BUILDPROVIDES: case RPMTAG_BUILDCONFLICTS: case RPMTAG_CONFLICTFLAGS: case RPMTAG_OBSOLETEFLAGS: case RPMTAG_PROVIDEFLAGS: tagflags = RPMSENSE_ANY; if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags))) return rc; break; case RPMTAG_BUILDPLATFORMS: /* XXX needs pattern parsing */ case RPMTAG_EXCLUDEARCH: case RPMTAG_EXCLUSIVEARCH: case RPMTAG_EXCLUDEOS: case RPMTAG_EXCLUSIVEOS: addOrAppendListEntry(spec->sourceHeader, tag, field); break; case RPMTAG_BUILDARCHS: { const char ** BANames = NULL; int BACount = 0; if ((rc = poptParseArgvString(field, &BACount, &BANames))) { rpmlog(RPMLOG_ERR, _("line %d: Bad BuildArchitecture format: %s\n"), spec->lineNum, spec->line); return RPMRC_FAIL; } if (spec->toplevel) { if (BACount > 0 && BANames != NULL) { spec->BACount = BACount; spec->BANames = BANames; BANames = NULL; /* XXX don't free. */ } } else { if (BACount != 1 || strcmp(BANames[0], "noarch")) { rpmlog(RPMLOG_ERR, _("line %d: Only \"noarch\" sub-packages are supported: %s\n"), spec->lineNum, spec->line); BANames = _free(BANames); return RPMRC_FAIL; } pkg->noarch = 1; } BANames = _free(BANames); } break; default: macro = NULL; he->tag = tag; he->t = RPM_STRING_ARRAY_TYPE; he->p.argv= (const char **) &field; /* XXX NOCAST */ he->c = 1; he->append = 1; xx = headerPut(pkg->header, he, 0); he->append = 0; break; } /*@-usereleased@*/ if (macro) addMacro(spec->macros, macro, NULL, field, RMIL_SPEC); /*@=usereleased@*/ return RPMRC_OK; }
static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag, const char *macro, const char *lang) { char * field = spec->line; char * end; int multiToken = 0; rpmsenseFlags tagflags = RPMSENSE_ANY; rpmRC rc = RPMRC_FAIL; if (field == NULL) /* XXX can't happen */ goto exit; /* Find the start of the "field" and strip trailing space */ while ((*field) && (*field != ':')) field++; if (*field != ':') { rpmlog(RPMLOG_ERR, _("line %d: Malformed tag: %s\n"), spec->lineNum, spec->line); goto exit; } field++; SKIPSPACE(field); if (!*field) { /* Empty field */ rpmlog(RPMLOG_ERR, _("line %d: Empty tag: %s\n"), spec->lineNum, spec->line); goto exit; } end = findLastChar(field); *(end+1) = '\0'; /* See if this is multi-token */ end = field; SKIPNONSPACE(end); if (*end != '\0') multiToken = 1; switch (tag) { case RPMTAG_NAME: SINGLE_TOKEN_ONLY; if (rpmCharCheck(spec, field, WHITELIST_NAME)) goto exit; headerPutString(pkg->header, tag, field); /* Main pkg name is unknown at the start, populate as soon as we can */ if (pkg == spec->packages) pkg->name = rpmstrPoolId(spec->pool, field, 1); break; case RPMTAG_VERSION: case RPMTAG_RELEASE: SINGLE_TOKEN_ONLY; if (rpmCharCheck(spec, field, "._+%{}~")) goto exit; headerPutString(pkg->header, tag, field); break; case RPMTAG_URL: case RPMTAG_DISTTAG: case RPMTAG_BUGURL: /* XXX TODO: validate format somehow */ case RPMTAG_VCS: SINGLE_TOKEN_ONLY; headerPutString(pkg->header, tag, field); break; case RPMTAG_GROUP: case RPMTAG_SUMMARY: case RPMTAG_DISTRIBUTION: case RPMTAG_VENDOR: case RPMTAG_LICENSE: case RPMTAG_PACKAGER: if (addLangTag(spec, pkg->header, tag, field, lang)) goto exit; break; case RPMTAG_BUILDROOT: /* just silently ignore BuildRoot */ macro = NULL; break; case RPMTAG_PREFIXES: { struct rpmtd_s td; const char *str; if (addOrAppendListEntry(pkg->header, tag, field)) goto exit; headerGet(pkg->header, tag, &td, HEADERGET_MINMEM); while ((str = rpmtdNextString(&td))) { size_t len = strlen(str); if (len > 1 && str[len-1] == '/') { rpmlog(RPMLOG_ERR, _("line %d: Prefixes must not end with \"/\": %s\n"), spec->lineNum, spec->line); rpmtdFreeData(&td); goto exit; } } rpmtdFreeData(&td); break; } case RPMTAG_DOCDIR: SINGLE_TOKEN_ONLY; if (field[0] != '/') { rpmlog(RPMLOG_ERR, _("line %d: Docdir must begin with '/': %s\n"), spec->lineNum, spec->line); goto exit; } macro = NULL; rpmPopMacro(NULL, "_docdir"); rpmPushMacro(NULL, "_docdir", NULL, field, RMIL_SPEC); break; case RPMTAG_EPOCH: { SINGLE_TOKEN_ONLY; uint32_t epoch; if (parseUnsignedNum(field, &epoch)) { rpmlog(RPMLOG_ERR, _("line %d: Epoch field must be an unsigned number: %s\n"), spec->lineNum, spec->line); goto exit; } headerPutUint32(pkg->header, tag, &epoch, 1); break; } case RPMTAG_AUTOREQPROV: pkg->autoReq = parseYesNo(field); pkg->autoProv = pkg->autoReq; break; case RPMTAG_AUTOREQ: pkg->autoReq = parseYesNo(field); break; case RPMTAG_AUTOPROV: pkg->autoProv = parseYesNo(field); break; case RPMTAG_SOURCE: case RPMTAG_PATCH: macro = NULL; if (addSource(spec, pkg, field, tag)) goto exit; break; case RPMTAG_ICON: SINGLE_TOKEN_ONLY; if (addSource(spec, pkg, field, tag) || readIcon(pkg->header, field)) goto exit; break; case RPMTAG_NOSOURCE: case RPMTAG_NOPATCH: spec->noSource = 1; if (parseNoSource(spec, field, tag)) goto exit; break; case RPMTAG_ORDERFLAGS: case RPMTAG_REQUIREFLAGS: if (parseBits(lang, installScriptBits, &tagflags)) { rpmlog(RPMLOG_ERR, _("line %d: Bad %s: qualifiers: %s\n"), spec->lineNum, rpmTagGetName(tag), spec->line); goto exit; } /* fallthrough */ case RPMTAG_PREREQ: case RPMTAG_RECOMMENDFLAGS: case RPMTAG_SUGGESTFLAGS: case RPMTAG_SUPPLEMENTFLAGS: case RPMTAG_ENHANCEFLAGS: case RPMTAG_CONFLICTFLAGS: case RPMTAG_OBSOLETEFLAGS: case RPMTAG_PROVIDEFLAGS: if (parseRCPOT(spec, pkg, field, tag, 0, tagflags)) goto exit; break; case RPMTAG_BUILDPREREQ: case RPMTAG_BUILDREQUIRES: case RPMTAG_BUILDCONFLICTS: if (parseRCPOT(spec, spec->sourcePackage, field, tag, 0, tagflags)) goto exit; break; case RPMTAG_EXCLUDEARCH: case RPMTAG_EXCLUSIVEARCH: case RPMTAG_EXCLUDEOS: case RPMTAG_EXCLUSIVEOS: if (addOrAppendListEntry(spec->buildRestrictions, tag, field)) goto exit; break; case RPMTAG_BUILDARCHS: { int BACount; const char **BANames = NULL; if (poptParseArgvString(field, &BACount, &BANames)) { rpmlog(RPMLOG_ERR, _("line %d: Bad BuildArchitecture format: %s\n"), spec->lineNum, spec->line); goto exit; } if (spec->packages == pkg) { if (spec->BANames) { rpmlog(RPMLOG_ERR, _("line %d: Duplicate BuildArch entry: %s\n"), spec->lineNum, spec->line); BANames = _free(BANames); goto exit; } spec->BACount = BACount; spec->BANames = BANames; } else { if (BACount != 1 || !rstreq(BANames[0], "noarch")) { rpmlog(RPMLOG_ERR, _("line %d: Only noarch subpackages are supported: %s\n"), spec->lineNum, spec->line); BANames = _free(BANames); goto exit; } headerPutString(pkg->header, RPMTAG_ARCH, "noarch"); } if (!BACount) spec->BANames = _free(spec->BANames); break; } case RPMTAG_REMOVEPATHPOSTFIXES: argvSplit(&pkg->removePostfixes, field, ":"); break; default: rpmlog(RPMLOG_ERR, _("Internal error: Bogus tag %d\n"), tag); goto exit; } if (macro) { rpmPushMacro(spec->macros, macro, NULL, field, RMIL_SPEC); /* Add a separate uppercase macro for tags from the main package */ if (pkg == spec->packages) { char *m = xstrdup(macro); for (char *p = m; *p; ++p) *p = rtoupper(*p); rpmPushMacro(spec->macros, m, NULL, field, RMIL_SPEC); free(m); } } rc = RPMRC_OK; exit: return rc; }