From 7adfd76b17adc78b0646a835711d3cd935bfb02b Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 13 May 2013 21:02:30 +0200 Subject: [PATCH] Add "base package" package attribute --- headers/os/package/PackageInfo.h | 3 + headers/os/package/PackageInfoAttributes.h | 1 + headers/os/package/hpkg/HPKGDefs.h | 1 + src/bin/package/command_list.cpp | 4 + src/kits/package/PackageInfo.cpp | 99 ++++++++++++++++--- .../package/hpkg/PackageContentHandler.cpp | 1 + src/kits/package/hpkg/ReaderImplBase.cpp | 4 + src/kits/package/hpkg/WriterImplBase.cpp | 11 +++ 8 files changed, 109 insertions(+), 15 deletions(-) diff --git a/headers/os/package/PackageInfo.h b/headers/os/package/PackageInfo.h index 9833a9047d..f2b08b2f14 100644 --- a/headers/os/package/PackageInfo.h +++ b/headers/os/package/PackageInfo.h @@ -64,6 +64,7 @@ public: const BString& Description() const; const BString& Vendor() const; const BString& Packager() const; + const BString& BasePackage() const; const BString& Checksum() const; const BString& InstallPath() const; @@ -96,6 +97,7 @@ public: void SetDescription(const BString& description); void SetVendor(const BString& vendor); void SetPackager(const BString& packager); + void SetBasePackage(const BString& basePackage); void SetChecksum(const BString& checksum); void SetInstallPath(const BString& installPath); @@ -205,6 +207,7 @@ private: BString fDescription; BString fVendor; BString fPackager; + BString fBasePackage; uint32 fFlags; diff --git a/headers/os/package/PackageInfoAttributes.h b/headers/os/package/PackageInfoAttributes.h index 56fa2ef7aa..83fbd4d1d1 100644 --- a/headers/os/package/PackageInfoAttributes.h +++ b/headers/os/package/PackageInfoAttributes.h @@ -40,6 +40,7 @@ enum BPackageInfoAttributeID { B_PACKAGE_INFO_CHECKSUM, // sha256-checksum B_PACKAGE_INFO_INSTALL_PATH, // package install path; only for package // building + B_PACKAGE_INFO_BASE_PACKAGE, // name of the base package for this package // B_PACKAGE_INFO_ENUM_COUNT, }; diff --git a/headers/os/package/hpkg/HPKGDefs.h b/headers/os/package/hpkg/HPKGDefs.h index cc955d67c4..d4f90156c1 100644 --- a/headers/os/package/hpkg/HPKGDefs.h +++ b/headers/os/package/hpkg/HPKGDefs.h @@ -128,6 +128,7 @@ enum BHPKGAttributeID { B_HPKG_ATTRIBUTE_ID_PACKAGE_URL = 41, B_HPKG_ATTRIBUTE_ID_PACKAGE_SOURCE_URL = 42, B_HPKG_ATTRIBUTE_ID_PACKAGE_INSTALL_PATH = 43, + B_HPKG_ATTRIBUTE_ID_PACKAGE_BASE_PACKAGE = 44, // B_HPKG_ATTRIBUTE_ID_ENUM_COUNT, }; diff --git a/src/bin/package/command_list.cpp b/src/bin/package/command_list.cpp index 372152d03b..de9220c217 100644 --- a/src/bin/package/command_list.cpp +++ b/src/bin/package/command_list.cpp @@ -159,6 +159,10 @@ struct PackageContentListHandler : VersionPolicy::PackageContentHandler { printf("\tpackager: %s\n", value.string); break; + case B_PACKAGE_INFO_BASE_PACKAGE: + printf("\tbase package: %s\n", value.string); + break; + case B_PACKAGE_INFO_FLAGS: if (value.unsignedInt == 0) break; diff --git a/src/kits/package/PackageInfo.cpp b/src/kits/package/PackageInfo.cpp index a27f691c1a..6e6553e942 100644 --- a/src/kits/package/PackageInfo.cpp +++ b/src/kits/package/PackageInfo.cpp @@ -106,7 +106,8 @@ private: BObjectList* value); void _ParseResolvableExprList( BObjectList* - value); + value, + BString* _basePackage = NULL); void _Parse(BPackageInfo* packageInfo); @@ -681,17 +682,20 @@ BPackageInfo::Parser::_ParseResolvableList( void BPackageInfo::Parser::_ParseResolvableExprList( - BObjectList* value) + BObjectList* value, BString* _basePackage) { struct ResolvableExpressionParser : public ListElementParser { Parser& parser; BObjectList* value; + BString* basePackage; - ResolvableExpressionParser(Parser& parser_, - BObjectList* value_) + ResolvableExpressionParser(Parser& parser, + BObjectList* value, + BString* basePackage) : - parser(parser_), - value(value_) + parser(parser), + value(value), + basePackage(basePackage) { } @@ -709,17 +713,31 @@ BPackageInfo::Parser::_ParseResolvableExprList( } BPackageVersion version; - Token op = parser._NextToken(); + Token op = parser._NextToken(); if (op.type == TOKEN_OPERATOR_LESS || op.type == TOKEN_OPERATOR_LESS_EQUAL || op.type == TOKEN_OPERATOR_EQUAL || op.type == TOKEN_OPERATOR_NOT_EQUAL || op.type == TOKEN_OPERATOR_GREATER_EQUAL || op.type == TOKEN_OPERATOR_GREATER) { - parser._ParseVersionValue(&version, true); + parser._ParseVersionValue(&version, true); + + if (basePackage != NULL) { + Token base = parser._NextToken(); + if (base.type == TOKEN_WORD && base.text == "base") { + if (!basePackage->IsEmpty()) { + throw ParseError( + "multiple packages marked as base package", + token.pos); + } + + *basePackage = token.text; + } else + parser._RewindTo(base); + } } else if (op.type == TOKEN_ITEM_SEPARATOR || op.type == TOKEN_CLOSE_BRACE) { - parser._RewindTo(op); + parser._RewindTo(op); } else { throw ParseError( "expected '<', '<=', '==', '!=', '>=', '>', comma or '}'", @@ -730,9 +748,9 @@ BPackageInfo::Parser::_ParseResolvableExprList( = (BPackageResolvableOperator)(op.type - TOKEN_OPERATOR_LESS); value->AddItem(new BPackageResolvableExpression(token.text, - resolvableOperator, version)); - } - } resolvableExpressionParser(*this, value); + resolvableOperator, version)); + } + } resolvableExpressionParser(*this, value, _basePackage); _ParseList(resolvableExpressionParser, false); } @@ -811,6 +829,10 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) _ParseStringValue(&packageInfo->fPackager); break; + case B_PACKAGE_INFO_BASE_PACKAGE: + _ParseStringValue(&packageInfo->fBasePackage); + break; + case B_PACKAGE_INFO_ARCHITECTURE: _ParseArchitectureValue(&packageInfo->fArchitecture); break; @@ -840,7 +862,9 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) break; case B_PACKAGE_INFO_REQUIRES: - _ParseResolvableExprList(&packageInfo->fRequiresList); + packageInfo->fBasePackage.Truncate(0); + _ParseResolvableExprList(&packageInfo->fRequiresList, + &packageInfo->fBasePackage); break; case B_PACKAGE_INFO_SUPPLEMENTS: @@ -981,7 +1005,8 @@ struct BPackageInfo::StringBuilder { StringBuilder() : fData(), - fError(B_OK) + fError(B_OK), + fBasePackage() { } @@ -1034,6 +1059,18 @@ struct BPackageInfo::StringBuilder { return *this; } + StringBuilder& BeginRequires(const BString& basePackage) + { + fBasePackage = basePackage; + return *this; + } + + StringBuilder& EndRequires() + { + fBasePackage.Truncate(0); + return *this; + } + private: void _WriteValue(const char* value) { @@ -1075,9 +1112,17 @@ private: template void _WriteValue(const BObjectList& value) { + // Note: The fBasePackage solution is disgusting, but any attempt of + // encapsulating the stringification via templates seems to result in + // an Internal Compiler Error with gcc 2. + int32 count = value.CountItems(); if (count == 1) { _Write(value.ItemAt(0)->ToString()); + if (!fBasePackage.IsEmpty() + && value.ItemAt(0)->Name() == fBasePackage) { + _Write(" base"); + } } else { _Write("{\n", 2); @@ -1085,6 +1130,10 @@ private: for (int32 i = 0; i < count; i++) { _Write('\t'); _Write(value.ItemAt(i)->ToString()); + if (!fBasePackage.IsEmpty() + && value.ItemAt(i)->Name() == fBasePackage) { + _Write(" base"); + } _Write('\n'); } @@ -1196,6 +1245,7 @@ private: private: BMallocIO fData; status_t fError; + BString fBasePackage; }; @@ -1324,6 +1374,7 @@ BPackageInfo::BPackageInfo(BMessage* archive, status_t* _error) && (error = archive->FindString("description", &fDescription)) == B_OK && (error = archive->FindString("vendor", &fVendor)) == B_OK && (error = archive->FindString("packager", &fPackager)) == B_OK + && (error = archive->FindString("basePackage", &fBasePackage)) == B_OK && (error = archive->FindUInt32("flags", &fFlags)) == B_OK && (error = archive->FindInt32("architecture", &architecture)) == B_OK && (error = _ExtractVersion(archive, "version", 0, fVersion)) == B_OK @@ -1483,6 +1534,13 @@ BPackageInfo::Packager() const } +const BString& +BPackageInfo::BasePackage() const +{ + return fBasePackage; +} + + const BString& BPackageInfo::Checksum() const { @@ -1635,6 +1693,13 @@ BPackageInfo::SetPackager(const BString& packager) } +void +BPackageInfo::SetBasePackage(const BString& basePackage) +{ + fBasePackage = basePackage; +} + + void BPackageInfo::SetChecksum(const BString& checksum) { @@ -1843,6 +1908,7 @@ BPackageInfo::Clear() fDescription.Truncate(0); fVendor.Truncate(0); fPackager.Truncate(0); + fBasePackage.Truncate(0); fChecksum.Truncate(0); fInstallPath.Truncate(0); fFlags = 0; @@ -1873,6 +1939,7 @@ BPackageInfo::Archive(BMessage* archive, bool deep) const || (error = archive->AddString("description", fDescription)) != B_OK || (error = archive->AddString("vendor", fVendor)) != B_OK || (error = archive->AddString("packager", fPackager)) != B_OK + || (error = archive->AddString("basePackage", fBasePackage)) != B_OK || (error = archive->AddUInt32("flags", fFlags)) != B_OK || (error = archive->AddInt32("architecture", fArchitecture)) != B_OK || (error = _AddVersion(archive, "version", fVersion)) != B_OK @@ -1926,7 +1993,9 @@ BPackageInfo::GetConfigString(BString& _string) const .Write("urls", fURLList) .Write("source-urls", fSourceURLList) .Write("provides", fProvidesList) - .Write("requires", fRequiresList) + .BeginRequires(fBasePackage) + .Write("requires", fRequiresList) + .EndRequires() .Write("supplements", fSupplementsList) .Write("conflicts", fConflictsList) .Write("freshens", fFreshensList) diff --git a/src/kits/package/hpkg/PackageContentHandler.cpp b/src/kits/package/hpkg/PackageContentHandler.cpp index 1a2a201253..70bfc7e015 100644 --- a/src/kits/package/hpkg/PackageContentHandler.cpp +++ b/src/kits/package/hpkg/PackageContentHandler.cpp @@ -60,6 +60,7 @@ static const char* kAttributeNames[B_HPKG_ATTRIBUTE_ID_ENUM_COUNT + 1] = { "package:url", "package:source-url", "package:install-path", + "package:base-package", NULL }; diff --git a/src/kits/package/hpkg/ReaderImplBase.cpp b/src/kits/package/hpkg/ReaderImplBase.cpp index dd2e6d5602..5137d70213 100644 --- a/src/kits/package/hpkg/ReaderImplBase.cpp +++ b/src/kits/package/hpkg/ReaderImplBase.cpp @@ -335,6 +335,10 @@ ReaderImplBase::PackageAttributeHandler::HandleAttribute( fPackageInfoValue.SetTo(B_PACKAGE_INFO_PACKAGER, value.string); break; + case B_HPKG_ATTRIBUTE_ID_PACKAGE_BASE_PACKAGE: + fPackageInfoValue.SetTo(B_PACKAGE_INFO_BASE_PACKAGE, value.string); + break; + case B_HPKG_ATTRIBUTE_ID_PACKAGE_FLAGS: fPackageInfoValue.SetTo(B_PACKAGE_INFO_FLAGS, (uint32)value.unsignedInt); diff --git a/src/kits/package/hpkg/WriterImplBase.cpp b/src/kits/package/hpkg/WriterImplBase.cpp index df0469766d..e3abd7752a 100644 --- a/src/kits/package/hpkg/WriterImplBase.cpp +++ b/src/kits/package/hpkg/WriterImplBase.cpp @@ -399,6 +399,17 @@ WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList, packager->string = fPackageStringCache.Get(packageInfo.Packager().String()); attributeList.Add(packager); + // base package + if (!packageInfo.BasePackage().IsEmpty()) { + PackageAttribute* basePackage = new PackageAttribute( + B_HPKG_ATTRIBUTE_ID_PACKAGE_BASE_PACKAGE, + B_HPKG_ATTRIBUTE_TYPE_STRING, + B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE); + basePackage->string + = fPackageStringCache.Get(packageInfo.BasePackage()); + attributeList.Add(basePackage); + } + // flags PackageAttribute* flags = new PackageAttribute( B_HPKG_ATTRIBUTE_ID_PACKAGE_FLAGS, B_HPKG_ATTRIBUTE_TYPE_UINT,