xref: /haiku/src/kits/package/PackageInfoParser.h (revision 9f3bdf3d039430b5172c424def20ce5d9f7367d4)
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 
13 namespace BPackageKit {
14 
15 
16 /*
17  * Parses a ".PackageInfo" file and fills a BPackageInfo object with the
18  * package info elements found.
19  */
20 class BPackageInfo::Parser {
21 public:
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 
37 private:
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 
61 private:
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 
115 private:
116 			ParseErrorListener*	fListener;
117 			const char*			fPos;
118 };
119 
120 
121 struct 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 
132 struct 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 
156 struct BPackageInfo::Parser::ListElementParser {
157 	virtual ~ListElementParser()
158 	{
159 	}
160 
161 	virtual void operator()(const Token& token) = 0;
162 };
163 
164 
165 struct BPackageInfo::Parser::StringValidator {
166 public:
167 	virtual void Validate(const BString &string, const char *pos) = 0;
168 };
169 
170 
171 struct BPackageInfo::Parser::UrlStringValidator
172     : public BPackageInfo::Parser::StringValidator {
173 public:
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