Completed PackageInfo-parser and fleshed out BPackageVersion, BPackageProvision and BPackageRequirement.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40313 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe 2011-01-28 23:36:08 +00:00
parent 28e96d8542
commit 30222ff141
2 changed files with 558 additions and 199 deletions

View File

@ -18,12 +18,12 @@ namespace BPackageKit {
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 BPackageInfoIndex {
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 @@ enum BPackageArchitecture {
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 @@ public:
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;

View File

@ -1,4 +1,3 @@
#include <stdio.h>
/*
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
* Distributed under the terms of the MIT License.
@ -17,6 +16,11 @@
#include <Entry.h>
#include <String.h>
#include <NaturalCompare.h>
using BPrivate::NaturalCompare;
namespace BPackageKit {
@ -37,7 +41,6 @@ enum TokenType {
TOKEN_OPEN_BRACKET,
TOKEN_CLOSE_BRACKET,
TOKEN_COMMA,
TOKEN_SEMICOLON,
TOKEN_COLON,
//
TOKEN_EOF,
@ -73,16 +76,24 @@ private:
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::ParseErrorListener::~ParseErrorListener()
BPackageInfo::Parser::Parser(ParseErrorListener* listener)
:
fListener(listener),
fPos(NULL),
fCurrentLine(0)
fPos(NULL)
{
}
@ -154,7 +164,6 @@ BPackageInfo::Parser::Parse(const BString& packageInfoString,
return B_BAD_VALUE;
fPos = packageInfoString.String();
fCurrentLine = 1;
try {
_Parse(packageInfo);
@ -164,7 +173,7 @@ BPackageInfo::Parser::Parse(const BString& packageInfoString,
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 @@ BPackageInfo::Parser::Parse(const BString& packageInfoString,
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::Token
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 @@ printf("2: %p\n", fPos);
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 @@ printf("2: %p\n", fPos);
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 @@ printf("2: %p\n", fPos);
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 @@ printf("2: %p\n", fPos);
lastWasEscape = false;
else if (*fPos == '\\')
lastWasEscape = true;
else if (*fPos == '\n')
fCurrentLine++;
fPos++;
}
if (*fPos != '"')
@ -297,6 +299,13 @@ printf("2: %p\n", fPos);
}
void
BPackageInfo::Parser::_RewindTo(const Token& token)
{
fPos = token.pos;
}
void
BPackageInfo::Parser::_ParseStringValue(BString* value)
{
@ -332,6 +341,165 @@ BPackageInfo::Parser::_ParseArchitectureValue(BPackageArchitecture* value)
}
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)
{
@ -343,11 +511,11 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo)
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 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo)
_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);
// 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(&copyrights);
// 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);
}
Token semicolon = _NextToken();
if (semicolon.type != TOKEN_SEMICOLON)
throw ParseError("expected semicolon [';']", semicolon.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(&copyrights);
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;
}
}
for (int i = 0; i < B_PACKAGE_INFO_ENUM_COUNT; ++i) {
@ -497,6 +660,197 @@ 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",
@ -514,7 +868,7 @@ const char* BPackageInfo::kElementNames[B_PACKAGE_INFO_ENUM_COUNT] = {
const char*
BPackageInfo::kArchitectureNames[B_PACKAGE_ARCHITECTURE_ENUM_COUNT] = {
"no_arch",
"any",
"x86",
"x86_gcc2",
};
@ -522,7 +876,7 @@ BPackageInfo::kArchitectureNames[B_PACKAGE_ARCHITECTURE_ENUM_COUNT] = {
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 @@ status_t
BPackageInfo::ReadFromConfigString(const BString& packageInfoString,
ParseErrorListener* listener)
{
MakeEmpty();
Clear();
Parser parser(listener);
return parser.Parse(packageInfoString, this);
@ -583,7 +937,15 @@ BPackageInfo::ReadFromConfigString(const BString& packageInfoString,
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 @@ BPackageInfo::AddCopyright(const BString& copyright)
}
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,55 +1112,6 @@ BPackageInfo::AddLicense(const BString& license)
}
status_t
BPackageInfo::RemoveLicense(const BString& license)
{
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;
}
}
return B_NAME_NOT_FOUND;
}
void
BPackageInfo::ClearRequirements()
{
fRequirements.MakeEmpty();
}
status_t
BPackageInfo::AddRequirement(const BPackageRequirement& requirement)
{
BPackageRequirement* newRequirement
= new (std::nothrow) BPackageRequirement(requirement);
if (newRequirement == NULL)
return B_NO_MEMORY;
return fRequirements.AddItem(newRequirement) ? B_OK : B_ERROR;
}
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()
{
@ -833,31 +1131,35 @@ BPackageInfo::AddProvision(const BPackageProvision& provision)
}
status_t
BPackageInfo::RemoveProvision(const BPackageProvision& provision)
void
BPackageInfo::ClearRequirements()
{
int32 count = fProvisions.CountItems();
for (int i = 0; i < count; ++i) {
if (fProvisions.ItemAt(i)->Compare(provision) == 0) {
delete fProvisions.RemoveItemAt(i);
return B_OK;
}
}
fRequirements.MakeEmpty();
}
return B_NAME_NOT_FOUND;
status_t
BPackageInfo::AddRequirement(const BPackageRequirement& requirement)
{
BPackageRequirement* newRequirement
= new (std::nothrow) BPackageRequirement(requirement);
if (newRequirement == NULL)
return B_NO_MEMORY;
return fRequirements.AddItem(newRequirement) ? B_OK : B_ERROR;
}
void
BPackageInfo::MakeEmpty()
BPackageInfo::Clear()
{
fName.Truncate(0);
fSummary.Truncate(0);
fDescription.Truncate(0);
fVendor.Truncate(0);
fPackager.Truncate(0);
fVersion.MakeEmpty();
fArchitecture = B_PACKAGE_ARCHITECTURE_NONE;
fVersion.Clear();
fArchitecture = B_PACKAGE_ARCHITECTURE_ENUM_COUNT;
fCopyrights.MakeEmpty();
fLicenses.MakeEmpty();
fRequirements.MakeEmpty();
@ -877,4 +1179,16 @@ BPackageInfo::GetElementName(BPackageInfoIndex index, const char** name)
}
/*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;
}
} // namespace BPackageKit