1/*
2 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
3 * Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef PACKAGE_INFO_PARSER_H
7#define PACKAGE_INFO_PARSER_H
8
9
10#include <package/PackageInfo.h>
11
12
13namespace BPackageKit {
14
15
16/*
17 * Parses a ".PackageInfo" file and fills a BPackageInfo object with the
18 * package info elements found.
19 */
20class BPackageInfo::Parser {
21public:
22								Parser(ParseErrorListener* listener = NULL);
23
24			status_t			Parse(const BString& packageInfoString,
25									BPackageInfo* packageInfo);
26
27			status_t			ParseVersion(const BString& versionString,
28									bool revisionIsOptional,
29									BPackageVersion& _version);
30			status_t			ParseResolvable(
31									const BString& expressionString,
32									BPackageResolvable& _expression);
33			status_t			ParseResolvableExpression(
34									const BString& expressionString,
35									BPackageResolvableExpression& _expression);
36
37private:
38			struct UrlStringValidator;
39			struct StringValidator;
40			struct ParseError;
41			struct Token;
42			struct ListElementParser;
43	friend	struct ListElementParser;
44
45			enum TokenType {
46				TOKEN_STRING,
47				TOKEN_OPERATOR_ASSIGN,
48				TOKEN_OPERATOR_LESS,
49				TOKEN_OPERATOR_LESS_EQUAL,
50				TOKEN_OPERATOR_EQUAL,
51				TOKEN_OPERATOR_NOT_EQUAL,
52				TOKEN_OPERATOR_GREATER_EQUAL,
53				TOKEN_OPERATOR_GREATER,
54				TOKEN_OPEN_BRACE,
55				TOKEN_CLOSE_BRACE,
56				TOKEN_ITEM_SEPARATOR,
57				//
58				TOKEN_EOF,
59			};
60
61private:
62			Token				_NextToken();
63			void				_RewindTo(const Token& token);
64
65			void				_ParseStringValue(BString* value,
66									const char** _tokenPos = NULL);
67			uint32				_ParseFlags();
68			void				_ParseArchitectureValue(
69									BPackageArchitecture* value);
70			void				_ParseVersionValue(BPackageVersion* value,
71									bool revisionIsOptional);
72	static	void				_ParseVersionValue(Token& word,
73									BPackageVersion* value,
74									bool revisionIsOptional);
75			void				_ParseResolvable(
76									const Token& token,
77									BPackageResolvable& _value);
78			void				_ParseResolvableExpression(
79									const Token& token,
80									BPackageResolvableExpression& _value,
81									BString* _basePackage);
82			void				_ParseList(ListElementParser& elementParser,
83									bool allowSingleNonListElement);
84			void				_ParseStringList(BStringList* value,
85									bool requireResolvableName = false,
86									bool convertToLowerCase = false,
87									StringValidator* stringValidator = NULL);
88			void				_ParseResolvableList(
89									BObjectList<BPackageResolvable>* value);
90			void				_ParseResolvableExprList(
91									BObjectList<BPackageResolvableExpression>*
92										value,
93									BString* _basePackage = NULL);
94			void				_ParseGlobalWritableFileInfos(
95									GlobalWritableFileInfoList* infos);
96			void				_ParseUserSettingsFileInfos(
97									UserSettingsFileInfoList* infos);
98			void				_ParseUsers(UserList* users);
99
100			void				_Parse(BPackageInfo* packageInfo);
101
102	static	bool				_IsAlphaNumUnderscore(const BString& string,
103									const char* additionalChars,
104									int32* _errorPos);
105	static	bool				_IsAlphaNumUnderscore(const char* string,
106									const char* additionalChars,
107									int32* _errorPos);
108	static	bool				_IsAlphaNumUnderscore(const char* start,
109									const char* end,
110									const char* additionalChars,
111									int32* _errorPos);
112	static	bool				_IsValidResolvableName(const char* string,
113									int32* _errorPos);
114
115private:
116			ParseErrorListener*	fListener;
117			const char*			fPos;
118};
119
120
121struct BPackageInfo::Parser::ParseError {
122	BString 	message;
123	const char*	pos;
124
125	ParseError(const BString& _message, const char* _pos)
126		: message(_message), pos(_pos)
127	{
128	}
129};
130
131
132struct BPackageInfo::Parser::Token {
133	TokenType	type;
134	BString		text;
135	const char*	pos;
136
137	Token(TokenType _type, const char* _pos, int length = 0,
138		const char* text = NULL)
139		:
140		type(_type),
141		pos(_pos)
142	{
143		if (text != NULL)
144			this->text = text;
145		else if (length != 0)
146			this->text.SetTo(pos, length);
147	}
148
149	operator bool() const
150	{
151		return type != TOKEN_EOF;
152	}
153};
154
155
156struct BPackageInfo::Parser::ListElementParser {
157	virtual ~ListElementParser()
158	{
159	}
160
161	virtual void operator()(const Token& token) = 0;
162};
163
164
165struct BPackageInfo::Parser::StringValidator {
166public:
167	virtual void Validate(const BString &string, const char *pos) = 0;
168};
169
170
171struct BPackageInfo::Parser::UrlStringValidator
172    : public BPackageInfo::Parser::StringValidator {
173public:
174	virtual	void				Validate(const BString &string, const char* pos);
175};
176
177
178} // namespace BPackageKit
179
180
181#endif	// PACKAGE_INFO_PARSER_H
182