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