Author: zooey Date: 2011-01-29 00:36:08 +0100 (Sat, 29 Jan 2011) New Revision: 40313 Changeset: http://dev.haiku-os.org/changeset/40313 Modified: haiku/trunk/headers/os/package/PackageInfo.h haiku/trunk/src/kits/package/PackageInfo.cpp Log: Completed PackageInfo-parser and fleshed out BPackageVersion, BPackageProvision and BPackageRequirement. Modified: haiku/trunk/headers/os/package/PackageInfo.h =================================================================== --- haiku/trunk/headers/os/package/PackageInfo.h 2011-01-28 22:36:13 UTC (rev 40312) +++ haiku/trunk/headers/os/package/PackageInfo.h 2011-01-28 23:36:08 UTC (rev 40313) @@ -18,12 +18,12 @@ enum BPackageInfoIndex { B_PACKAGE_INFO_NAME = 0, - B_PACKAGE_INFO_SUMMARY, // single line, 72 chars max + 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_ARCHITECTURE, - B_PACKAGE_INFO_VERSION, + B_PACKAGE_INFO_VERSION, // <major>[.<minor>[.<micro>]] B_PACKAGE_INFO_COPYRIGHTS, // list B_PACKAGE_INFO_LICENSES, // list B_PACKAGE_INFO_PROVIDES, // list @@ -34,7 +34,7 @@ enum BPackageArchitecture { - B_PACKAGE_ARCHITECTURE_NONE = 0, + B_PACKAGE_ARCHITECTURE_ANY = 0, B_PACKAGE_ARCHITECTURE_X86, B_PACKAGE_ARCHITECTURE_X86_GCC2, // @@ -44,29 +44,76 @@ class BPackageVersion { public: - void MakeEmpty() {} + 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: - int Compare(const BPackageProvision& other) const - { - return fX.Compare(other.fX); - } + 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 fX; + BString fName; + BPackageVersion fVersion; }; class BPackageRequirement { public: - int Compare(const BPackageRequirement& other) const - { - return fX.Compare(other.fX); - } + 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 fX; + BString fName; + BString fOperator; + BPackageVersion fVersion; }; @@ -126,31 +173,29 @@ void ClearCopyrights(); status_t AddCopyright(const BString& copyright); - status_t RemoveCopyright(const BString& copyright); void ClearLicenses(); status_t AddLicense(const BString& license); - status_t RemoveLicense(const BString& license); void ClearProvisions(); status_t AddProvision( const BPackageProvision& provision); - status_t RemoveProvision( - const BPackageProvision& provision); void ClearRequirements(); status_t AddRequirement( const BPackageRequirement& requirement); - status_t RemoveRequirement( - const BPackageRequirement& requirement); - void MakeEmpty(); + void Clear(); public: static status_t GetElementName( BPackageInfoIndex index, const char** name); + static status_t GetArchitectureName( + BPackageArchitecture arch, + const char** name); + private: class Parser; friend class Parser; Modified: haiku/trunk/src/kits/package/PackageInfo.cpp =================================================================== --- haiku/trunk/src/kits/package/PackageInfo.cpp 2011-01-28 22:36:13 UTC (rev 40312) +++ haiku/trunk/src/kits/package/PackageInfo.cpp 2011-01-28 23:36:08 UTC (rev 40313) @@ -1,4 +1,3 @@ -#include <stdio.h> /* * Copyright 2011, Oliver Tappe <zooey@xxxxxxxxxxxxxxx> * Distributed under the terms of the MIT License. @@ -17,7 +16,12 @@ #include <Entry.h> #include <String.h> +#include <NaturalCompare.h> + +using BPrivate::NaturalCompare; + + namespace BPackageKit { @@ -37,7 +41,6 @@ TOKEN_OPEN_BRACKET, TOKEN_CLOSE_BRACKET, TOKEN_COMMA, - TOKEN_SEMICOLON, TOKEN_COLON, // TOKEN_EOF, @@ -73,16 +76,24 @@ struct Token; Token _NextToken(); + void _RewindTo(const Token& token); + void _ParseStringValue(BString* value); void _ParseArchitectureValue( BPackageArchitecture* value); + void _ParseVersionValue(BPackageVersion* value, + bool releaseIsOptional); + void _ParseStringList(BObjectList<BString>* value); + void _ParseProvisionList( + BObjectList<BPackageProvision>* value); + void _ParseRequirementList( + BObjectList<BPackageRequirement>* value); + void _Parse(BPackageInfo* packageInfo); private: ParseErrorListener* fListener; - const char* fPos; - int fCurrentLine; }; @@ -140,8 +151,7 @@ BPackageInfo::Parser::Parser(ParseErrorListener* listener) : fListener(listener), - fPos(NULL), - fCurrentLine(0) + fPos(NULL) { } @@ -154,7 +164,6 @@ return B_BAD_VALUE; fPos = packageInfoString.String(); - fCurrentLine = 1; try { _Parse(packageInfo); @@ -164,7 +173,7 @@ int line = 1; int column; int32 offset = error.pos - packageInfoString.String(); - int32 newlinePos = packageInfoString.FindLast('\n', offset); + int32 newlinePos = packageInfoString.FindLast('\n', offset - 1); if (newlinePos < 0) column = offset; else { @@ -178,6 +187,10 @@ fListener->OnError(error.message, line, column); } return B_BAD_DATA; + } catch (const std::bad_alloc& e) { + if (fListener != NULL) + fListener->OnError("out of memory", 0, 0); + return B_NO_MEMORY; } return B_OK; @@ -188,20 +201,15 @@ BPackageInfo::Parser::_NextToken() { // eat any whitespace or comments -printf("1: %p\n", fPos); bool inComment = false; while ((inComment && *fPos != '\0') || isspace(*fPos) || *fPos == '#') { -printf("1b: %p\n", fPos); if (*fPos == '#') inComment = true; - else if (*fPos == '\n') { + else if (*fPos == '\n') inComment = false; - fCurrentLine++; - } fPos++; } -printf("2: %p\n", fPos); const char* tokenPos = fPos; switch (*fPos) { case '\0': @@ -215,10 +223,6 @@ fPos++; return Token(TOKEN_COMMA, tokenPos); - case ';': - fPos++; - return Token(TOKEN_SEMICOLON, tokenPos); - case '[': fPos++; return Token(TOKEN_OPEN_BRACKET, tokenPos); @@ -231,22 +235,22 @@ fPos++; if (*fPos == '=') { fPos++; - return Token(TOKEN_OPERATOR_LESS_EQUAL, tokenPos); + return Token(TOKEN_OPERATOR_LESS_EQUAL, tokenPos, 2); } - return Token(TOKEN_OPERATOR_LESS, tokenPos); + return Token(TOKEN_OPERATOR_LESS, tokenPos, 1); case '=': fPos++; if (*fPos == '=') { fPos++; - return Token(TOKEN_OPERATOR_EQUAL, tokenPos); + return Token(TOKEN_OPERATOR_EQUAL, tokenPos, 2); } - return Token(TOKEN_OPERATOR_ASSIGN, tokenPos); + return Token(TOKEN_OPERATOR_ASSIGN, tokenPos, 1); case '!': if (fPos[1] == '=') { fPos += 2; - return Token(TOKEN_OPERATOR_NOT_EQUAL, tokenPos); + return Token(TOKEN_OPERATOR_NOT_EQUAL, tokenPos, 2); } break; @@ -254,9 +258,9 @@ fPos++; if (*fPos == '=') { fPos++; - return Token(TOKEN_OPERATOR_GREATER_EQUAL, tokenPos); + return Token(TOKEN_OPERATOR_GREATER_EQUAL, tokenPos, 2); } - return Token(TOKEN_OPERATOR_GREATER, tokenPos); + return Token(TOKEN_OPERATOR_GREATER, tokenPos, 1); case '"': { @@ -269,8 +273,6 @@ lastWasEscape = false; else if (*fPos == '\\') lastWasEscape = true; - else if (*fPos == '\n') - fCurrentLine++; fPos++; } if (*fPos != '"') @@ -298,6 +300,13 @@ void +BPackageInfo::Parser::_RewindTo(const Token& token) +{ + fPos = token.pos; +} + + +void BPackageInfo::Parser::_ParseStringValue(BString* value) { Token string = _NextToken(); @@ -333,6 +342,165 @@ void +BPackageInfo::Parser::_ParseVersionValue(BPackageVersion* value, + bool releaseIsOptional) +{ + Token word = _NextToken(); + if (word.type != TOKEN_WORD) + throw ParseError("expected word (a version)", word.pos); + + uint8 release = 0; + int32 lastDashPos = word.text.FindLast('-'); + if (lastDashPos < 0) { + if (!releaseIsOptional) { + throw ParseError("expected release number (-<number> suffix)", + word.pos + word.text.Length()); + } + } else { + int number = atoi(word.text.String() + lastDashPos + 1); + if (number <= 0 || number > 99) { + throw ParseError("release number must be from 1-99", + word.pos + word.text.Length()); + } + release = number; + word.text.Truncate(lastDashPos); + } + + BString major; + BString minor; + BString micro; + int32 firstDotPos = word.text.FindFirst('.'); + if (firstDotPos < 0) + major = word.text; + else { + word.text.CopyInto(major, 0, firstDotPos); + int32 secondDotPos = word.text.FindFirst('.', firstDotPos + 1); + if (secondDotPos == firstDotPos + 1) + throw ParseError("expected minor version", word.pos + secondDotPos); + + if (secondDotPos < 0) + word.text.CopyInto(minor, firstDotPos + 1, word.text.Length()); + else { + word.text.CopyInto(minor, firstDotPos + 1, + secondDotPos - firstDotPos + 1); + word.text.CopyInto(micro, secondDotPos + 1, word.text.Length()); + } + } + + value->SetTo(major, minor, micro, release); +} + + +void +BPackageInfo::Parser::_ParseStringList(BObjectList<BString>* value) +{ + Token openBracket = _NextToken(); + if (openBracket.type != TOKEN_OPEN_BRACKET) + throw ParseError("expected start of list ('[')", openBracket.pos); + + bool needComma = false; + while (true) { + Token token = _NextToken(); + if (token.type == TOKEN_CLOSE_BRACKET) + return; + + if (needComma) { + if (token.type != TOKEN_COMMA) + throw ParseError("expected comma", token.pos); + token = _NextToken(); + } else + needComma = true; + + if (token.type != TOKEN_QUOTED_STRING && token.type != TOKEN_WORD) + throw ParseError("expected quoted-string or word", token.pos); + + value->AddItem(new BString(token.text)); + } +} + + +void +BPackageInfo::Parser::_ParseProvisionList(BObjectList<BPackageProvision>* value) +{ + Token openBracket = _NextToken(); + if (openBracket.type != TOKEN_OPEN_BRACKET) + throw ParseError("expected start of list ('[')", openBracket.pos); + + bool needComma = false; + while (true) { + Token name = _NextToken(); + if (name.type == TOKEN_CLOSE_BRACKET) + return; + + if (needComma) { + if (name.type != TOKEN_COMMA) + throw ParseError("expected comma", name.pos); + name = _NextToken(); + } else + needComma = true; + + if (name.type != TOKEN_WORD) + throw ParseError("expected word (a provision name)", name.pos); + + BPackageVersion version; + Token op = _NextToken(); + if (op.type == TOKEN_OPERATOR_ASSIGN) + _ParseVersionValue(&version, true); + else if (op.type == TOKEN_COMMA || op.type == TOKEN_CLOSE_BRACKET) + _RewindTo(op); + else + throw ParseError("expected '=', comma or ']'", op.pos); + + value->AddItem(new BPackageProvision(name.text, version)); + } +} + + +void +BPackageInfo::Parser::_ParseRequirementList( + BObjectList<BPackageRequirement>* value) +{ + Token openBracket = _NextToken(); + if (openBracket.type != TOKEN_OPEN_BRACKET) + throw ParseError("expected start of list ('[')", openBracket.pos); + + bool needComma = false; + while (true) { + Token name = _NextToken(); + if (name.type == TOKEN_CLOSE_BRACKET) + return; + + if (needComma) { + if (name.type != TOKEN_COMMA) + throw ParseError("expected comma", name.pos); + name = _NextToken(); + } else + needComma = true; + + if (name.type != TOKEN_WORD) + throw ParseError("expected word (a requirement name)", name.pos); + + BPackageVersion version; + Token op = _NextToken(); + if (op.type == TOKEN_OPERATOR_LESS + || op.type == TOKEN_OPERATOR_LESS_EQUAL + || op.type == TOKEN_OPERATOR_EQUAL + || op.type == TOKEN_OPERATOR_GREATER_EQUAL + || op.type == TOKEN_OPERATOR_GREATER) + _ParseVersionValue(&version, true); + else if (op.type == TOKEN_COMMA || op.type == TOKEN_CLOSE_BRACKET) + _RewindTo(op); + else { + throw ParseError( + "expected '<', '<=', '==', '>=', '>', comma or ']'", op.pos); + } + + value->AddItem(new BPackageRequirement(name.text, op.text, version)); + } +} + + +void BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) { bool seen[B_PACKAGE_INFO_ENUM_COUNT]; @@ -343,11 +511,11 @@ while (Token t = _NextToken()) { if (t.type != TOKEN_WORD) - throw ParseError("expected word [a variable name]", t.pos); + throw ParseError("expected word (a variable name)", t.pos); Token opAssign = _NextToken(); if (opAssign.type != TOKEN_OPERATOR_ASSIGN) { - throw ParseError("expected assignment operator ['=']", + throw ParseError("expected assignment operator ('=')", opAssign.pos); } @@ -417,75 +585,70 @@ _ParseArchitectureValue(&architecture); packageInfo->SetArchitecture(architecture); 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; + _ParseVersionValue(&version, false); + packageInfo->SetVersion(version); + 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); + } + + BObjectList<BString> copyrights; + _ParseStringList(©rights); + int count = copyrights.CountItems(); + for (int i = 0; i < count; ++i) + packageInfo->AddCopyright(*(copyrights.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]) { + BString error = BString(names[B_PACKAGE_INFO_LICENSES]) + << " already seen!"; + throw ParseError(error, t.pos); + } + + BObjectList<BString> licenses; + _ParseStringList(&licenses); + int count = licenses.CountItems(); + for (int i = 0; i < count; ++i) + packageInfo->AddLicense(*(licenses.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]) { + BString error = BString(names[B_PACKAGE_INFO_PROVIDES]) + << " already seen!"; + throw ParseError(error, t.pos); + } + + BObjectList<BPackageProvision> provisions; + _ParseProvisionList(&provisions); + int count = provisions.CountItems(); + for (int i = 0; i < count; ++i) + packageInfo->AddProvision(*(provisions.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]) { + BString error = BString(names[B_PACKAGE_INFO_REQUIRES]) + << " already seen!"; + throw ParseError(error, t.pos); + } + + BObjectList<BPackageRequirement> requirements; + _ParseRequirementList(&requirements); + int count = requirements.CountItems(); + for (int i = 0; i < count; ++i) + packageInfo->AddRequirement(*(requirements.ItemAt(i))); + seen[B_PACKAGE_INFO_REQUIRES] = 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; -// _ParseVersionValue(&version); -// packageInfo->SetVersion(version); -// 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); -// } -// -// BObjectList<BString> copyrights; -// _ParseStringList(©rights); -// int count = copyrights.CountItems(); -// for (int i = 0; i < count; ++i) -// packageInfo->AddCopyright(*(copyrights.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]) { -// BString error = BString(names[B_PACKAGE_INFO_LICENSES]) -// << " already seen!"; -// throw ParseError(error, t.pos); -// } -// -// BObjectList<BString> licenses; -// _ParseStringList(&licenses); -// int count = licenses.CountItems(); -// for (int i = 0; i < count; ++i) -// packageInfo->AddLicense(*(licenses.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]) { -// BString error = BString(names[B_PACKAGE_INFO_PROVIDES]) -// << " already seen!"; -// throw ParseError(error, t.pos); -// } -// -// BObjectList<BPackageProvision> provisions; -// _ParseProvisionList(&provisions); -// int count = provisions.CountItems(); -// for (int i = 0; i < count; ++i) -// packageInfo->AddProvision(*(provisions.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]) { -// BString error = BString(names[B_PACKAGE_INFO_REQUIRES]) -// << " already seen!"; -// throw ParseError(error, t.pos); -// } -// -// BObjectList<BPackageRequirement> requirements; -// _ParseRequirementList(&requirements); -// int count = requirements.CountItems(); -// for (int i = 0; i < count; ++i) -// packageInfo->AddRequirement(*(requirements.ItemAt(i))); -// seen[B_PACKAGE_INFO_REQUIRES] = true; -// } - - Token semicolon = _NextToken(); - if (semicolon.type != TOKEN_SEMICOLON) - throw ParseError("expected semicolon [';']", semicolon.pos); } for (int i = 0; i < B_PACKAGE_INFO_ENUM_COUNT; ++i) { @@ -497,6 +660,197 @@ } +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", @@ -514,7 +868,7 @@ const char* BPackageInfo::kArchitectureNames[B_PACKAGE_ARCHITECTURE_ENUM_COUNT] = { - "no_arch", + "any", "x86", "x86_gcc2", }; @@ -522,7 +876,7 @@ BPackageInfo::BPackageInfo() : - fArchitecture(B_PACKAGE_ARCHITECTURE_NONE), + fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT), fCopyrights(5, true), fLicenses(5, true), fProvisions(20, true), @@ -573,7 +927,7 @@ BPackageInfo::ReadFromConfigString(const BString& packageInfoString, ParseErrorListener* listener) { - MakeEmpty(); + Clear(); Parser parser(listener); return parser.Parse(packageInfoString, this); @@ -583,7 +937,15 @@ status_t BPackageInfo::InitCheck() const { - // TODO + if (fName.Length() == 0 || fSummary.Length() == 0 + || fDescription.Length() == 0 || fVendor.Length() == 0 + || fPackager.Length() == 0 + || fArchitecture == B_PACKAGE_ARCHITECTURE_ENUM_COUNT + || fVersion.InitCheck() != B_OK + || fCopyrights.IsEmpty() || fLicenses.IsEmpty() + || fProvisions.IsEmpty() || fRequirements.IsEmpty()) + return B_NO_INIT; + return B_OK; } @@ -732,21 +1094,6 @@ } -status_t -BPackageInfo::RemoveCopyright(const BString& copyright) -{ - int32 count = fCopyrights.CountItems(); - for (int i = 0; i < count; ++i) { - if (fCopyrights.ItemAt(i)->Compare(copyright) == 0) { - delete fCopyrights.RemoveItemAt(i); - return B_OK; - } - } - - return B_NAME_NOT_FOUND; -} - - void BPackageInfo::ClearLicenses() { @@ -765,18 +1112,22 @@ } +void +BPackageInfo::ClearProvisions() +{ + fProvisions.MakeEmpty(); +} + + status_t -BPackageInfo::RemoveLicense(const BString& license) +BPackageInfo::AddProvision(const BPackageProvision& provision) { - int32 count = fLicenses.CountItems(); - for (int i = 0; i < count; ++i) { - if (fLicenses.ItemAt(i)->Compare(license) == 0) { - delete fLicenses.RemoveItemAt(i); - return B_OK; - } - } + BPackageProvision* newProvision + = new (std::nothrow) BPackageProvision(provision); + if (newProvision == NULL) + return B_NO_MEMORY; - return B_NAME_NOT_FOUND; + return fProvisions.AddItem(newProvision) ? B_OK : B_ERROR; } @@ -799,65 +1150,16 @@ } -status_t -BPackageInfo::RemoveRequirement(const BPackageRequirement& requirement) -{ - int32 count = fRequirements.CountItems(); - for (int i = 0; i < count; ++i) { - if (fRequirements.ItemAt(i)->Compare(requirement)) { - delete fRequirements.RemoveItemAt(i); - return B_OK; - } - } - - return B_NAME_NOT_FOUND; -} - - void -BPackageInfo::ClearProvisions() +BPackageInfo::Clear() { - fProvisions.MakeEmpty(); -} - - -status_t -BPackageInfo::AddProvision(const BPackageProvision& provision) -{ - BPackageProvision* newProvision - = new (std::nothrow) BPackageProvision(provision); - if (newProvision == NULL) - return B_NO_MEMORY; - - return fProvisions.AddItem(newProvision) ? B_OK : B_ERROR; -} - - -status_t [... truncated: 47 lines follow ...]