From 3aeae97f65ba61b4d012c6489514eb47ef9a3825 Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Sat, 29 Jan 2011 17:59:58 +0000 Subject: [PATCH] * added type-support to BPackageResolvable * split BPackageResolvable, BPackageResolvableExpression and BPackageVersion into separate files git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40316 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/package/PackageInfo.h | 186 +++--- headers/os/package/PackageResolvable.h | 86 +++ .../os/package/PackageResolvableExpression.h | 65 ++ headers/os/package/PackageVersion.h | 46 ++ src/kits/package/Jamfile | 3 + src/kits/package/PackageInfo.cpp | 587 +++++++++--------- src/kits/package/PackageResolvable.cpp | 78 +++ .../package/PackageResolvableExpression.cpp | 76 +++ src/kits/package/PackageVersion.cpp | 97 +++ 9 files changed, 807 insertions(+), 417 deletions(-) create mode 100644 headers/os/package/PackageResolvable.h create mode 100644 headers/os/package/PackageResolvableExpression.h create mode 100644 headers/os/package/PackageVersion.h create mode 100644 src/kits/package/PackageResolvable.cpp create mode 100644 src/kits/package/PackageResolvableExpression.cpp create mode 100644 src/kits/package/PackageVersion.cpp diff --git a/headers/os/package/PackageInfo.h b/headers/os/package/PackageInfo.h index 85160ab5ca..bfcc3ae6d4 100644 --- a/headers/os/package/PackageInfo.h +++ b/headers/os/package/PackageInfo.h @@ -1,5 +1,5 @@ /* - * Copyright 2011, Oliver Tappe + * Copyright 2011, Haiku, Inc. * Distributed under the terms of the MIT License. */ #ifndef _PACKAGE__PACKAGE_INFO_H_ @@ -9,6 +9,10 @@ #include #include +#include +#include +#include + class BEntry; @@ -18,16 +22,28 @@ namespace BPackageKit { enum BPackageInfoIndex { B_PACKAGE_INFO_NAME = 0, - B_PACKAGE_INFO_SUMMARY, // single line, 70 chars max - B_PACKAGE_INFO_DESCRIPTION, // multiple lines possible - B_PACKAGE_INFO_VENDOR, // e.g. "Haiku Project" - B_PACKAGE_INFO_PACKAGER, // e-mail address preferred + B_PACKAGE_INFO_SUMMARY, // single line + B_PACKAGE_INFO_DESCRIPTION, // multiple lines possible + B_PACKAGE_INFO_VENDOR, // e.g. "Haiku Project" + B_PACKAGE_INFO_PACKAGER, // e-mail address preferred B_PACKAGE_INFO_ARCHITECTURE, - B_PACKAGE_INFO_VERSION, // [.[.]] - B_PACKAGE_INFO_COPYRIGHTS, // list - B_PACKAGE_INFO_LICENSES, // list - B_PACKAGE_INFO_PROVIDES, // list - B_PACKAGE_INFO_REQUIRES, // list + B_PACKAGE_INFO_VERSION, // [.[.]] + B_PACKAGE_INFO_COPYRIGHTS, // list + B_PACKAGE_INFO_LICENSES, // list + B_PACKAGE_INFO_PROVIDES, // list of resolvables this package provides, + // each optionally giving a version + B_PACKAGE_INFO_REQUIRES, // list of resolvables required by this package, + // each optionally specifying a version relation + // (e.g. libssl.so >= 0.9.8) + B_PACKAGE_INFO_SUPPLEMENTS, // list of resolvables that are supplemented + // by this package, i.e. this package marks + // itself as an extension to other packages + B_PACKAGE_INFO_CONFLICTS, // list of resolvables that inhibit installation + // of this package + B_PACKAGE_INFO_REPLACES, // list of resolvables that this package + // will replace (upon update) + B_PACKAGE_INFO_FRESHENS, // list of resolvables that this package + // contains a patch for // B_PACKAGE_INFO_ENUM_COUNT, }; @@ -42,81 +58,6 @@ enum BPackageArchitecture { }; -class BPackageVersion { -public: - BPackageVersion(); - BPackageVersion(const BString& major, - const BString& minor, const BString& micro, - uint8 release); - - status_t InitCheck() const; - - void GetVersionString(BString& string) const; - - void SetTo(const BString& major, - const BString& minor, const BString& micro, - uint8 release); - void Clear(); - - int Compare(const BPackageVersion& other) const; - // does a natural compare over major, minor - // and micro, finally comparing release - -private: - BString fMajor; - BString fMinor; - BString fMicro; - uint8 fRelease; -}; - - -class BPackageProvision { -public: - BPackageProvision(); - BPackageProvision(const BString& name, - const BPackageVersion& version - = BPackageVersion()); - - status_t InitCheck() const; - - void GetProvisionString(BString& string) const; - - void SetTo(const BString& name, - const BPackageVersion& version - = BPackageVersion()); - void Clear(); - -private: - BString fName; - BPackageVersion fVersion; -}; - - -class BPackageRequirement { -public: - BPackageRequirement(); - BPackageRequirement(const BString& name, - const BString& _operator = "", - const BPackageVersion& version - = BPackageVersion()); - - status_t InitCheck() const; - - void GetRequirementString(BString& string) const; - - void SetTo(const BString& name, - const BString& _operator = "", - const BPackageVersion& version - = BPackageVersion()); - void Clear(); - -private: - BString fName; - BString fOperator; - BPackageVersion fVersion; -}; - - /* * Keeps a list of package info elements (e.g. name, version, vendor, ...) which * will be converted to package attributes when creating a package. Usually, @@ -154,11 +95,19 @@ public: const BPackageVersion& Version() const; - const BObjectList& Copyrights() const; - const BObjectList& Licenses() const; + const BObjectList& CopyrightList() const; + const BObjectList& LicenseList() const; - const BObjectList& Requirements() const; - const BObjectList& Provisions() const; + const BObjectList& ProvidesList() const; + const BObjectList& + RequiresList() const; + const BObjectList& + SupplementsList() const; + const BObjectList& + ConflictsList() const; + const BObjectList& + FreshensList() const; + const BObjectList& ReplacesList() const; void SetName(const BString& name); void SetSummary(const BString& summary); @@ -171,37 +120,42 @@ public: void SetVersion(const BPackageVersion& version); - void ClearCopyrights(); + void ClearCopyrightList(); status_t AddCopyright(const BString& copyright); - void ClearLicenses(); + void ClearLicenseList(); status_t AddLicense(const BString& license); - void ClearProvisions(); - status_t AddProvision( - const BPackageProvision& provision); + void ClearProvidesList(); + status_t AddProvides(const BPackageResolvable& provides); - void ClearRequirements(); - status_t AddRequirement( - const BPackageRequirement& requirement); + void ClearRequiresList(); + status_t AddRequires( + const BPackageResolvableExpression& expr); + + void ClearSupplementsList(); + status_t AddSupplements( + const BPackageResolvableExpression& expr); + + void ClearConflictsList(); + status_t AddConflicts( + const BPackageResolvableExpression& expr); + + void ClearFreshensList(); + status_t AddFreshens( + const BPackageResolvableExpression& expr); + + void ClearReplacesList(); + status_t AddReplaces(const BString& replaces); void Clear(); public: - static status_t GetElementName( - BPackageInfoIndex index, - const char** name); - - static status_t GetArchitectureName( - BPackageArchitecture arch, - const char** name); + static const char* kElementNames[]; + static const char* kArchitectureNames[]; private: class Parser; - friend class Parser; - - static const char* kElementNames[]; - static const char* kArchitectureNames[]; private: BString fName; @@ -214,11 +168,19 @@ private: BPackageVersion fVersion; - BObjectList fCopyrights; - BObjectList fLicenses; + BObjectList fCopyrightList; + BObjectList fLicenseList; - BObjectList fProvisions; - BObjectList fRequirements; + BObjectList fProvidesList; + + BObjectList fRequiresList; + BObjectList fSupplementsList; + + BObjectList fConflictsList; + + BObjectList fFreshensList; + + BObjectList fReplacesList; }; diff --git a/headers/os/package/PackageResolvable.h b/headers/os/package/PackageResolvable.h new file mode 100644 index 0000000000..f3d20511ad --- /dev/null +++ b/headers/os/package/PackageResolvable.h @@ -0,0 +1,86 @@ +/* + * Copyright 2011, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ +#ifndef _PACKAGE__PACKAGE_RESOLVALBE_H_ +#define _PACKAGE__PACKAGE_RESOLVALBE_H_ + + +#include + +#include + + +namespace BPackageKit { + + +enum BPackageResolvableType { + B_PACKAGE_RESOLVABLE_TYPE_DEFAULT = 0, + B_PACKAGE_RESOLVABLE_TYPE_LIBRARY, + B_PACKAGE_RESOLVABLE_TYPE_COMMAND, + B_PACKAGE_RESOLVABLE_TYPE_APPLICATION, + B_PACKAGE_RESOLVABLE_TYPE_ADD_ON, + // + B_PACKAGE_RESOLVABLE_TYPE_ENUM_COUNT, +}; + + +/* + * Defines a resolvable (something other packages can depend upon). + * Each resolvable is defined as a name (with an optional type prefix) + * and an optional version. + * + * resolvable ::= ['='] + * name ::= [':'] + * type ::= 'lib' | 'cmd' | 'app' | 'add_on' + * + * The type doesn't have any specific meaning to the dependency resolver, + * it just facilitates doing specific queries on the repository (like "is + * there any package providing the 'svn' command that the user just typed?"). + * At a later stage, more types may be added in order to declare additional + * entities, e.g. translators. + * + * String examples: + * haiku=r1 + * lib:libssl=0.9.8i + * subversion=1.5 + * cmd:svn + */ +class BPackageResolvable { +public: + BPackageResolvable(); + BPackageResolvable(const BString& name, + BPackageResolvableType type + = B_PACKAGE_RESOLVABLE_TYPE_DEFAULT, + const BPackageVersion& version + = BPackageVersion()); + + status_t InitCheck() const; + + const BString& Name() const; + BPackageResolvableType Type() const; + const BPackageVersion& Version() const; + + void GetAsString(BString& string) const; + + void SetTo(const BString& name, + BPackageResolvableType type + = B_PACKAGE_RESOLVABLE_TYPE_DEFAULT, + const BPackageVersion& version + = BPackageVersion()); + void Clear(); + +public: + static const char* kTypeNames[]; + +private: + BString fName; + BPackageResolvableType fType; + BPackageVersion fVersion; +}; + + +} // namespace BPackageKit + + +#endif // _PACKAGE__PACKAGE_RESOLVALBE_H_ diff --git a/headers/os/package/PackageResolvableExpression.h b/headers/os/package/PackageResolvableExpression.h new file mode 100644 index 0000000000..718305d4af --- /dev/null +++ b/headers/os/package/PackageResolvableExpression.h @@ -0,0 +1,65 @@ +/* + * Copyright 2011, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ +#ifndef _PACKAGE__PACKAGE_RESOLVABLE_EXPRESSION_H_ +#define _PACKAGE__PACKAGE_RESOLVABLE_EXPRESSION_H_ + + +#include + +#include + + +namespace BPackageKit { + + +/* + * Expresses a constraint on a specific resolvable, either just a name + * or a name plus a relational operator and a version. + * Instances of these will be matched against all the BPackageResolvable(s) + * of individual packages in order to solve a package management request. + * + * resolvable-expression ::= [] + * op ::= '<' | '<=' | '==' | '>=' | '>' + * + * String examples: + * haiku==r1 + * lib:libssl==0.9.8 + * subversion>=1.5 + * cmd:svn + */ +class BPackageResolvableExpression { +public: + BPackageResolvableExpression(); + BPackageResolvableExpression( + const BString& name, + const BString& _operator = "", + const BPackageVersion& version + = BPackageVersion()); + + status_t InitCheck() const; + + const BString& Name() const; + const BString& Operator() const; + const BPackageVersion& Version() const; + + void GetAsString(BString& string) const; + + void SetTo(const BString& name, + const BString& _operator = "", + const BPackageVersion& version + = BPackageVersion()); + void Clear(); + +private: + BString fName; + BString fOperator; + BPackageVersion fVersion; +}; + + +} // namespace BPackageKit + + +#endif // _PACKAGE__PACKAGE_RESOLVABLE_EXPRESSION_H_ diff --git a/headers/os/package/PackageVersion.h b/headers/os/package/PackageVersion.h new file mode 100644 index 0000000000..08fd724edb --- /dev/null +++ b/headers/os/package/PackageVersion.h @@ -0,0 +1,46 @@ +/* + * Copyright 2011, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ +#ifndef _PACKAGE__PACKAGE_VERSION_H_ +#define _PACKAGE__PACKAGE_VERSION_H_ + + +#include + + +namespace BPackageKit { + + +class BPackageVersion { +public: + BPackageVersion(); + BPackageVersion(const BString& major, + const BString& minor, const BString& micro, + uint8 release); + + status_t InitCheck() const; + + void GetAsString(BString& string) const; + + void SetTo(const BString& major, + const BString& minor, const BString& micro, + uint8 release); + void Clear(); + + int Compare(const BPackageVersion& other) const; + // does a natural compare over major, minor + // and micro, finally comparing release + +private: + BString fMajor; + BString fMinor; + BString fMicro; + uint8 fRelease; +}; + + +} // namespace BPackageKit + + +#endif // _PACKAGE__PACKAGE_VERSION_H_ diff --git a/src/kits/package/Jamfile b/src/kits/package/Jamfile index e128baf068..6a7900dda0 100644 --- a/src/kits/package/Jamfile +++ b/src/kits/package/Jamfile @@ -41,7 +41,10 @@ SharedLibrary libpackage.so Job.cpp JobQueue.cpp PackageInfo.cpp + PackageResolvable.cpp + PackageResolvableExpression.cpp PackageRoster.cpp + PackageVersion.cpp RefreshRepositoryRequest.cpp RemoveRepositoryJob.cpp RepositoryCache.cpp diff --git a/src/kits/package/PackageInfo.cpp b/src/kits/package/PackageInfo.cpp index 58d93c0836..d89ab1d69f 100644 --- a/src/kits/package/PackageInfo.cpp +++ b/src/kits/package/PackageInfo.cpp @@ -14,12 +14,6 @@ #include #include -#include - -#include - - -using BPrivate::NaturalCompare; namespace BPackageKit { @@ -41,7 +35,6 @@ enum TokenType { TOKEN_OPEN_BRACKET, TOKEN_CLOSE_BRACKET, TOKEN_COMMA, - TOKEN_COLON, // TOKEN_EOF, }; @@ -83,11 +76,13 @@ private: BPackageArchitecture* value); void _ParseVersionValue(BPackageVersion* value, bool releaseIsOptional); - void _ParseStringList(BObjectList* value); - void _ParseProvisionList( - BObjectList* value); - void _ParseRequirementList( - BObjectList* value); + void _ParseStringList(BObjectList* value, + bool allowQuotedStrings = true); + void _ParseResolvableList( + BObjectList* value); + void _ParseResolvableExprList( + BObjectList* + value); void _Parse(BPackageInfo* packageInfo); @@ -215,10 +210,6 @@ BPackageInfo::Parser::_NextToken() case '\0': return Token(TOKEN_EOF, fPos); - case ':': - fPos++; - return Token(TOKEN_COLON, tokenPos); - case ',': fPos++; return Token(TOKEN_COMMA, tokenPos); @@ -285,7 +276,7 @@ BPackageInfo::Parser::_NextToken() { const char* start = fPos; while (isalnum(*fPos) || *fPos == '.' || *fPos == '-' - || *fPos == '_') { + || *fPos == '_' || *fPos == ':') { fPos++; } if (fPos == start) @@ -392,7 +383,8 @@ BPackageInfo::Parser::_ParseVersionValue(BPackageVersion* value, void -BPackageInfo::Parser::_ParseStringList(BObjectList* value) +BPackageInfo::Parser::_ParseStringList(BObjectList* value, bool + allowQuotedStrings) { Token openBracket = _NextToken(); if (openBracket.type != TOKEN_OPEN_BRACKET) @@ -411,8 +403,13 @@ BPackageInfo::Parser::_ParseStringList(BObjectList* value) } else needComma = true; - if (token.type != TOKEN_QUOTED_STRING && token.type != TOKEN_WORD) - throw ParseError("expected quoted-string or word", token.pos); + if (allowQuotedStrings) { + if (token.type != TOKEN_QUOTED_STRING && token.type != TOKEN_WORD) + throw ParseError("expected quoted-string or word", token.pos); + } else { + if (token.type != TOKEN_WORD) + throw ParseError("expected word", token.pos); + } value->AddItem(new BString(token.text)); } @@ -420,7 +417,8 @@ BPackageInfo::Parser::_ParseStringList(BObjectList* value) void -BPackageInfo::Parser::_ParseProvisionList(BObjectList* value) +BPackageInfo::Parser::_ParseResolvableList( + BObjectList* value) { Token openBracket = _NextToken(); if (openBracket.type != TOKEN_OPEN_BRACKET) @@ -428,19 +426,42 @@ BPackageInfo::Parser::_ParseProvisionList(BObjectList* value) bool needComma = false; while (true) { - Token name = _NextToken(); - if (name.type == TOKEN_CLOSE_BRACKET) + BPackageResolvableType type = B_PACKAGE_RESOLVABLE_TYPE_DEFAULT; + + Token word = _NextToken(); + if (word.type == TOKEN_CLOSE_BRACKET) return; if (needComma) { - if (name.type != TOKEN_COMMA) - throw ParseError("expected comma", name.pos); - name = _NextToken(); + if (word.type != TOKEN_COMMA) + throw ParseError("expected comma", word.pos); + word = _NextToken(); } else needComma = true; - if (name.type != TOKEN_WORD) - throw ParseError("expected word (a provision name)", name.pos); + if (word.type != TOKEN_WORD) + throw ParseError("expected word (a resolvable name)", word.pos); + + int32 colonPos = word.text.FindFirst(':'); + if (colonPos >= 0) { + BString typeName(word.text, colonPos); + for (int i = 0; i < B_PACKAGE_RESOLVABLE_TYPE_ENUM_COUNT; ++i) { + if (typeName.ICompare(BPackageResolvable::kTypeNames[i]) == 0) { + type = (BPackageResolvableType)i; + break; + } + } + if (type == B_PACKAGE_RESOLVABLE_TYPE_DEFAULT) { + BString error("resolvable type (:) must be one of ["); + for (int i = 1; i < B_PACKAGE_RESOLVABLE_TYPE_ENUM_COUNT; ++i) { + if (i > 1) + error << ","; + error << BPackageResolvable::kTypeNames[i]; + } + error << "]"; + throw ParseError(error, word.pos); + } + } BPackageVersion version; Token op = _NextToken(); @@ -451,14 +472,14 @@ BPackageInfo::Parser::_ParseProvisionList(BObjectList* value) else throw ParseError("expected '=', comma or ']'", op.pos); - value->AddItem(new BPackageProvision(name.text, version)); + value->AddItem(new BPackageResolvable(word.text, type, version)); } } void -BPackageInfo::Parser::_ParseRequirementList( - BObjectList* value) +BPackageInfo::Parser::_ParseResolvableExprList( + BObjectList* value) { Token openBracket = _NextToken(); if (openBracket.type != TOKEN_OPEN_BRACKET) @@ -478,7 +499,7 @@ BPackageInfo::Parser::_ParseRequirementList( needComma = true; if (name.type != TOKEN_WORD) - throw ParseError("expected word (a requirement name)", name.pos); + throw ParseError("expected word (a resolvable name)", name.pos); BPackageVersion version; Token op = _NextToken(); @@ -495,7 +516,8 @@ BPackageInfo::Parser::_ParseRequirementList( "expected '<', '<=', '==', '>=', '>', comma or ']'", op.pos); } - value->AddItem(new BPackageRequirement(name.text, op.text, version)); + value->AddItem( + new BPackageResolvableExpression(name.text, op.text, version)); } } @@ -539,6 +561,8 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) BString summary; _ParseStringValue(&summary); + if (summary.FindFirst('\n') >= 0) + throw ParseError("the summary contains linebreaks", t.pos); packageInfo->SetSummary(summary); seen[B_PACKAGE_INFO_SUMMARY] = true; } else if (t.text.ICompare(names[B_PACKAGE_INFO_DESCRIPTION]) == 0) { @@ -603,11 +627,11 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) throw ParseError(error, t.pos); } - BObjectList copyrights; - _ParseStringList(©rights); - int count = copyrights.CountItems(); + BObjectList copyrightList; + _ParseStringList(©rightList); + int count = copyrightList.CountItems(); for (int i = 0; i < count; ++i) - packageInfo->AddCopyright(*(copyrights.ItemAt(i))); + packageInfo->AddCopyright(*(copyrightList.ItemAt(i))); seen[B_PACKAGE_INFO_COPYRIGHTS] = true; } else if (t.text.ICompare(names[B_PACKAGE_INFO_LICENSES]) == 0) { if (seen[B_PACKAGE_INFO_LICENSES]) { @@ -616,11 +640,11 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) throw ParseError(error, t.pos); } - BObjectList licenses; - _ParseStringList(&licenses); - int count = licenses.CountItems(); + BObjectList licenseList; + _ParseStringList(&licenseList); + int count = licenseList.CountItems(); for (int i = 0; i < count; ++i) - packageInfo->AddLicense(*(licenses.ItemAt(i))); + packageInfo->AddLicense(*(licenseList.ItemAt(i))); seen[B_PACKAGE_INFO_LICENSES] = true; } else if (t.text.ICompare(names[B_PACKAGE_INFO_PROVIDES]) == 0) { if (seen[B_PACKAGE_INFO_PROVIDES]) { @@ -629,11 +653,11 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) throw ParseError(error, t.pos); } - BObjectList provisions; - _ParseProvisionList(&provisions); - int count = provisions.CountItems(); + BObjectList providesList; + _ParseResolvableList(&providesList); + int count = providesList.CountItems(); for (int i = 0; i < count; ++i) - packageInfo->AddProvision(*(provisions.ItemAt(i))); + packageInfo->AddProvides(*(providesList.ItemAt(i))); seen[B_PACKAGE_INFO_PROVIDES] = true; } else if (t.text.ICompare(names[B_PACKAGE_INFO_REQUIRES]) == 0) { if (seen[B_PACKAGE_INFO_REQUIRES]) { @@ -642,16 +666,69 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) throw ParseError(error, t.pos); } - BObjectList requirements; - _ParseRequirementList(&requirements); - int count = requirements.CountItems(); + BObjectList requiresList; + _ParseResolvableExprList(&requiresList); + int count = requiresList.CountItems(); for (int i = 0; i < count; ++i) - packageInfo->AddRequirement(*(requirements.ItemAt(i))); + packageInfo->AddRequires(*(requiresList.ItemAt(i))); seen[B_PACKAGE_INFO_REQUIRES] = true; + } 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); + } + + BObjectList supplementsList; + _ParseResolvableExprList(&supplementsList); + int count = supplementsList.CountItems(); + for (int i = 0; i < count; ++i) + packageInfo->AddRequires(*(supplementsList.ItemAt(i))); + seen[B_PACKAGE_INFO_SUPPLEMENTS] = true; + } 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); + } + + BObjectList conflictsList; + _ParseResolvableExprList(&conflictsList); + int count = conflictsList.CountItems(); + for (int i = 0; i < count; ++i) + packageInfo->AddRequires(*(conflictsList.ItemAt(i))); + seen[B_PACKAGE_INFO_CONFLICTS] = true; + } 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); + } + + BObjectList freshensList; + _ParseResolvableExprList(&freshensList); + int count = freshensList.CountItems(); + for (int i = 0; i < count; ++i) + packageInfo->AddRequires(*(freshensList.ItemAt(i))); + seen[B_PACKAGE_INFO_FRESHENS] = true; + } 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); + } + + BObjectList replacesList; + _ParseStringList(&replacesList, false); + int count = replacesList.CountItems(); + for (int i = 0; i < count; ++i) + packageInfo->AddRequires(*(replacesList.ItemAt(i))); + seen[B_PACKAGE_INFO_REPLACES] = true; } } - for (int i = 0; i < B_PACKAGE_INFO_ENUM_COUNT; ++i) { + // everything up to and including 'provides' is mandatory + for (int i = 0; i <= B_PACKAGE_INFO_PROVIDES; ++i) { if (!seen[i]) { BString error = BString(names[i]) << " is not being set anywhere!"; throw ParseError(error, fPos); @@ -660,197 +737,6 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) } -BPackageVersion::BPackageVersion() -{ -} - - -BPackageVersion::BPackageVersion(const BString& major, const BString& minor, - const BString& micro, uint8 release) - : - fMajor(major), - fMinor(minor), - fMicro(micro), - fRelease(release) -{ -} - - -status_t -BPackageVersion::InitCheck() const -{ - return fMajor.Length() > 0 ? B_OK : B_NO_INIT; -} - - -int -BPackageVersion::Compare(const BPackageVersion& other) const -{ - int majorDiff = NaturalCompare(fMajor.String(), other.fMajor.String()); - if (majorDiff != 0) - return majorDiff; - - int minorDiff = NaturalCompare(fMinor.String(), other.fMinor.String()); - if (minorDiff != 0) - return minorDiff; - - int microDiff = NaturalCompare(fMicro.String(), other.fMicro.String()); - if (microDiff != 0) - return microDiff; - - return (int)fRelease - (int)other.fRelease; -} - - -void -BPackageVersion::GetVersionString(BString& string) const -{ - string = fMajor; - - if (fMinor.Length() > 0) { - string << '.' << fMinor; - if (fMicro.Length() > 0) - string << '.' << fMicro; - } - - if (fRelease > 0) - string << '-' << fRelease; -} - - -void -BPackageVersion::SetTo(const BString& major, const BString& minor, - const BString& micro, uint8 release) -{ - fMajor = major; - fMinor = minor; - fMicro = micro; - fRelease = release; -} - - -void -BPackageVersion::Clear() -{ - fMajor.Truncate(0); - fMinor.Truncate(0); - fMicro.Truncate(0); - fRelease = 0; -} - - -BPackageProvision::BPackageProvision() -{ -} - - -BPackageProvision::BPackageProvision(const BString& name, - const BPackageVersion& version) - : - fName(name), - fVersion(version) -{ -} - - -status_t -BPackageProvision::InitCheck() const -{ - return fName.Length() > 0 ? B_OK : B_NO_INIT; -} - - -void -BPackageProvision::GetProvisionString(BString& string) const -{ - string = fName; - - if (fVersion.InitCheck() == B_OK) { - string << '='; - fVersion.GetVersionString(string); - } -} - - -void -BPackageProvision::SetTo(const BString& name, const BPackageVersion& version) -{ - fName = name; - fVersion = version; -} - - -void -BPackageProvision::Clear() -{ - fName.Truncate(0); - fVersion.Clear(); -} - - -BPackageRequirement::BPackageRequirement() -{ -} - - -BPackageRequirement::BPackageRequirement(const BString& name, - const BString& _operator, const BPackageVersion& version) - : - fName(name), - fOperator(_operator), - fVersion(version) -{ -} - - -status_t -BPackageRequirement::InitCheck() const -{ - if (fName.Length() == 0) - return B_NO_INIT; - - // either both or none of operator and version must be set - if (fOperator.Length() == 0 && fVersion.InitCheck() == B_OK) - return B_NO_INIT; - - if (fOperator.Length() > 0 && fVersion.InitCheck() != B_OK) - return B_NO_INIT; - - return B_OK; -} - - -void -BPackageRequirement::GetRequirementString(BString& string) const -{ - string = fName; - - if (fVersion.InitCheck() == B_OK) { - string << fOperator; - fVersion.GetVersionString(string); - } -} - - -void -BPackageRequirement::SetTo(const BString& name, const BString& _operator, - const BPackageVersion& version) -{ - fName = name; - fOperator = _operator; - fVersion = version; -} - - -void -BPackageRequirement::Clear() -{ - fName.Truncate(0); - fOperator.Truncate(0); - fVersion.Clear(); -} - - const char* BPackageInfo::kElementNames[B_PACKAGE_INFO_ENUM_COUNT] = { "name", "summary", @@ -863,6 +749,10 @@ const char* BPackageInfo::kElementNames[B_PACKAGE_INFO_ENUM_COUNT] = { "licenses", "provides", "requires", + "conflicts", + "supplements", + "replaces", + "freshens", }; @@ -877,10 +767,14 @@ BPackageInfo::kArchitectureNames[B_PACKAGE_ARCHITECTURE_ENUM_COUNT] = { BPackageInfo::BPackageInfo() : fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT), - fCopyrights(5, true), - fLicenses(5, true), - fProvisions(20, true), - fRequirements(20, true) + fCopyrightList(5, true), + fLicenseList(5, true), + fProvidesList(20, true), + fRequiresList(20, true), + fSupplementsList(20, true), + fConflictsList(5, true), + fFreshensList(5, true), + fReplacesList(5, true) { } @@ -942,8 +836,8 @@ BPackageInfo::InitCheck() const || fPackager.Length() == 0 || fArchitecture == B_PACKAGE_ARCHITECTURE_ENUM_COUNT || fVersion.InitCheck() != B_OK - || fCopyrights.IsEmpty() || fLicenses.IsEmpty() - || fProvisions.IsEmpty() || fRequirements.IsEmpty()) + || fCopyrightList.IsEmpty() || fLicenseList.IsEmpty() + || fProvidesList.IsEmpty()) return B_NO_INIT; return B_OK; @@ -1000,30 +894,58 @@ BPackageInfo::Version() const const BObjectList& -BPackageInfo::Copyrights() const +BPackageInfo::CopyrightList() const { - return fCopyrights; + return fCopyrightList; } const BObjectList& -BPackageInfo::Licenses() const +BPackageInfo::LicenseList() const { - return fLicenses; + return fLicenseList; } -const BObjectList& -BPackageInfo::Requirements() const +const BObjectList& +BPackageInfo::ProvidesList() const { - return fRequirements; + return fProvidesList; } -const BObjectList& -BPackageInfo::Provisions() const +const BObjectList& +BPackageInfo::RequiresList() const { - return fProvisions; + return fRequiresList; +} + + +const BObjectList& +BPackageInfo::SupplementsList() const +{ + return fSupplementsList; +} + + +const BObjectList& +BPackageInfo::ConflictsList() const +{ + return fConflictsList; +} + + +const BObjectList& +BPackageInfo::FreshensList() const +{ + return fFreshensList; +} + + +const BObjectList& +BPackageInfo::ReplacesList() const +{ + return fReplacesList; } @@ -1077,9 +999,9 @@ BPackageInfo::SetArchitecture(BPackageArchitecture architecture) void -BPackageInfo::ClearCopyrights() +BPackageInfo::ClearCopyrightList() { - fCopyrights.MakeEmpty(); + fCopyrightList.MakeEmpty(); } @@ -1090,14 +1012,14 @@ BPackageInfo::AddCopyright(const BString& copyright) if (newCopyright == NULL) return B_NO_MEMORY; - return fCopyrights.AddItem(newCopyright) ? B_OK : B_ERROR; + return fCopyrightList.AddItem(newCopyright) ? B_OK : B_ERROR; } void -BPackageInfo::ClearLicenses() +BPackageInfo::ClearLicenseList() { - fLicenses.MakeEmpty(); + fLicenseList.MakeEmpty(); } @@ -1108,45 +1030,120 @@ BPackageInfo::AddLicense(const BString& license) if (newLicense == NULL) return B_NO_MEMORY; - return fLicenses.AddItem(newLicense) ? B_OK : B_ERROR; + return fLicenseList.AddItem(newLicense) ? B_OK : B_ERROR; } void -BPackageInfo::ClearProvisions() +BPackageInfo::ClearProvidesList() { - fProvisions.MakeEmpty(); + fProvidesList.MakeEmpty(); } status_t -BPackageInfo::AddProvision(const BPackageProvision& provision) +BPackageInfo::AddProvides(const BPackageResolvable& provides) { - BPackageProvision* newProvision - = new (std::nothrow) BPackageProvision(provision); - if (newProvision == NULL) + BPackageResolvable* newProvides + = new (std::nothrow) BPackageResolvable(provides); + if (newProvides == NULL) return B_NO_MEMORY; - return fProvisions.AddItem(newProvision) ? B_OK : B_ERROR; + return fProvidesList.AddItem(newProvides) ? B_OK : B_ERROR; } void -BPackageInfo::ClearRequirements() +BPackageInfo::ClearRequiresList() { - fRequirements.MakeEmpty(); + fRequiresList.MakeEmpty(); } status_t -BPackageInfo::AddRequirement(const BPackageRequirement& requirement) +BPackageInfo::AddRequires(const BPackageResolvableExpression& requires) { - BPackageRequirement* newRequirement - = new (std::nothrow) BPackageRequirement(requirement); - if (newRequirement == NULL) + BPackageResolvableExpression* newRequires + = new (std::nothrow) BPackageResolvableExpression(requires); + if (newRequires == NULL) return B_NO_MEMORY; - return fRequirements.AddItem(newRequirement) ? B_OK : B_ERROR; + return fRequiresList.AddItem(newRequires) ? B_OK : B_ERROR; +} + + +void +BPackageInfo::ClearSupplementsList() +{ + fSupplementsList.MakeEmpty(); +} + + +status_t +BPackageInfo::AddSupplements(const BPackageResolvableExpression& supplements) +{ + BPackageResolvableExpression* newSupplements + = new (std::nothrow) BPackageResolvableExpression(supplements); + if (newSupplements == NULL) + return B_NO_MEMORY; + + return fSupplementsList.AddItem(newSupplements) ? B_OK : B_ERROR; +} + + +void +BPackageInfo::ClearConflictsList() +{ + fConflictsList.MakeEmpty(); +} + + +status_t +BPackageInfo::AddConflicts(const BPackageResolvableExpression& conflicts) +{ + BPackageResolvableExpression* newConflicts + = new (std::nothrow) BPackageResolvableExpression(conflicts); + if (newConflicts == NULL) + return B_NO_MEMORY; + + return fConflictsList.AddItem(newConflicts) ? B_OK : B_ERROR; +} + + +void +BPackageInfo::ClearFreshensList() +{ + fFreshensList.MakeEmpty(); +} + + +status_t +BPackageInfo::AddFreshens(const BPackageResolvableExpression& freshens) +{ + BPackageResolvableExpression* newFreshens + = new (std::nothrow) BPackageResolvableExpression(freshens); + if (newFreshens == NULL) + return B_NO_MEMORY; + + return fFreshensList.AddItem(newFreshens) ? B_OK : B_ERROR; +} + + +void +BPackageInfo::ClearReplacesList() +{ + fReplacesList.MakeEmpty(); +} + + +status_t +BPackageInfo::AddReplaces(const BString& replaces) +{ + BString* newReplaces = new (std::nothrow) BString(replaces); + if (newReplaces == NULL) + return B_NO_MEMORY; + + return fReplacesList.AddItem(newReplaces) ? B_OK : B_ERROR; } @@ -1160,34 +1157,14 @@ BPackageInfo::Clear() fPackager.Truncate(0); fVersion.Clear(); fArchitecture = B_PACKAGE_ARCHITECTURE_ENUM_COUNT; - fCopyrights.MakeEmpty(); - fLicenses.MakeEmpty(); - fRequirements.MakeEmpty(); - fProvisions.MakeEmpty(); -} - - -/*static*/ status_t -BPackageInfo::GetElementName(BPackageInfoIndex index, const char** name) -{ - if (index < 0 || index >= B_PACKAGE_INFO_ENUM_COUNT || name == NULL) - return B_BAD_VALUE; - - *name = kElementNames[index]; - - return B_OK; -} - - -/*static*/ status_t -BPackageInfo::GetArchitectureName(BPackageArchitecture arch, const char** name) -{ - if (arch < 0 || arch >= B_PACKAGE_ARCHITECTURE_ENUM_COUNT || name == NULL) - return B_BAD_VALUE; - - *name = kArchitectureNames[arch]; - - return B_OK; + fCopyrightList.MakeEmpty(); + fLicenseList.MakeEmpty(); + fRequiresList.MakeEmpty(); + fProvidesList.MakeEmpty(); + fSupplementsList.MakeEmpty(); + fConflictsList.MakeEmpty(); + fFreshensList.MakeEmpty(); + fReplacesList.MakeEmpty(); } diff --git a/src/kits/package/PackageResolvable.cpp b/src/kits/package/PackageResolvable.cpp new file mode 100644 index 0000000000..bd1060479a --- /dev/null +++ b/src/kits/package/PackageResolvable.cpp @@ -0,0 +1,78 @@ +/* + * Copyright 2011, Oliver Tappe + * Distributed under the terms of the MIT License. + */ + + +#include + + +namespace BPackageKit { + + +const char* +BPackageResolvable::kTypeNames[B_PACKAGE_RESOLVABLE_TYPE_ENUM_COUNT] = { + "", + "lib", + "cmd", + "app", + "add_on", +}; + + +BPackageResolvable::BPackageResolvable() + : + fType(B_PACKAGE_RESOLVABLE_TYPE_DEFAULT) +{ +} + + +BPackageResolvable::BPackageResolvable(const BString& name, + BPackageResolvableType type, const BPackageVersion& version) + : + fName(name), + fType(type), + fVersion(version) +{ +} + + +status_t +BPackageResolvable::InitCheck() const +{ + return fName.Length() > 0 ? B_OK : B_NO_INIT; +} + + +void +BPackageResolvable::GetAsString(BString& string) const +{ + // the type is part of the name + string = fName; + + if (fVersion.InitCheck() == B_OK) { + string << '='; + fVersion.GetAsString(string); + } +} + + +void +BPackageResolvable::SetTo(const BString& name, BPackageResolvableType type, + const BPackageVersion& version) +{ + fName = name; + fType = type; + fVersion = version; +} + + +void +BPackageResolvable::Clear() +{ + fName.Truncate(0); + fVersion.Clear(); +} + + +} // namespace BPackageKit diff --git a/src/kits/package/PackageResolvableExpression.cpp b/src/kits/package/PackageResolvableExpression.cpp new file mode 100644 index 0000000000..6409c0937b --- /dev/null +++ b/src/kits/package/PackageResolvableExpression.cpp @@ -0,0 +1,76 @@ +/* + * Copyright 2011, Oliver Tappe + * Distributed under the terms of the MIT License. + */ + + +#include + + +namespace BPackageKit { + + +BPackageResolvableExpression::BPackageResolvableExpression() +{ +} + + +BPackageResolvableExpression::BPackageResolvableExpression(const BString& name, + const BString& _operator, const BPackageVersion& version) + : + fName(name), + fOperator(_operator), + fVersion(version) +{ +} + + +status_t +BPackageResolvableExpression::InitCheck() const +{ + if (fName.Length() == 0) + return B_NO_INIT; + + // either both or none of operator and version must be set + if (fOperator.Length() == 0 && fVersion.InitCheck() == B_OK) + return B_NO_INIT; + + if (fOperator.Length() > 0 && fVersion.InitCheck() != B_OK) + return B_NO_INIT; + + return B_OK; +} + + +void +BPackageResolvableExpression::GetAsString(BString& string) const +{ + string = fName; + + if (fVersion.InitCheck() == B_OK) { + string << fOperator; + fVersion.GetAsString(string); + } +} + + +void +BPackageResolvableExpression::SetTo(const BString& name, + const BString& _operator, const BPackageVersion& version) +{ + fName = name; + fOperator = _operator; + fVersion = version; +} + + +void +BPackageResolvableExpression::Clear() +{ + fName.Truncate(0); + fOperator.Truncate(0); + fVersion.Clear(); +} + + +} // namespace BPackageKit diff --git a/src/kits/package/PackageVersion.cpp b/src/kits/package/PackageVersion.cpp new file mode 100644 index 0000000000..75d211705a --- /dev/null +++ b/src/kits/package/PackageVersion.cpp @@ -0,0 +1,97 @@ +/* + * Copyright 2011, Oliver Tappe + * Distributed under the terms of the MIT License. + */ + + +#include + +#include + + +using BPrivate::NaturalCompare; + + +namespace BPackageKit { + + +BPackageVersion::BPackageVersion() +{ +} + + +BPackageVersion::BPackageVersion(const BString& major, const BString& minor, + const BString& micro, uint8 release) + : + fMajor(major), + fMinor(minor), + fMicro(micro), + fRelease(release) +{ +} + + +status_t +BPackageVersion::InitCheck() const +{ + return fMajor.Length() > 0 ? B_OK : B_NO_INIT; +} + + +int +BPackageVersion::Compare(const BPackageVersion& other) const +{ + int majorDiff = NaturalCompare(fMajor.String(), other.fMajor.String()); + if (majorDiff != 0) + return majorDiff; + + int minorDiff = NaturalCompare(fMinor.String(), other.fMinor.String()); + if (minorDiff != 0) + return minorDiff; + + int microDiff = NaturalCompare(fMicro.String(), other.fMicro.String()); + if (microDiff != 0) + return microDiff; + + return (int)fRelease - (int)other.fRelease; +} + + +void +BPackageVersion::GetAsString(BString& string) const +{ + string = fMajor; + + if (fMinor.Length() > 0) { + string << '.' << fMinor; + if (fMicro.Length() > 0) + string << '.' << fMicro; + } + + if (fRelease > 0) + string << '-' << fRelease; +} + + +void +BPackageVersion::SetTo(const BString& major, const BString& minor, + const BString& micro, uint8 release) +{ + fMajor = major; + fMinor = minor; + fMicro = micro; + fRelease = release; +} + + +void +BPackageVersion::Clear() +{ + fMajor.Truncate(0); + fMinor.Truncate(0); + fMicro.Truncate(0); + fRelease = 0; +} + + +} // namespace BPackageKit