kits/package: allow to set BPackageResolvable to parsed string

Change-Id: I8ebb46b12a8af229d05994eb3cdd2d8180edc903
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7555
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
X512 2024-03-28 03:24:34 +09:00 committed by waddlesplash
parent 9b8fbc06c8
commit 8b5f785b6a
6 changed files with 104 additions and 38 deletions

View File

@ -202,6 +202,10 @@ public:
bool revisionIsOptional,
BPackageVersion& _version,
ParseErrorListener* listener = NULL);
static status_t ParseResolvableString(
const BString& string,
BPackageResolvable& _expression,
ParseErrorListener* listener = NULL);
static status_t ParseResolvableExpressionString(
const BString& string,
BPackageResolvableExpression& _expression,

View File

@ -61,6 +61,7 @@ public:
BString ToString() const;
status_t SetToString(const BString& expressionString);
void SetTo(const BString& name,
const BPackageVersion& version
= BPackageVersion(),

View File

@ -1156,6 +1156,14 @@ BPackageInfo::ParseVersionString(const BString& string, bool revisionIsOptional,
}
/*static*/ status_t
BPackageInfo::ParseResolvableString(const BString& string,
BPackageResolvable& _expression, ParseErrorListener* listener)
{
return Parser(listener).ParseResolvable(string, _expression);
}
/*static*/ status_t
BPackageInfo::ParseResolvableExpressionString(const BString& string,
BPackageResolvableExpression& _expression, ParseErrorListener* listener)

View File

@ -106,6 +106,31 @@ BPackageInfo::Parser::ParseVersion(const BString& versionString,
}
status_t
BPackageInfo::Parser::ParseResolvable(const BString& expressionString,
BPackageResolvable& _expression)
{
fPos = expressionString.String();
try {
Token token(TOKEN_STRING, fPos, expressionString.Length());
_ParseResolvable(_NextToken(), _expression);
} catch (const ParseError& error) {
if (fListener != NULL) {
int32 offset = error.pos - expressionString.String();
fListener->OnError(error.message, 1, offset);
}
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;
}
status_t
BPackageInfo::Parser::ParseResolvableExpression(const BString& expressionString,
BPackageResolvableExpression& _expression)
@ -427,6 +452,50 @@ BPackageInfo::Parser::_ParseVersionValue(Token& word, BPackageVersion* value,
}
void
BPackageInfo::Parser::_ParseResolvable(const Token& token,
BPackageResolvable& _value)
{
if (token.type != TOKEN_STRING) {
throw ParseError("expected word (a resolvable name)",
token.pos);
}
int32 errorPos;
if (!_IsValidResolvableName(token.text, &errorPos)) {
throw ParseError("invalid character in resolvable name",
token.pos + errorPos);
}
// parse version
BPackageVersion version;
Token op = _NextToken();
if (op.type == TOKEN_OPERATOR_ASSIGN) {
_ParseVersionValue(&version, true);
} else if (op.type == TOKEN_ITEM_SEPARATOR
|| op.type == TOKEN_CLOSE_BRACE || op.type == TOKEN_EOF) {
_RewindTo(op);
} else
throw ParseError("expected '=', comma or '}'", op.pos);
// parse compatible version
BPackageVersion compatibleVersion;
Token compatible = _NextToken();
if (compatible.type == TOKEN_STRING
&& (compatible.text == "compat"
|| compatible.text == "compatible")) {
op = _NextToken();
if (op.type == TOKEN_OPERATOR_GREATER_EQUAL) {
_ParseVersionValue(&compatibleVersion, true);
} else
_RewindTo(compatible);
} else
_RewindTo(compatible);
_value.SetTo(token.text, version, compatibleVersion);
}
void
BPackageInfo::Parser::_ParseResolvableExpression(const Token& token,
BPackageResolvableExpression& _value, BString* _basePackage)
@ -611,44 +680,9 @@ BPackageInfo::Parser::_ParseResolvableList(
virtual void operator()(const Token& token)
{
if (token.type != TOKEN_STRING) {
throw ParseError("expected word (a resolvable name)",
token.pos);
}
int32 errorPos;
if (!_IsValidResolvableName(token.text, &errorPos)) {
throw ParseError("invalid character in resolvable name",
token.pos + errorPos);
}
// parse version
BPackageVersion version;
Token op = parser._NextToken();
if (op.type == TOKEN_OPERATOR_ASSIGN) {
parser._ParseVersionValue(&version, true);
} else if (op.type == TOKEN_ITEM_SEPARATOR
|| op.type == TOKEN_CLOSE_BRACE) {
parser._RewindTo(op);
} else
throw ParseError("expected '=', comma or '}'", op.pos);
// parse compatible version
BPackageVersion compatibleVersion;
Token compatible = parser._NextToken();
if (compatible.type == TOKEN_STRING
&& (compatible.text == "compat"
|| compatible.text == "compatible")) {
op = parser._NextToken();
if (op.type == TOKEN_OPERATOR_GREATER_EQUAL) {
parser._ParseVersionValue(&compatibleVersion, true);
} else
parser._RewindTo(compatible);
} else
parser._RewindTo(compatible);
value->AddItem(new BPackageResolvable(token.text, version,
compatibleVersion));
BPackageResolvable expression;
parser._ParseResolvable(token, expression);
value->AddItem(new BPackageResolvable(expression));
}
} resolvableParser(*this, value);

View File

@ -27,6 +27,9 @@ public:
status_t ParseVersion(const BString& versionString,
bool revisionIsOptional,
BPackageVersion& _version);
status_t ParseResolvable(
const BString& expressionString,
BPackageResolvable& _expression);
status_t ParseResolvableExpression(
const BString& expressionString,
BPackageResolvableExpression& _expression);
@ -69,6 +72,9 @@ private:
static void _ParseVersionValue(Token& word,
BPackageVersion* value,
bool revisionIsOptional);
void _ParseResolvable(
const Token& token,
BPackageResolvable& _value);
void _ParseResolvableExpression(
const Token& token,
BPackageResolvableExpression& _value,

View File

@ -7,6 +7,7 @@
#include <package/PackageResolvable.h>
#include <package/hpkg/PackageInfoAttributeValue.h>
#include <package/PackageInfo.h>
namespace BPackageKit {
@ -81,6 +82,18 @@ BPackageResolvable::ToString() const
}
status_t
BPackageResolvable::SetToString(const BString& expressionString)
{
fName.Truncate(0);
fVersion.Clear();
fCompatibleVersion.Clear();
return BPackageInfo::ParseResolvableString(expressionString,
*this);
}
void
BPackageResolvable::SetTo(const BString& name, const BPackageVersion& version,
const BPackageVersion& compatibleVersion)