Author: zooey Date: 2011-01-29 18:59:58 +0100 (Sat, 29 Jan 2011) New Revision: 40316 Changeset: http://dev.haiku-os.org/changeset/40316 Added: haiku/trunk/headers/os/package/PackageResolvable.h haiku/trunk/headers/os/package/PackageResolvableExpression.h haiku/trunk/headers/os/package/PackageVersion.h haiku/trunk/src/kits/package/PackageResolvable.cpp haiku/trunk/src/kits/package/PackageResolvableExpression.cpp haiku/trunk/src/kits/package/PackageVersion.cpp Modified: haiku/trunk/headers/os/package/PackageInfo.h haiku/trunk/src/kits/package/Jamfile haiku/trunk/src/kits/package/PackageInfo.cpp Log: * added type-support to BPackageResolvable * split BPackageResolvable, BPackageResolvableExpression and BPackageVersion into separate files Modified: haiku/trunk/headers/os/package/PackageInfo.h =================================================================== --- haiku/trunk/headers/os/package/PackageInfo.h 2011-01-29 16:01:44 UTC (rev 40315) +++ haiku/trunk/headers/os/package/PackageInfo.h 2011-01-29 17:59:58 UTC (rev 40316) @@ -1,5 +1,5 @@ /* - * Copyright 2011, Oliver Tappe <zooey@xxxxxxxxxxxxxxx> + * Copyright 2011, Haiku, Inc. * Distributed under the terms of the MIT License. */ #ifndef _PACKAGE__PACKAGE_INFO_H_ @@ -9,7 +9,11 @@ #include <ObjectList.h> #include <String.h> +#include <package/PackageResolvable.h> +#include <package/PackageResolvableExpression.h> +#include <package/PackageVersion.h> + class BEntry; @@ -18,16 +22,28 @@ 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, // <major>[.<minor>[.<micro>]] - B_PACKAGE_INFO_COPYRIGHTS, // list - B_PACKAGE_INFO_LICENSES, // list - B_PACKAGE_INFO_PROVIDES, // list - B_PACKAGE_INFO_REQUIRES, // list + B_PACKAGE_INFO_VERSION, // <major>[.<minor>[.<micro>]] + 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 @@ }; -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 @@ const BPackageVersion& Version() const; - const BObjectList<BString>& Copyrights() const; - const BObjectList<BString>& Licenses() const; + const BObjectList<BString>& CopyrightList() const; + const BObjectList<BString>& LicenseList() const; - const BObjectList<BPackageRequirement>& Requirements() const; - const BObjectList<BPackageProvision>& Provisions() const; + const BObjectList<BPackageResolvable>& ProvidesList() const; + const BObjectList<BPackageResolvableExpression>& + RequiresList() const; + const BObjectList<BPackageResolvableExpression>& + SupplementsList() const; + const BObjectList<BPackageResolvableExpression>& + ConflictsList() const; + const BObjectList<BPackageResolvableExpression>& + FreshensList() const; + const BObjectList<BString>& ReplacesList() const; void SetName(const BString& name); void SetSummary(const BString& summary); @@ -171,39 +120,44 @@ 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 Clear(); + void ClearSupplementsList(); + status_t AddSupplements( + const BPackageResolvableExpression& expr); -public: - static status_t GetElementName( - BPackageInfoIndex index, - const char** name); + void ClearConflictsList(); + status_t AddConflicts( + const BPackageResolvableExpression& expr); - static status_t GetArchitectureName( - BPackageArchitecture arch, - const char** name); + void ClearFreshensList(); + status_t AddFreshens( + const BPackageResolvableExpression& expr); -private: - class Parser; - friend class Parser; + void ClearReplacesList(); + status_t AddReplaces(const BString& replaces); + void Clear(); + +public: static const char* kElementNames[]; static const char* kArchitectureNames[]; private: + class Parser; + +private: BString fName; BString fSummary; BString fDescription; @@ -214,11 +168,19 @@ BPackageVersion fVersion; - BObjectList<BString> fCopyrights; - BObjectList<BString> fLicenses; + BObjectList<BString> fCopyrightList; + BObjectList<BString> fLicenseList; - BObjectList<BPackageProvision> fProvisions; - BObjectList<BPackageRequirement> fRequirements; + BObjectList<BPackageResolvable> fProvidesList; + + BObjectList<BPackageResolvableExpression> fRequiresList; + BObjectList<BPackageResolvableExpression> fSupplementsList; + + BObjectList<BPackageResolvableExpression> fConflictsList; + + BObjectList<BPackageResolvableExpression> fFreshensList; + + BObjectList<BString> fReplacesList; }; Added: haiku/trunk/headers/os/package/PackageResolvable.h =================================================================== --- haiku/trunk/headers/os/package/PackageResolvable.h (rev 0) +++ haiku/trunk/headers/os/package/PackageResolvable.h 2011-01-29 17:59:58 UTC (rev 40316) @@ -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 <String.h> + +#include <package/PackageVersion.h> + + +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>['='<version>] + * name ::= [<type>':']<word> + * 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_ Added: haiku/trunk/headers/os/package/PackageResolvableExpression.h =================================================================== --- haiku/trunk/headers/os/package/PackageResolvableExpression.h (rev 0) +++ haiku/trunk/headers/os/package/PackageResolvableExpression.h 2011-01-29 17:59:58 UTC (rev 40316) @@ -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 <String.h> + +#include <package/PackageVersion.h> + + +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 ::= <name>[<op><version>] + * 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_ Added: haiku/trunk/headers/os/package/PackageVersion.h =================================================================== --- haiku/trunk/headers/os/package/PackageVersion.h (rev 0) +++ haiku/trunk/headers/os/package/PackageVersion.h 2011-01-29 17:59:58 UTC (rev 40316) @@ -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 <String.h> + + +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_ Modified: haiku/trunk/src/kits/package/Jamfile =================================================================== --- haiku/trunk/src/kits/package/Jamfile 2011-01-29 16:01:44 UTC (rev 40315) +++ haiku/trunk/src/kits/package/Jamfile 2011-01-29 17:59:58 UTC (rev 40316) @@ -41,7 +41,10 @@ Job.cpp JobQueue.cpp PackageInfo.cpp + PackageResolvable.cpp + PackageResolvableExpression.cpp PackageRoster.cpp + PackageVersion.cpp RefreshRepositoryRequest.cpp RemoveRepositoryJob.cpp RepositoryCache.cpp Modified: haiku/trunk/src/kits/package/PackageInfo.cpp =================================================================== --- haiku/trunk/src/kits/package/PackageInfo.cpp 2011-01-29 16:01:44 UTC (rev 40315) +++ haiku/trunk/src/kits/package/PackageInfo.cpp 2011-01-29 17:59:58 UTC (rev 40316) @@ -14,14 +14,8 @@ #include <File.h> #include <Entry.h> -#include <String.h> -#include <NaturalCompare.h> - -using BPrivate::NaturalCompare; - - namespace BPackageKit { @@ -41,7 +35,6 @@ TOKEN_OPEN_BRACKET, TOKEN_CLOSE_BRACKET, TOKEN_COMMA, - TOKEN_COLON, // TOKEN_EOF, }; @@ -83,11 +76,13 @@ BPackageArchitecture* value); void _ParseVersionValue(BPackageVersion* value, bool releaseIsOptional); - void _ParseStringList(BObjectList<BString>* value); - void _ParseProvisionList( - BObjectList<BPackageProvision>* value); - void _ParseRequirementList( - BObjectList<BPackageRequirement>* value); + void _ParseStringList(BObjectList<BString>* value, + bool allowQuotedStrings = true); + void _ParseResolvableList( + BObjectList<BPackageResolvable>* value); + void _ParseResolvableExprList( + BObjectList<BPackageResolvableExpression>* + value); void _Parse(BPackageInfo* packageInfo); @@ -215,10 +210,6 @@ 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 @@ { const char* start = fPos; while (isalnum(*fPos) || *fPos == '.' || *fPos == '-' - || *fPos == '_') { + || *fPos == '_' || *fPos == ':') { fPos++; } if (fPos == start) @@ -392,7 +383,8 @@ void -BPackageInfo::Parser::_ParseStringList(BObjectList<BString>* value) +BPackageInfo::Parser::_ParseStringList(BObjectList<BString>* value, bool + allowQuotedStrings) { Token openBracket = _NextToken(); if (openBracket.type != TOKEN_OPEN_BRACKET) @@ -411,8 +403,13 @@ } 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 @@ void -BPackageInfo::Parser::_ParseProvisionList(BObjectList<BPackageProvision>* value) +BPackageInfo::Parser::_ParseResolvableList( + BObjectList<BPackageResolvable>* value) { Token openBracket = _NextToken(); if (openBracket.type != TOKEN_OPEN_BRACKET) @@ -428,20 +426,43 @@ 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 (<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(); if (op.type == TOKEN_OPERATOR_ASSIGN) @@ -451,14 +472,14 @@ 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<BPackageRequirement>* value) +BPackageInfo::Parser::_ParseResolvableExprList( + BObjectList<BPackageResolvableExpression>* value) { Token openBracket = _NextToken(); if (openBracket.type != TOKEN_OPEN_BRACKET) @@ -478,7 +499,7 @@ 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 @@ "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 @@ 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 @@ throw ParseError(error, t.pos); } - BObjectList<BString> copyrights; - _ParseStringList(©rights); - int count = copyrights.CountItems(); + BObjectList<BString> 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 @@ throw ParseError(error, t.pos); } - BObjectList<BString> licenses; - _ParseStringList(&licenses); - int count = licenses.CountItems(); + BObjectList<BString> 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 @@ throw ParseError(error, t.pos); } - BObjectList<BPackageProvision> provisions; - _ParseProvisionList(&provisions); - int count = provisions.CountItems(); + BObjectList<BPackageResolvable> 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 @@ throw ParseError(error, t.pos); } - BObjectList<BPackageRequirement> requirements; - _ParseRequirementList(&requirements); - int count = requirements.CountItems(); + BObjectList<BPackageResolvableExpression> 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<BPackageResolvableExpression> 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<BPackageResolvableExpression> 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<BPackageResolvableExpression> 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<BString> 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 @@ } -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); [... truncated: 602 lines follow ...]