xref: /haiku/src/kits/package/PackageInfoParser.h (revision 8b5f785b6a4baacea04971694acdb20c6a1b7cd3)
16da0ce6fSIngo Weinhold /*
26da0ce6fSIngo Weinhold  * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
3fa2dd9c4SAndrew Lindesay  * Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>
46da0ce6fSIngo Weinhold  * Distributed under the terms of the MIT License.
56da0ce6fSIngo Weinhold  */
66da0ce6fSIngo Weinhold #ifndef PACKAGE_INFO_PARSER_H
76da0ce6fSIngo Weinhold #define PACKAGE_INFO_PARSER_H
86da0ce6fSIngo Weinhold 
96da0ce6fSIngo Weinhold 
106da0ce6fSIngo Weinhold #include <package/PackageInfo.h>
116da0ce6fSIngo Weinhold 
126da0ce6fSIngo Weinhold 
136da0ce6fSIngo Weinhold namespace BPackageKit {
146da0ce6fSIngo Weinhold 
156da0ce6fSIngo Weinhold 
166da0ce6fSIngo Weinhold /*
176da0ce6fSIngo Weinhold  * Parses a ".PackageInfo" file and fills a BPackageInfo object with the
186da0ce6fSIngo Weinhold  * package info elements found.
196da0ce6fSIngo Weinhold  */
206da0ce6fSIngo Weinhold class BPackageInfo::Parser {
216da0ce6fSIngo Weinhold public:
226da0ce6fSIngo Weinhold 								Parser(ParseErrorListener* listener = NULL);
236da0ce6fSIngo Weinhold 
246da0ce6fSIngo Weinhold 			status_t			Parse(const BString& packageInfoString,
256da0ce6fSIngo Weinhold 									BPackageInfo* packageInfo);
266da0ce6fSIngo Weinhold 
276da0ce6fSIngo Weinhold 			status_t			ParseVersion(const BString& versionString,
286da0ce6fSIngo Weinhold 									bool revisionIsOptional,
296da0ce6fSIngo Weinhold 									BPackageVersion& _version);
30*8b5f785bSX512 			status_t			ParseResolvable(
31*8b5f785bSX512 									const BString& expressionString,
32*8b5f785bSX512 									BPackageResolvable& _expression);
3388706cfaSIngo Weinhold 			status_t			ParseResolvableExpression(
3488706cfaSIngo Weinhold 									const BString& expressionString,
3588706cfaSIngo Weinhold 									BPackageResolvableExpression& _expression);
366da0ce6fSIngo Weinhold 
376da0ce6fSIngo Weinhold private:
38fa2dd9c4SAndrew Lindesay 			struct UrlStringValidator;
39fa2dd9c4SAndrew Lindesay 			struct StringValidator;
406da0ce6fSIngo Weinhold 			struct ParseError;
416da0ce6fSIngo Weinhold 			struct Token;
426da0ce6fSIngo Weinhold 			struct ListElementParser;
436da0ce6fSIngo Weinhold 	friend	struct ListElementParser;
446da0ce6fSIngo Weinhold 
456da0ce6fSIngo Weinhold 			enum TokenType {
460e9ec703SIngo Weinhold 				TOKEN_STRING,
476da0ce6fSIngo Weinhold 				TOKEN_OPERATOR_ASSIGN,
486da0ce6fSIngo Weinhold 				TOKEN_OPERATOR_LESS,
496da0ce6fSIngo Weinhold 				TOKEN_OPERATOR_LESS_EQUAL,
506da0ce6fSIngo Weinhold 				TOKEN_OPERATOR_EQUAL,
516da0ce6fSIngo Weinhold 				TOKEN_OPERATOR_NOT_EQUAL,
526da0ce6fSIngo Weinhold 				TOKEN_OPERATOR_GREATER_EQUAL,
536da0ce6fSIngo Weinhold 				TOKEN_OPERATOR_GREATER,
546da0ce6fSIngo Weinhold 				TOKEN_OPEN_BRACE,
556da0ce6fSIngo Weinhold 				TOKEN_CLOSE_BRACE,
566da0ce6fSIngo Weinhold 				TOKEN_ITEM_SEPARATOR,
576da0ce6fSIngo Weinhold 				//
586da0ce6fSIngo Weinhold 				TOKEN_EOF,
596da0ce6fSIngo Weinhold 			};
606da0ce6fSIngo Weinhold 
616da0ce6fSIngo Weinhold private:
626da0ce6fSIngo Weinhold 			Token				_NextToken();
636da0ce6fSIngo Weinhold 			void				_RewindTo(const Token& token);
646da0ce6fSIngo Weinhold 
656da0ce6fSIngo Weinhold 			void				_ParseStringValue(BString* value,
666da0ce6fSIngo Weinhold 									const char** _tokenPos = NULL);
676da0ce6fSIngo Weinhold 			uint32				_ParseFlags();
686da0ce6fSIngo Weinhold 			void				_ParseArchitectureValue(
696da0ce6fSIngo Weinhold 									BPackageArchitecture* value);
706da0ce6fSIngo Weinhold 			void				_ParseVersionValue(BPackageVersion* value,
716da0ce6fSIngo Weinhold 									bool revisionIsOptional);
726da0ce6fSIngo Weinhold 	static	void				_ParseVersionValue(Token& word,
736da0ce6fSIngo Weinhold 									BPackageVersion* value,
746da0ce6fSIngo Weinhold 									bool revisionIsOptional);
75*8b5f785bSX512 			void				_ParseResolvable(
76*8b5f785bSX512 									const Token& token,
77*8b5f785bSX512 									BPackageResolvable& _value);
7888706cfaSIngo Weinhold 			void				_ParseResolvableExpression(
7988706cfaSIngo Weinhold 									const Token& token,
8088706cfaSIngo Weinhold 									BPackageResolvableExpression& _value,
8188706cfaSIngo Weinhold 									BString* _basePackage);
826da0ce6fSIngo Weinhold 			void				_ParseList(ListElementParser& elementParser,
836da0ce6fSIngo Weinhold 									bool allowSingleNonListElement);
846da0ce6fSIngo Weinhold 			void				_ParseStringList(BStringList* value,
850e9ec703SIngo Weinhold 									bool requireResolvableName = false,
86fa2dd9c4SAndrew Lindesay 									bool convertToLowerCase = false,
87fa2dd9c4SAndrew Lindesay 									StringValidator* stringValidator = NULL);
886da0ce6fSIngo Weinhold 			void				_ParseResolvableList(
896da0ce6fSIngo Weinhold 									BObjectList<BPackageResolvable>* value);
906da0ce6fSIngo Weinhold 			void				_ParseResolvableExprList(
916da0ce6fSIngo Weinhold 									BObjectList<BPackageResolvableExpression>*
926da0ce6fSIngo Weinhold 										value,
936da0ce6fSIngo Weinhold 									BString* _basePackage = NULL);
944489c88bSIngo Weinhold 			void				_ParseGlobalWritableFileInfos(
954489c88bSIngo Weinhold 									GlobalWritableFileInfoList* infos);
966da0ce6fSIngo Weinhold 			void				_ParseUserSettingsFileInfos(
976da0ce6fSIngo Weinhold 									UserSettingsFileInfoList* infos);
980f4e11e7SIngo Weinhold 			void				_ParseUsers(UserList* users);
996da0ce6fSIngo Weinhold 
1006da0ce6fSIngo Weinhold 			void				_Parse(BPackageInfo* packageInfo);
1016da0ce6fSIngo Weinhold 
1026da0ce6fSIngo Weinhold 	static	bool				_IsAlphaNumUnderscore(const BString& string,
1036da0ce6fSIngo Weinhold 									const char* additionalChars,
1046da0ce6fSIngo Weinhold 									int32* _errorPos);
1056da0ce6fSIngo Weinhold 	static	bool				_IsAlphaNumUnderscore(const char* string,
1066da0ce6fSIngo Weinhold 									const char* additionalChars,
1076da0ce6fSIngo Weinhold 									int32* _errorPos);
1086da0ce6fSIngo Weinhold 	static	bool				_IsAlphaNumUnderscore(const char* start,
1096da0ce6fSIngo Weinhold 									const char* end,
1106da0ce6fSIngo Weinhold 									const char* additionalChars,
1116da0ce6fSIngo Weinhold 									int32* _errorPos);
1126da0ce6fSIngo Weinhold 	static	bool				_IsValidResolvableName(const char* string,
1136da0ce6fSIngo Weinhold 									int32* _errorPos);
1146da0ce6fSIngo Weinhold 
1156da0ce6fSIngo Weinhold private:
1166da0ce6fSIngo Weinhold 			ParseErrorListener*	fListener;
1176da0ce6fSIngo Weinhold 			const char*			fPos;
1186da0ce6fSIngo Weinhold };
1196da0ce6fSIngo Weinhold 
1206da0ce6fSIngo Weinhold 
1216da0ce6fSIngo Weinhold struct BPackageInfo::Parser::ParseError {
1226da0ce6fSIngo Weinhold 	BString 	message;
1236da0ce6fSIngo Weinhold 	const char*	pos;
1246da0ce6fSIngo Weinhold 
ParseErrorParseError1256da0ce6fSIngo Weinhold 	ParseError(const BString& _message, const char* _pos)
1266da0ce6fSIngo Weinhold 		: message(_message), pos(_pos)
1276da0ce6fSIngo Weinhold 	{
1286da0ce6fSIngo Weinhold 	}
1296da0ce6fSIngo Weinhold };
1306da0ce6fSIngo Weinhold 
1316da0ce6fSIngo Weinhold 
1326da0ce6fSIngo Weinhold struct BPackageInfo::Parser::Token {
1336da0ce6fSIngo Weinhold 	TokenType	type;
1346da0ce6fSIngo Weinhold 	BString		text;
1356da0ce6fSIngo Weinhold 	const char*	pos;
1366da0ce6fSIngo Weinhold 
1370e9ec703SIngo Weinhold 	Token(TokenType _type, const char* _pos, int length = 0,
1380e9ec703SIngo Weinhold 		const char* text = NULL)
1390e9ec703SIngo Weinhold 		:
typeToken1400e9ec703SIngo Weinhold 		type(_type),
1410e9ec703SIngo Weinhold 		pos(_pos)
1426da0ce6fSIngo Weinhold 	{
1430e9ec703SIngo Weinhold 		if (text != NULL)
1440e9ec703SIngo Weinhold 			this->text = text;
1450e9ec703SIngo Weinhold 		else if (length != 0)
1460e9ec703SIngo Weinhold 			this->text.SetTo(pos, length);
1476da0ce6fSIngo Weinhold 	}
1486da0ce6fSIngo Weinhold 
1496da0ce6fSIngo Weinhold 	operator bool() const
1506da0ce6fSIngo Weinhold 	{
1516da0ce6fSIngo Weinhold 		return type != TOKEN_EOF;
1526da0ce6fSIngo Weinhold 	}
1536da0ce6fSIngo Weinhold };
1546da0ce6fSIngo Weinhold 
1556da0ce6fSIngo Weinhold 
1566da0ce6fSIngo Weinhold struct BPackageInfo::Parser::ListElementParser {
~ListElementParserListElementParser1576da0ce6fSIngo Weinhold 	virtual ~ListElementParser()
1586da0ce6fSIngo Weinhold 	{
1596da0ce6fSIngo Weinhold 	}
1606da0ce6fSIngo Weinhold 
1616da0ce6fSIngo Weinhold 	virtual void operator()(const Token& token) = 0;
1626da0ce6fSIngo Weinhold };
1636da0ce6fSIngo Weinhold 
1646da0ce6fSIngo Weinhold 
165fa2dd9c4SAndrew Lindesay struct BPackageInfo::Parser::StringValidator {
166fa2dd9c4SAndrew Lindesay public:
167fa2dd9c4SAndrew Lindesay 	virtual void Validate(const BString &string, const char *pos) = 0;
168fa2dd9c4SAndrew Lindesay };
169fa2dd9c4SAndrew Lindesay 
170fa2dd9c4SAndrew Lindesay 
171fa2dd9c4SAndrew Lindesay struct BPackageInfo::Parser::UrlStringValidator
172fa2dd9c4SAndrew Lindesay     : public BPackageInfo::Parser::StringValidator {
173fa2dd9c4SAndrew Lindesay public:
174fa2dd9c4SAndrew Lindesay 	virtual	void				Validate(const BString &string, const char* pos);
175fa2dd9c4SAndrew Lindesay };
176fa2dd9c4SAndrew Lindesay 
177fa2dd9c4SAndrew Lindesay 
1786da0ce6fSIngo Weinhold } // namespace BPackageKit
1796da0ce6fSIngo Weinhold 
1806da0ce6fSIngo Weinhold 
1816da0ce6fSIngo Weinhold #endif	// PACKAGE_INFO_PARSER_H
182