/* * Copyright 2011, Oliver Tappe * Copyright 2016, Andrew Lindesay * Distributed under the terms of the MIT License. */ #ifndef PACKAGE_INFO_PARSER_H #define PACKAGE_INFO_PARSER_H #include namespace BPackageKit { /* * Parses a ".PackageInfo" file and fills a BPackageInfo object with the * package info elements found. */ class BPackageInfo::Parser { public: Parser(ParseErrorListener* listener = NULL); status_t Parse(const BString& packageInfoString, BPackageInfo* packageInfo); 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); private: struct UrlStringValidator; struct StringValidator; struct ParseError; struct Token; struct ListElementParser; friend struct ListElementParser; enum TokenType { TOKEN_STRING, TOKEN_OPERATOR_ASSIGN, TOKEN_OPERATOR_LESS, TOKEN_OPERATOR_LESS_EQUAL, TOKEN_OPERATOR_EQUAL, TOKEN_OPERATOR_NOT_EQUAL, TOKEN_OPERATOR_GREATER_EQUAL, TOKEN_OPERATOR_GREATER, TOKEN_OPEN_BRACE, TOKEN_CLOSE_BRACE, TOKEN_ITEM_SEPARATOR, // TOKEN_EOF, }; private: Token _NextToken(); void _RewindTo(const Token& token); void _ParseStringValue(BString* value, const char** _tokenPos = NULL); uint32 _ParseFlags(); void _ParseArchitectureValue( BPackageArchitecture* value); void _ParseVersionValue(BPackageVersion* value, bool revisionIsOptional); static void _ParseVersionValue(Token& word, BPackageVersion* value, bool revisionIsOptional); void _ParseResolvable( const Token& token, BPackageResolvable& _value); void _ParseResolvableExpression( const Token& token, BPackageResolvableExpression& _value, BString* _basePackage); void _ParseList(ListElementParser& elementParser, bool allowSingleNonListElement); void _ParseStringList(BStringList* value, bool requireResolvableName = false, bool convertToLowerCase = false, StringValidator* stringValidator = NULL); void _ParseResolvableList( BObjectList* value); void _ParseResolvableExprList( BObjectList* value, BString* _basePackage = NULL); void _ParseGlobalWritableFileInfos( GlobalWritableFileInfoList* infos); void _ParseUserSettingsFileInfos( UserSettingsFileInfoList* infos); void _ParseUsers(UserList* users); void _Parse(BPackageInfo* packageInfo); static bool _IsAlphaNumUnderscore(const BString& string, const char* additionalChars, int32* _errorPos); static bool _IsAlphaNumUnderscore(const char* string, const char* additionalChars, int32* _errorPos); static bool _IsAlphaNumUnderscore(const char* start, const char* end, const char* additionalChars, int32* _errorPos); static bool _IsValidResolvableName(const char* string, int32* _errorPos); private: ParseErrorListener* fListener; const char* fPos; }; struct BPackageInfo::Parser::ParseError { BString message; const char* pos; ParseError(const BString& _message, const char* _pos) : message(_message), pos(_pos) { } }; struct BPackageInfo::Parser::Token { TokenType type; BString text; const char* pos; Token(TokenType _type, const char* _pos, int length = 0, const char* text = NULL) : type(_type), pos(_pos) { if (text != NULL) this->text = text; else if (length != 0) this->text.SetTo(pos, length); } operator bool() const { return type != TOKEN_EOF; } }; struct BPackageInfo::Parser::ListElementParser { virtual ~ListElementParser() { } virtual void operator()(const Token& token) = 0; }; struct BPackageInfo::Parser::StringValidator { public: virtual void Validate(const BString &string, const char *pos) = 0; }; struct BPackageInfo::Parser::UrlStringValidator : public BPackageInfo::Parser::StringValidator { public: virtual void Validate(const BString &string, const char* pos); }; } // namespace BPackageKit #endif // PACKAGE_INFO_PARSER_H