diff options
Diffstat (limited to 'generator/parser/rpp/pp-engine.h')
-rw-r--r-- | generator/parser/rpp/pp-engine.h | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/generator/parser/rpp/pp-engine.h b/generator/parser/rpp/pp-engine.h new file mode 100644 index 0000000..e8e0d52 --- /dev/null +++ b/generator/parser/rpp/pp-engine.h @@ -0,0 +1,265 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** Copyright 2005 Roberto Raggi <roberto@kdevelop.org> +** +** This file is part of $PRODUCT$. +** +** $CPP_LICENSE$ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef PP_ENGINE_H +#define PP_ENGINE_H + +namespace rpp { + +struct Value +{ + enum Kind { + Kind_Long, + Kind_ULong, + }; + + Kind kind; + + union { + long l; + unsigned long ul; + }; + + inline bool is_ulong () const { return kind == Kind_ULong; } + + inline void set_ulong (unsigned long v) + { + ul = v; + kind = Kind_ULong; + } + + inline void set_long (long v) + { + l = v; + kind = Kind_Long; + } + + inline bool is_zero () const { return l == 0; } + +#define PP_DEFINE_BIN_OP(name, op) \ + inline Value &name (const Value &other) \ + { \ + if (is_ulong () || other.is_ulong ()) \ + set_ulong (ul op other.ul); \ + else \ + set_long (l op other.l); \ + return *this; \ + } + + PP_DEFINE_BIN_OP(op_add, +) + PP_DEFINE_BIN_OP(op_sub, -) + PP_DEFINE_BIN_OP(op_mult, *) + PP_DEFINE_BIN_OP(op_div, /) + PP_DEFINE_BIN_OP(op_mod, %) + PP_DEFINE_BIN_OP(op_lhs, <<) + PP_DEFINE_BIN_OP(op_rhs, >>) + PP_DEFINE_BIN_OP(op_lt, <) + PP_DEFINE_BIN_OP(op_gt, >) + PP_DEFINE_BIN_OP(op_le, <=) + PP_DEFINE_BIN_OP(op_ge, >=) + PP_DEFINE_BIN_OP(op_eq, ==) + PP_DEFINE_BIN_OP(op_ne, !=) + PP_DEFINE_BIN_OP(op_bit_and, &) + PP_DEFINE_BIN_OP(op_bit_or, |) + PP_DEFINE_BIN_OP(op_bit_xor, ^) + PP_DEFINE_BIN_OP(op_and, &&) + PP_DEFINE_BIN_OP(op_or, ||) + +#undef PP_DEFINE_BIN_OP +}; + +class pp +{ + pp_environment &env; + pp_macro_expander expand; + pp_skip_identifier skip_identifier; + pp_skip_comment_or_divop skip_comment_or_divop; + pp_skip_blanks skip_blanks; + pp_skip_number skip_number; + std::vector<std::string> include_paths; + std::string _M_current_text; + + enum { MAX_LEVEL = 512 }; + int _M_skipping[MAX_LEVEL]; + int _M_true_test[MAX_LEVEL]; + int iflevel; + + union + { + long token_value; + unsigned long token_uvalue; + std::string *token_text; + }; + + enum INCLUDE_POLICY + { + INCLUDE_GLOBAL, + INCLUDE_LOCAL + }; + + enum TOKEN_TYPE + { + TOKEN_NUMBER = 1000, + TOKEN_UNUMBER, + TOKEN_IDENTIFIER, + TOKEN_DEFINED, + TOKEN_LT_LT, + TOKEN_LT_EQ, + TOKEN_GT_GT, + TOKEN_GT_EQ, + TOKEN_EQ_EQ, + TOKEN_NOT_EQ, + TOKEN_OR_OR, + TOKEN_AND_AND, + }; + + enum PP_DIRECTIVE_TYPE + { + PP_UNKNOWN_DIRECTIVE, + PP_DEFINE, + PP_INCLUDE, + PP_INCLUDE_NEXT, + PP_ELIF, + PP_ELSE, + PP_ENDIF, + PP_IF, + PP_IFDEF, + PP_IFNDEF, + PP_UNDEF, + PP_PRAGMA, + PP_ERROR + }; + +public: + pp (pp_environment &__env); + + inline std::back_insert_iterator<std::vector<std::string> > include_paths_inserter (); + + inline void push_include_path (std::string const &__path); + + inline std::vector<std::string>::iterator include_paths_begin (); + inline std::vector<std::string>::iterator include_paths_end (); + + inline std::vector<std::string>::const_iterator include_paths_begin () const; + inline std::vector<std::string>::const_iterator include_paths_end () const; + + template <typename _InputIterator> + inline _InputIterator eval_expression (_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _OutputIterator> + void file (std::string const &filename, _OutputIterator __result); + + template <typename _OutputIterator> + void file (FILE *fp, _OutputIterator __result); + + template <typename _InputIterator, typename _OutputIterator> + void operator () (_InputIterator __first, _InputIterator __last, _OutputIterator __result); + +private: + inline bool file_isdir (std::string const &__filename) const; + inline bool file_exists (std::string const &__filename) const; + FILE *find_include_file (std::string const &__filename, std::string *__filepath, + INCLUDE_POLICY __include_policy, bool __skip_current_path = false) const; + + inline int skipping() const; + bool test_if_level(); + + inline std::string fix_file_path (std::string const &filename) const; + inline bool is_absolute (std::string const &filename) const; + + PP_DIRECTIVE_TYPE find_directive (char const *__directive, std::size_t __size) const; + + template <typename _InputIterator> + bool find_header_protection (_InputIterator __first, _InputIterator __last, std::string *__prot); + + template <typename _InputIterator> + _InputIterator skip (_InputIterator __first, _InputIterator __last); + + template <typename _InputIterator> + _InputIterator eval_primary(_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _InputIterator> + _InputIterator eval_multiplicative(_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _InputIterator> + _InputIterator eval_additive(_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _InputIterator> + _InputIterator eval_shift(_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _InputIterator> + _InputIterator eval_relational(_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _InputIterator> + _InputIterator eval_equality(_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _InputIterator> + _InputIterator eval_and(_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _InputIterator> + _InputIterator eval_xor(_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _InputIterator> + _InputIterator eval_or(_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _InputIterator> + _InputIterator eval_logical_and(_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _InputIterator> + _InputIterator eval_logical_or(_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _InputIterator> + _InputIterator eval_constant_expression(_InputIterator __first, _InputIterator __last, Value *result); + + template <typename _InputIterator, typename _OutputIterator> + _InputIterator handle_directive(char const *__directive, std::size_t __size, + _InputIterator __first, _InputIterator __last, _OutputIterator __result); + + template <typename _InputIterator, typename _OutputIterator> + _InputIterator handle_include(bool skip_current_path, _InputIterator __first, _InputIterator __last, + _OutputIterator __result); + + template <typename _InputIterator> + _InputIterator handle_define (_InputIterator __first, _InputIterator __last); + + template <typename _InputIterator> + _InputIterator handle_if (_InputIterator __first, _InputIterator __last); + + template <typename _InputIterator> + _InputIterator handle_else (_InputIterator __first, _InputIterator __last); + + template <typename _InputIterator> + _InputIterator handle_elif (_InputIterator __first, _InputIterator __last); + + template <typename _InputIterator> + _InputIterator handle_endif (_InputIterator __first, _InputIterator __last); + + template <typename _InputIterator> + _InputIterator handle_ifdef (bool check_undefined, _InputIterator __first, _InputIterator __last); + + template <typename _InputIterator> + _InputIterator handle_undef(_InputIterator __first, _InputIterator __last); + + template <typename _InputIterator> + inline char peek_char (_InputIterator __first, _InputIterator __last); + + template <typename _InputIterator> + _InputIterator next_token (_InputIterator __first, _InputIterator __last, int *kind); +}; + +} // namespace rpp + +#endif // PP_ENGINE_H + +// kate: space-indent on; indent-width 2; replace-tabs on; |