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