Simplify BPackageInfo::Parser::_Parse() further

* Match the attribute in a loop, use an attribute ID switch, do the
  "seen" checks without the switch.
* Explicitly handle the case when encountering an unknown attribute.
This commit is contained in:
Ingo Weinhold 2011-06-28 18:01:14 +02:00
parent 122597e0ba
commit d4701a2921

View File

@ -668,185 +668,109 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo)
if (t.type != TOKEN_WORD) if (t.type != TOKEN_WORD)
throw ParseError("expected word (a variable name)", t.pos); throw ParseError("expected word (a variable name)", t.pos);
if (t.text.ICompare(names[B_PACKAGE_INFO_NAME]) == 0) { BPackageInfoAttributeID attribute = B_PACKAGE_INFO_ENUM_COUNT;
if (seen[B_PACKAGE_INFO_NAME]) { for (int i = 0; i < B_PACKAGE_INFO_ENUM_COUNT; i++) {
BString error = BString(names[B_PACKAGE_INFO_NAME]) if (t.text.ICompare(names[i]) == 0) {
<< " already seen!"; attribute = (BPackageInfoAttributeID)i;
break;
}
}
if (attribute == B_PACKAGE_INFO_ENUM_COUNT) {
BString error = BString("unknown attribute \"") << t.text << '"';
throw ParseError(error, t.pos); throw ParseError(error, t.pos);
} }
BString name; if (seen[attribute]) {
_ParseStringValue(&name); BString error = BString(names[attribute]) << " already seen!";
packageInfo->SetName(name);
seen[B_PACKAGE_INFO_NAME] = true;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_SUMMARY]) == 0) {
if (seen[B_PACKAGE_INFO_SUMMARY]) {
BString error = BString(names[B_PACKAGE_INFO_SUMMARY])
<< " already seen!";
throw ParseError(error, t.pos); throw ParseError(error, t.pos);
} }
switch (attribute) {
case B_PACKAGE_INFO_NAME:
_ParseStringValue(&packageInfo->fName);
break;
case B_PACKAGE_INFO_SUMMARY:
{
BString summary; BString summary;
_ParseStringValue(&summary); _ParseStringValue(&summary);
if (summary.FindFirst('\n') >= 0) if (summary.FindFirst('\n') >= 0)
throw ParseError("the summary contains linebreaks", t.pos); throw ParseError("the summary contains linebreaks", t.pos);
packageInfo->SetSummary(summary); packageInfo->SetSummary(summary);
seen[B_PACKAGE_INFO_SUMMARY] = true; break;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_DESCRIPTION]) == 0) {
if (seen[B_PACKAGE_INFO_DESCRIPTION]) {
BString error = BString(names[B_PACKAGE_INFO_DESCRIPTION])
<< " already seen!";
throw ParseError(error, t.pos);
} }
BString description; case B_PACKAGE_INFO_DESCRIPTION:
_ParseStringValue(&description); _ParseStringValue(&packageInfo->fDescription);
packageInfo->SetDescription(description); break;
seen[B_PACKAGE_INFO_DESCRIPTION] = true;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_VENDOR]) == 0) {
if (seen[B_PACKAGE_INFO_VENDOR]) {
BString error = BString(names[B_PACKAGE_INFO_VENDOR])
<< " already seen!";
throw ParseError(error, t.pos);
}
BString vendor; case B_PACKAGE_INFO_VENDOR:
_ParseStringValue(&vendor); _ParseStringValue(&packageInfo->fVendor);
packageInfo->SetVendor(vendor); break;
seen[B_PACKAGE_INFO_VENDOR] = true;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_PACKAGER]) == 0) {
if (seen[B_PACKAGE_INFO_PACKAGER]) {
BString error = BString(names[B_PACKAGE_INFO_PACKAGER])
<< " already seen!";
throw ParseError(error, t.pos);
}
BString packager; case B_PACKAGE_INFO_PACKAGER:
_ParseStringValue(&packager); _ParseStringValue(&packageInfo->fPackager);
packageInfo->SetPackager(packager); break;
seen[B_PACKAGE_INFO_PACKAGER] = true;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_ARCHITECTURE]) == 0) {
if (seen[B_PACKAGE_INFO_ARCHITECTURE]) {
BString error = BString(names[B_PACKAGE_INFO_ARCHITECTURE])
<< " already seen!";
throw ParseError(error, t.pos);
}
BPackageArchitecture architecture; case B_PACKAGE_INFO_ARCHITECTURE:
_ParseArchitectureValue(&architecture); _ParseArchitectureValue(&packageInfo->fArchitecture);
packageInfo->SetArchitecture(architecture); break;
seen[B_PACKAGE_INFO_ARCHITECTURE] = true;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_VERSION]) == 0) {
if (seen[B_PACKAGE_INFO_VERSION]) {
BString error = BString(names[B_PACKAGE_INFO_VERSION])
<< " already seen!";
throw ParseError(error, t.pos);
}
BPackageVersion version; case B_PACKAGE_INFO_VERSION:
_ParseVersionValue(&version, false); _ParseVersionValue(&packageInfo->fVersion, false);
packageInfo->SetVersion(version); break;
seen[B_PACKAGE_INFO_VERSION] = true;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_COPYRIGHTS]) == 0) {
if (seen[B_PACKAGE_INFO_COPYRIGHTS]) {
BString error = BString(names[B_PACKAGE_INFO_COPYRIGHTS])
<< " already seen!";
throw ParseError(error, t.pos);
}
case B_PACKAGE_INFO_COPYRIGHTS:
_ParseStringList(&packageInfo->fCopyrightList); _ParseStringList(&packageInfo->fCopyrightList);
seen[B_PACKAGE_INFO_COPYRIGHTS] = true; break;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_LICENSES]) == 0) {
if (seen[B_PACKAGE_INFO_LICENSES]) {
BString error = BString(names[B_PACKAGE_INFO_LICENSES])
<< " already seen!";
throw ParseError(error, t.pos);
}
case B_PACKAGE_INFO_LICENSES:
_ParseStringList(&packageInfo->fLicenseList); _ParseStringList(&packageInfo->fLicenseList);
seen[B_PACKAGE_INFO_LICENSES] = true; break;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_URLS]) == 0) {
if (seen[B_PACKAGE_INFO_URLS]) {
BString error = BString(names[B_PACKAGE_INFO_URLS])
<< " already seen!";
throw ParseError(error, t.pos);
}
case B_PACKAGE_INFO_URLS:
_ParseStringList(&packageInfo->fURLList); _ParseStringList(&packageInfo->fURLList);
seen[B_PACKAGE_INFO_URLS] = true; break;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_SOURCE_URLS]) == 0) {
if (seen[B_PACKAGE_INFO_SOURCE_URLS]) {
BString error = BString(names[B_PACKAGE_INFO_SOURCE_URLS])
<< " already seen!";
throw ParseError(error, t.pos);
}
case B_PACKAGE_INFO_SOURCE_URLS:
_ParseStringList(&packageInfo->fSourceURLList); _ParseStringList(&packageInfo->fSourceURLList);
seen[B_PACKAGE_INFO_SOURCE_URLS] = true; break;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_PROVIDES]) == 0) {
if (seen[B_PACKAGE_INFO_PROVIDES]) {
BString error = BString(names[B_PACKAGE_INFO_PROVIDES])
<< " already seen!";
throw ParseError(error, t.pos);
}
case B_PACKAGE_INFO_PROVIDES:
_ParseResolvableList(&packageInfo->fProvidesList); _ParseResolvableList(&packageInfo->fProvidesList);
seen[B_PACKAGE_INFO_PROVIDES] = true; break;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_REQUIRES]) == 0) {
if (seen[B_PACKAGE_INFO_REQUIRES]) {
BString error = BString(names[B_PACKAGE_INFO_REQUIRES])
<< " already seen!";
throw ParseError(error, t.pos);
}
case B_PACKAGE_INFO_REQUIRES:
_ParseResolvableExprList(&packageInfo->fRequiresList); _ParseResolvableExprList(&packageInfo->fRequiresList);
seen[B_PACKAGE_INFO_REQUIRES] = true; break;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_SUPPLEMENTS]) == 0) {
if (seen[B_PACKAGE_INFO_SUPPLEMENTS]) {
BString error = BString(names[B_PACKAGE_INFO_SUPPLEMENTS])
<< " already seen!";
throw ParseError(error, t.pos);
}
case B_PACKAGE_INFO_SUPPLEMENTS:
_ParseResolvableExprList(&packageInfo->fSupplementsList); _ParseResolvableExprList(&packageInfo->fSupplementsList);
seen[B_PACKAGE_INFO_SUPPLEMENTS] = true; break;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_CONFLICTS]) == 0) {
if (seen[B_PACKAGE_INFO_CONFLICTS]) {
BString error = BString(names[B_PACKAGE_INFO_CONFLICTS])
<< " already seen!";
throw ParseError(error, t.pos);
}
case B_PACKAGE_INFO_CONFLICTS:
_ParseResolvableExprList(&packageInfo->fConflictsList); _ParseResolvableExprList(&packageInfo->fConflictsList);
seen[B_PACKAGE_INFO_CONFLICTS] = true; break;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_FRESHENS]) == 0) {
if (seen[B_PACKAGE_INFO_FRESHENS]) {
BString error = BString(names[B_PACKAGE_INFO_FRESHENS])
<< " already seen!";
throw ParseError(error, t.pos);
}
case B_PACKAGE_INFO_FRESHENS:
_ParseResolvableExprList(&packageInfo->fFreshensList); _ParseResolvableExprList(&packageInfo->fFreshensList);
seen[B_PACKAGE_INFO_FRESHENS] = true; break;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_REPLACES]) == 0) {
if (seen[B_PACKAGE_INFO_REPLACES]) {
BString error = BString(names[B_PACKAGE_INFO_REPLACES])
<< " already seen!";
throw ParseError(error, t.pos);
}
case B_PACKAGE_INFO_REPLACES:
_ParseStringList(&packageInfo->fReplacesList, false); _ParseStringList(&packageInfo->fReplacesList, false);
seen[B_PACKAGE_INFO_REPLACES] = true; break;
} else if (t.text.ICompare(names[B_PACKAGE_INFO_FLAGS]) == 0) {
if (seen[B_PACKAGE_INFO_FLAGS]) { case B_PACKAGE_INFO_FLAGS:
BString error = BString(names[B_PACKAGE_INFO_FLAGS]) packageInfo->SetFlags(_ParseFlags());
<< " already seen!"; break;
throw ParseError(error, t.pos);
default:
// can never get here
break;
} }
packageInfo->SetFlags(_ParseFlags()); seen[attribute] = true;
seen[B_PACKAGE_INFO_FLAGS] = true;
}
} }
// everything up to and including 'provides' is mandatory // everything up to and including 'provides' is mandatory