xref: /haiku/src/kits/package/PackageInfoParser.h (revision 8a6724a0ee3803f1e9f487d8111bb3f6cb8d16db)
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			ParseResolvableExpression(
31 									const BString& expressionString,
32 									BPackageResolvableExpression& _expression);
33 
34 private:
35 			struct UrlStringValidator;
36 			struct StringValidator;
37 			struct ParseError;
38 			struct Token;
39 			struct ListElementParser;
40 	friend	struct ListElementParser;
41 
42 			enum TokenType {
43 				TOKEN_STRING,
44 				TOKEN_OPERATOR_ASSIGN,
45 				TOKEN_OPERATOR_LESS,
46 				TOKEN_OPERATOR_LESS_EQUAL,
47 				TOKEN_OPERATOR_EQUAL,
48 				TOKEN_OPERATOR_NOT_EQUAL,
49 				TOKEN_OPERATOR_GREATER_EQUAL,
50 				TOKEN_OPERATOR_GREATER,
51 				TOKEN_OPEN_BRACE,
52 				TOKEN_CLOSE_BRACE,
53 				TOKEN_ITEM_SEPARATOR,
54 				//
55 				TOKEN_EOF,
56 			};
57 
58 private:
59 			Token				_NextToken();
60 			void				_RewindTo(const Token& token);
61 
62 			void				_ParseStringValue(BString* value,
63 									const char** _tokenPos = NULL);
64 			uint32				_ParseFlags();
65 			void				_ParseArchitectureValue(
66 									BPackageArchitecture* value);
67 			void				_ParseVersionValue(BPackageVersion* value,
68 									bool revisionIsOptional);
69 	static	void				_ParseVersionValue(Token& word,
70 									BPackageVersion* value,
71 									bool revisionIsOptional);
72 			void				_ParseResolvableExpression(
73 									const Token& token,
74 									BPackageResolvableExpression& _value,
75 									BString* _basePackage);
76 			void				_ParseList(ListElementParser& elementParser,
77 									bool allowSingleNonListElement);
78 			void				_ParseStringList(BStringList* value,
79 									bool requireResolvableName = false,
80 									bool convertToLowerCase = false,
81 									StringValidator* stringValidator = NULL);
82 			void				_ParseResolvableList(
83 									BObjectList<BPackageResolvable>* value);
84 			void				_ParseResolvableExprList(
85 									BObjectList<BPackageResolvableExpression>*
86 										value,
87 									BString* _basePackage = NULL);
88 			void				_ParseGlobalWritableFileInfos(
89 									GlobalWritableFileInfoList* infos);
90 			void				_ParseUserSettingsFileInfos(
91 									UserSettingsFileInfoList* infos);
92 			void				_ParseUsers(UserList* users);
93 
94 			void				_Parse(BPackageInfo* packageInfo);
95 
96 	static	bool				_IsAlphaNumUnderscore(const BString& string,
97 									const char* additionalChars,
98 									int32* _errorPos);
99 	static	bool				_IsAlphaNumUnderscore(const char* string,
100 									const char* additionalChars,
101 									int32* _errorPos);
102 	static	bool				_IsAlphaNumUnderscore(const char* start,
103 									const char* end,
104 									const char* additionalChars,
105 									int32* _errorPos);
106 	static	bool				_IsValidResolvableName(const char* string,
107 									int32* _errorPos);
108 
109 private:
110 			ParseErrorListener*	fListener;
111 			const char*			fPos;
112 };
113 
114 
115 struct BPackageInfo::Parser::ParseError {
116 	BString 	message;
117 	const char*	pos;
118 
119 	ParseError(const BString& _message, const char* _pos)
120 		: message(_message), pos(_pos)
121 	{
122 	}
123 };
124 
125 
126 struct BPackageInfo::Parser::Token {
127 	TokenType	type;
128 	BString		text;
129 	const char*	pos;
130 
131 	Token(TokenType _type, const char* _pos, int length = 0,
132 		const char* text = NULL)
133 		:
134 		type(_type),
135 		pos(_pos)
136 	{
137 		if (text != NULL)
138 			this->text = text;
139 		else if (length != 0)
140 			this->text.SetTo(pos, length);
141 	}
142 
143 	operator bool() const
144 	{
145 		return type != TOKEN_EOF;
146 	}
147 };
148 
149 
150 struct BPackageInfo::Parser::ListElementParser {
151 	virtual ~ListElementParser()
152 	{
153 	}
154 
155 	virtual void operator()(const Token& token) = 0;
156 };
157 
158 
159 struct BPackageInfo::Parser::StringValidator {
160 public:
161 	virtual void Validate(const BString &string, const char *pos) = 0;
162 };
163 
164 
165 struct BPackageInfo::Parser::UrlStringValidator
166     : public BPackageInfo::Parser::StringValidator {
167 public:
168 	virtual	void				Validate(const BString &string, const char* pos);
169 };
170 
171 
172 } // namespace BPackageKit
173 
174 
175 #endif	// PACKAGE_INFO_PARSER_H
176