diff options
Diffstat (limited to 'sources/shiboken2/ApiExtractor/parser/rpp/pp-engine-bits.h')
-rw-r--r-- | sources/shiboken2/ApiExtractor/parser/rpp/pp-engine-bits.h | 1300 |
1 files changed, 0 insertions, 1300 deletions
diff --git a/sources/shiboken2/ApiExtractor/parser/rpp/pp-engine-bits.h b/sources/shiboken2/ApiExtractor/parser/rpp/pp-engine-bits.h deleted file mode 100644 index 3d8aee029..000000000 --- a/sources/shiboken2/ApiExtractor/parser/rpp/pp-engine-bits.h +++ /dev/null @@ -1,1300 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PP_ENGINE_BITS_H -#define PP_ENGINE_BITS_H - -#include "pp.h" -#include <sys/stat.h> -#include <cstdio> -#include <iostream> - -namespace rpp -{ - -inline std::string pp::fix_file_path(std::string const &filename) const -{ -#if defined (PP_OS_WIN) - std::string s = filename; - for (std::string::iterator it = s.begin(); it != s.end(); ++it) { - if (*it == '/') - *it = '\\'; - } - return s; -#else - return filename; -#endif -} - -inline bool pp::is_absolute(std::string const &filename) const -{ -#if defined(PP_OS_WIN) - return filename.length() >= 3 - && filename.at(1) == ':' - && (filename.at(2) == '\\' || filename.at(2) == '/'); -#else - return filename.length() >= 1 - && filename.at(0) == '/'; -#endif -} - -template <typename _OutputIterator> -void pp::file(std::string const &filename, _OutputIterator __result) -{ - FILE *fp = std::fopen(filename.c_str(), "rb"); - if (fp != 0) { - std::string was = env.current_file; - env.current_file = filename; - file(fp, __result); - env.current_file = was; - } - //else - //std::cerr << "** WARNING file ``" << filename << " not found!" << std::endl; -} - -template <typename _OutputIterator> -void pp::file(FILE *fp, _OutputIterator __result) -{ - assert(fp != 0); - -#if defined (HAVE_MMAP) - struct stat st; - fstat(FILENO(fp), &st); - std::size_t size = st.st_size; - char *buffer = 0; - buffer = (char *) ::mmap(0, size, PROT_READ, MAP_SHARED, FILENO(fp), 0); - fclose(fp); - if (!buffer || buffer == (char*) - 1) - return; - this->operator()(buffer, buffer + size, __result); - ::munmap(buffer, size); -#else - std::string buffer; - while (!feof(fp)) { - char tmp[1024]; - int read = (int) fread(tmp, sizeof(char), 1023, fp); - tmp[read] = '\0'; - buffer += tmp; - } - fclose(fp); - this->operator()(buffer.c_str(), buffer.c_str() + buffer.size(), __result); -#endif -} - -template <typename _InputIterator> -bool pp::find_header_protection(_InputIterator __first, _InputIterator __last, std::string *__prot) -{ - int was = env.current_line; - - while (__first != __last) { - if (pp_isspace(*__first)) { - if (*__first == '\n') - ++env.current_line; - - ++__first; - } else if (_PP_internal::comment_p(__first, __last)) { - __first = skip_comment_or_divop(__first, __last); - env.current_line += skip_comment_or_divop.lines; - } else if (*__first == '#') { - __first = skip_blanks(++__first, __last); - env.current_line += skip_blanks.lines; - - if (__first != __last && *__first == 'i') { - _InputIterator __begin = __first; - __first = skip_identifier(__begin, __last); - env.current_line += skip_identifier.lines; - - std::string __directive(__begin, __first); - - if (__directive == "ifndef") { - __first = skip_blanks(__first, __last); - env.current_line += skip_blanks.lines; - - __begin = __first; - __first = skip_identifier(__first, __last); - env.current_line += skip_identifier.lines; - - if (__begin != __first && __first != __last) { - __prot->assign(__begin, __first); - return true; - } - } - } - break; - } else - break; - } - - env.current_line = was; - return false; -} - -inline pp::PP_DIRECTIVE_TYPE pp::find_directive(char const *__directive, std::size_t __size) const -{ - switch (__size) { - case 0: - return PP_UNNAMED_DIRECTIVE; - case 2: - if (__directive[0] == 'i' - && __directive[1] == 'f') - return PP_IF; - break; - - case 4: - if (__directive[0] == 'e' && !strcmp(__directive, "elif")) - return PP_ELIF; - else if (__directive[0] == 'e' && !strcmp(__directive, "else")) - return PP_ELSE; - break; - - case 5: - if (__directive[0] == 'i' && !strcmp(__directive, "ifdef")) - return PP_IFDEF; - else if (__directive[0] == 'u' && !strcmp(__directive, "undef")) - return PP_UNDEF; - else if (__directive[0] == 'e') { - if (!strcmp(__directive, "endif")) - return PP_ENDIF; - else if (!strcmp(__directive, "error")) - return PP_ERROR; - } - break; - - case 6: - if (__directive[0] == 'i' && !strcmp(__directive, "ifndef")) - return PP_IFNDEF; - else if (__directive[0] == 'd' && !strcmp(__directive, "define")) - return PP_DEFINE; - else if (__directive[0] == 'p' && !strcmp(__directive, "pragma")) - return PP_PRAGMA; - break; - - case 7: - if (__directive[0] == 'i' && !strcmp(__directive, "include")) - return PP_INCLUDE; - else if (!strcmp(__directive, "warning")) - return PP_WARNING; - break; - - case 12: - if (__directive[0] == 'i' && !strcmp(__directive, "include_next")) - return PP_INCLUDE_NEXT; - break; - - default: - break; - } - std::cerr << "** WARNING unknown directive '#" << __directive << "' at " << env.current_file << ":" << env.current_line << std::endl; - return PP_UNKNOWN_DIRECTIVE; -} - -inline bool pp::file_isdir(std::string const &__filename) const -{ - struct stat __st; - if (stat(__filename.c_str(), &__st) == 0) -#if defined(PP_OS_WIN) - return (__st.st_mode & _S_IFDIR) == _S_IFDIR; -#else - return (__st.st_mode & S_IFDIR) == S_IFDIR; -#endif - else - return false; -} - -inline bool pp::file_exists(std::string const &__filename) const -{ - struct stat __st; - return stat(__filename.c_str(), &__st) == 0; -} - -inline FILE *pp::find_include_file(std::string const &__input_filename, std::string *__filepath, - INCLUDE_POLICY __include_policy, bool __skip_current_path) const -{ - assert(__filepath != 0); - assert(! __input_filename.empty()); - - __filepath->assign(__input_filename); - - if (is_absolute(*__filepath) && !file_isdir(*__filepath)) - return std::fopen(__filepath->c_str(), "r"); - - if (! env.current_file.empty()) - _PP_internal::extract_file_path(env.current_file, __filepath); - - if (__include_policy == INCLUDE_LOCAL && ! __skip_current_path) { - std::string __tmp(*__filepath); - __tmp += __input_filename; - - if (file_exists(__tmp) && !file_isdir(__tmp)) { - __filepath->append(__input_filename); - return std::fopen(__filepath->c_str(), "r"); - } - } - - std::vector<std::string>::const_iterator it = include_paths.begin(); - - if (__skip_current_path) { - it = std::find(include_paths.begin(), include_paths.end(), *__filepath); - - if (it != include_paths.end()) - ++it; - - else - it = include_paths.begin(); - } - - for (; it != include_paths.end(); ++it) { - if (__skip_current_path && it == include_paths.begin()) - continue; - - __filepath->assign(*it); - __filepath->append(__input_filename); - - if (file_exists(*__filepath) && !file_isdir(*__filepath)) - return std::fopen(__filepath->c_str(), "r"); - -#ifdef Q_OS_MAC - // try in Framework path on Mac, if there is a path in front - // ### what about escaped slashes? - size_t slashPos = __input_filename.find('/'); - if (slashPos != std::string::npos) { - __filepath->assign(*it); - __filepath->append(__input_filename.substr(0, slashPos)); - __filepath->append(".framework/Headers/"); - __filepath->append(__input_filename.substr(slashPos + 1, std::string::npos)); - - if (file_exists(*__filepath) && !file_isdir(*__filepath)) { - return fopen(__filepath->c_str(), "r"); - } - } -#endif // Q_OS_MAC - } - - return 0; -} - -template <typename _InputIterator, typename _OutputIterator> -_InputIterator pp::handle_directive(char const *__directive, std::size_t __size, - _InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - __first = skip_blanks(__first, __last); - - PP_DIRECTIVE_TYPE d = find_directive(__directive, __size); - switch (d) { - case PP_UNNAMED_DIRECTIVE: - /* There are many boost headers that include the character '#' - * at the beginning of any line and just do nothing else with - * that unnamed directive. Well, as that's not an error so - * we'll just ignore this unnamed directive for now. - */ - ++__last; - return ++__first; - case PP_DEFINE: - if (! skipping()) - return handle_define(__first, __last); - break; - - case PP_INCLUDE: - case PP_INCLUDE_NEXT: - if (! skipping()) - return handle_include(d == PP_INCLUDE_NEXT, __first, __last, __result); - break; - - case PP_UNDEF: - if (! skipping()) - return handle_undef(__first, __last); - break; - - case PP_ELIF: - return handle_elif(__first, __last); - - case PP_ELSE: - return handle_else(__first, __last); - - case PP_ENDIF: - return handle_endif(__first, __last); - - case PP_IF: - return handle_if(__first, __last); - - case PP_IFDEF: - return handle_ifdef(false, __first, __last); - - case PP_IFNDEF: - return handle_ifdef(true, __first, __last); - - default: - break; - } - - return __first; -} - -template <typename _InputIterator, typename _OutputIterator> -_InputIterator pp::handle_include(bool __skip_current_path, _InputIterator __first, _InputIterator __last, - _OutputIterator __result) -{ - if (pp_isalpha(*__first) || *__first == '_') { - pp_macro_expander expand_include(env); - std::string name; - name.reserve(255); - expand_include(__first, __last, std::back_inserter(name)); - std::string::iterator it = skip_blanks(name.begin(), name.end()); - if (it != name.end() && !(*it == '<' || *it == '"')) { - std::cerr << "** WARNING APIExtractor does not support the use " - "of #include directives without passing either " - "\"<path/to/header.h>\" or \"./path/to/header.h\", " - "for example. Invalid use at " << env.current_file - << ":" << env.current_line << "." << std::endl; - return __last; - } - - handle_include(__skip_current_path, it, name.end(), __result); - return __first; - } - - assert(*__first == '<' || *__first == '"'); - int quote = (*__first == '"') ? '"' : '>'; - ++__first; - - _InputIterator end_name = __first; - for (; end_name != __last; ++end_name) { - assert(*end_name != '\n'); - - if (*end_name == quote) - break; - } - - std::string filename(__first, end_name); - -#ifdef PP_OS_WIN - std::replace(filename.begin(), filename.end(), '/', '\\'); -#endif - - std::string filepath; - FILE *fp = find_include_file(filename, &filepath, quote == '>' ? INCLUDE_GLOBAL : INCLUDE_LOCAL, __skip_current_path); - -#if defined (PP_HOOK_ON_FILE_INCLUDED) - PP_HOOK_ON_FILE_INCLUDED(env.current_file, fp ? filepath : filename, fp); -#endif - - if (fp != 0) { - std::string old_file = env.current_file; - env.current_file = filepath; - int __saved_lines = env.current_line; - - env.current_line = 1; - //output_line (env.current_file, 1, __result); - - file(fp, __result); - - // restore the file name and the line position - env.current_file = old_file; - env.current_line = __saved_lines; - - // sync the buffer - _PP_internal::output_line(env.current_file, env.current_line, __result); - } -#ifndef RPP_JAMBI -// else -// std::cerr << "*** WARNING " << filename << ": No such file or directory" << std::endl; -#endif - - return __first; -} - -template <typename _InputIterator, typename _OutputIterator> -void pp::operator()(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ -#ifndef PP_NO_SMART_HEADER_PROTECTION - std::string __prot; - __prot.reserve(255); - pp_fast_string __tmp(__prot.c_str(), __prot.size()); - - if (find_header_protection(__first, __last, &__prot) - && env.resolve(&__tmp) != 0) { - // std::cerr << "** DEBUG found header protection:" << __prot << std::endl; - return; - } -#endif - - env.current_line = 1; - char __buffer[512]; - - while (true) { - __first = skip_blanks(__first, __last); - env.current_line += skip_blanks.lines; - - if (__first == __last) - break; - else if (*__first == '#') { - assert(*__first == '#'); - __first = skip_blanks(++__first, __last); - env.current_line += skip_blanks.lines; - - _InputIterator end_id = skip_identifier(__first, __last); - env.current_line += skip_identifier.lines; - std::size_t __size = end_id - __first; - - assert(__size < 512); - char *__cp = __buffer; - std::copy(__first, end_id, __cp); - __cp[__size] = '\0'; - - end_id = skip_blanks(end_id, __last); - __first = skip(end_id, __last); - - int was = env.current_line; - (void) handle_directive(__buffer, __size, end_id, __first, __result); - - if (env.current_line != was) { - env.current_line = was; - _PP_internal::output_line(env.current_file, env.current_line, __result); - } - } else if (*__first == '\n') { - // ### compress the line - *__result++ = *__first++; - ++env.current_line; - } else if (skipping()) - __first = skip(__first, __last); - else { - _PP_internal::output_line(env.current_file, env.current_line, __result); - __first = expand(__first, __last, __result); - env.current_line += expand.lines; - - if (expand.generated_lines) - _PP_internal::output_line(env.current_file, env.current_line, __result); - } - } -} - -inline pp::pp(pp_environment &__env): - env(__env), expand(env) -{ - iflevel = 0; - _M_skipping[iflevel] = 0; - _M_true_test[iflevel] = 0; -} - -inline std::back_insert_iterator<std::vector<std::string> > pp::include_paths_inserter() -{ - return std::back_inserter(include_paths); -} - -inline std::vector<std::string>::iterator pp::include_paths_begin() -{ - return include_paths.begin(); -} - -inline std::vector<std::string>::iterator pp::include_paths_end() -{ - return include_paths.end(); -} - -inline std::vector<std::string>::const_iterator pp::include_paths_begin() const -{ - return include_paths.begin(); -} - -inline std::vector<std::string>::const_iterator pp::include_paths_end() const -{ - return include_paths.end(); -} - -inline void pp::push_include_path(std::string const &__path) -{ - if (__path.empty() || __path [__path.size() - 1] != PATH_SEPARATOR) { - std::string __tmp(__path); - __tmp += PATH_SEPARATOR; - include_paths.push_back(__tmp); - } - - else - include_paths.push_back(__path); -} - -template <typename _InputIterator> -_InputIterator pp::handle_define(_InputIterator __first, _InputIterator __last) -{ - pp_macro macro; -#if defined (PP_WITH_MACRO_POSITION) - macro.file = pp_symbol::get(env.current_file); -#endif - std::string definition; - - __first = skip_blanks(__first, __last); - _InputIterator end_macro_name = skip_identifier(__first, __last); - pp_fast_string const *macro_name = pp_symbol::get(__first, end_macro_name); - __first = end_macro_name; - - if (__first != __last && *__first == '(') { - macro.function_like = true; - macro.formals.reserve(5); - - __first = skip_blanks(++__first, __last); // skip '(' - _InputIterator arg_end = skip_identifier(__first, __last); - if (__first != arg_end) - macro.formals.push_back(pp_symbol::get(__first, arg_end)); - - __first = skip_blanks(arg_end, __last); - - if (*__first == '.') { - macro.variadics = true; - while (*__first == '.') - ++__first; - } - - while (__first != __last && *__first == ',') { - __first = skip_blanks(++__first, __last); - - arg_end = skip_identifier(__first, __last); - if (__first != arg_end) - macro.formals.push_back(pp_symbol::get(__first, arg_end)); - - __first = skip_blanks(arg_end, __last); - - if (*__first == '.') { - macro.variadics = true; - while (*__first == '.') - ++__first; - } - } - - assert(*__first == ')'); - ++__first; - } - - __first = skip_blanks(__first, __last); - - /* Note: Sometimes one can include a path between brackets (for - * e.g., when defining a macro or so) so that we cannot simply - * ignore that. The in_path variable will handle this situation. - */ - bool in_path = false; - while (__first != __last && *__first != '\n') { - if ((*__first == '<' || *__first == '"') && - (*(__first + 1) != '*' && *(__first + 1) != '/')) { - in_path = true; - goto skip_path; - } - - if (in_path) { - if (*__first == '>' || *__first == '"') { - in_path = false; - goto skip_path; - } else if (*__first == ',' || *__first == ' ' || *__first == '\\') { - in_path = false; - continue; - } - } - - if (*__first == '/') { - if (*(__first + 1) != '*' && *(__first + 1) != '/') { - in_path = true; - goto skip_path; - } else { - __first = skip_comment_or_divop(__first, __last); - env.current_line += skip_comment_or_divop.lines; - if (__first == __last) - break; - } - } - - if (*__first == '\\') { - _InputIterator __begin = __first; - __begin = skip_blanks(++__begin, __last); - - if (__begin != __last && *__begin == '\n') { - ++macro.lines; - __first = skip_blanks(++__begin, __last); - definition += ' '; - continue; - } - } - -skip_path: - definition += *__first++; - } - - macro.definition = pp_symbol::get(definition); - env.bind(macro_name, macro); - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::skip(_InputIterator __first, _InputIterator __last) -{ - pp_skip_string_literal skip_string_literal; - pp_skip_char_literal skip_char_literal; - - while (__first != __last && *__first != '\n') { - if (*__first == '/') { - __first = skip_comment_or_divop(__first, __last); - env.current_line += skip_comment_or_divop.lines; - } else if (*__first == '"') { - __first = skip_string_literal(__first, __last); - env.current_line += skip_string_literal.lines; - } else if (*__first == '\'') { - __first = skip_char_literal(__first, __last); - env.current_line += skip_char_literal.lines; - } else if (*__first == '\\') { - __first = skip_blanks(++__first, __last); - env.current_line += skip_blanks.lines; - - if (__first != __last && *__first == '\n') { - ++__first; - ++env.current_line; - } - } else - ++__first; - } - - return __first; -} - -inline bool pp::test_if_level() -{ - bool result = !_M_skipping[iflevel++]; - _M_skipping[iflevel] = _M_skipping[iflevel - 1]; - _M_true_test[iflevel] = false; - return result; -} - -inline int pp::skipping() const -{ - return _M_skipping[iflevel]; -} - -template <typename _InputIterator> -_InputIterator pp::eval_primary(_InputIterator __first, _InputIterator __last, Value *result) -{ - bool expect_paren = false; - int token; - __first = next_token(__first, __last, &token); - - switch (token) { - case TOKEN_NUMBER: - result->set_long(token_value); - break; - - case TOKEN_UNUMBER: - result->set_ulong(token_uvalue); - break; - - case TOKEN_DEFINED: - __first = next_token(__first, __last, &token); - - if (token == '(') { - expect_paren = true; - __first = next_token(__first, __last, &token); - } - - if (token != TOKEN_IDENTIFIER) { - std::cerr << "** WARNING expected ``identifier'' found:" << char(token) << std::endl; - result->set_long(0); - break; - } - - result->set_long(env.resolve(token_text->c_str(), token_text->size()) != 0); - - next_token(__first, __last, &token); // skip '(' - - if (expect_paren) { - _InputIterator next = next_token(__first, __last, &token); - if (token != ')') - std::cerr << "** WARNING expected ``)''" << std::endl; - else - __first = next; - } - break; - - case TOKEN_IDENTIFIER: - result->set_long(0); - break; - - case '-': - __first = eval_primary(__first, __last, result); - result->set_long(- result->l); - return __first; - - case '+': - __first = eval_primary(__first, __last, result); - return __first; - - case '!': - __first = eval_primary(__first, __last, result); - result->set_long(result->is_zero()); - return __first; - - case '(': - __first = eval_constant_expression(__first, __last, result); - next_token(__first, __last, &token); - - if (token != ')') { - std::cerr << "** WARNING expected ``)'' = " << token << " (at " - << env.current_file << ":" << env.current_line - << ")." << std::endl; - } else { - __first = next_token(__first, __last, &token); - } - break; - - default: - result->set_long(0); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_multiplicative(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_primary(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == '*' || token == '/' || token == '%') { - Value value; - __first = eval_primary(next, __last, &value); - - if (token == '*') - result->op_mult(value); - else if (token == '/') { - if (value.is_zero()) { - std::cerr << "** WARNING division by zero" << std::endl; - result->set_long(0); - } else - result->op_div(value); - } else { - if (value.is_zero()) { - std::cerr << "** WARNING division by zero" << std::endl; - result->set_long(0); - } else - result->op_mod(value); - } - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_additive(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_multiplicative(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == '+' || token == '-') { - Value value; - __first = eval_multiplicative(next, __last, &value); - - if (token == '+') - result->op_add(value); - else - result->op_sub(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_shift(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_additive(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == TOKEN_LT_LT || token == TOKEN_GT_GT) { - Value value; - __first = eval_additive(next, __last, &value); - - if (token == TOKEN_LT_LT) - result->op_lhs(value); - else - result->op_rhs(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_relational(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_shift(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == '<' - || token == '>' - || token == TOKEN_LT_EQ - || token == TOKEN_GT_EQ) { - Value value; - __first = eval_shift(next, __last, &value); - - switch (token) { - default: - assert(0); - break; - - case '<': - result->op_lt(value); - break; - - case '>': - result->op_gt(value); - break; - - case TOKEN_LT_EQ: - result->op_le(value); - break; - - case TOKEN_GT_EQ: - result->op_ge(value); - break; - } - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_equality(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_relational(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == TOKEN_EQ_EQ || token == TOKEN_NOT_EQ) { - Value value; - __first = eval_relational(next, __last, &value); - - if (token == TOKEN_EQ_EQ) - result->op_eq(value); - else - result->op_ne(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_and(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_equality(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == '&') { - Value value; - __first = eval_equality(next, __last, &value); - result->op_bit_and(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_xor(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_and(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == '^') { - Value value; - __first = eval_and(next, __last, &value); - result->op_bit_xor(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_or(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_xor(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == '|') { - Value value; - __first = eval_xor(next, __last, &value); - result->op_bit_or(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_logical_and(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_or(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == TOKEN_AND_AND) { - Value value; - __first = eval_or(next, __last, &value); - result->op_and(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_logical_or(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_logical_and(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - while (token == TOKEN_OR_OR) { - Value value; - __first = eval_logical_and(next, __last, &value); - result->op_or(value); - next = next_token(__first, __last, &token); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_constant_expression(_InputIterator __first, _InputIterator __last, Value *result) -{ - __first = eval_logical_or(__first, __last, result); - - int token; - _InputIterator next = next_token(__first, __last, &token); - - if (token == '?') { - Value left_value; - __first = eval_constant_expression(next, __last, &left_value); - __first = skip_blanks(__first, __last); - - __first = next_token(__first, __last, &token); - if (token == ':') { - Value right_value; - __first = eval_constant_expression(__first, __last, &right_value); - - *result = !result->is_zero() ? left_value : right_value; - } else { - std::cerr << "** WARNING expected ``:'' = " << int (token) << std::endl; - *result = left_value; - } - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::eval_expression(_InputIterator __first, _InputIterator __last, Value *result) -{ - return __first = eval_constant_expression(skip_blanks(__first, __last), __last, result); -} - -template <typename _InputIterator> -_InputIterator pp::handle_if(_InputIterator __first, _InputIterator __last) -{ - if (test_if_level()) { - pp_macro_expander expand_condition(env); - std::string condition; - condition.reserve(255); - expand_condition(skip_blanks(__first, __last), __last, std::back_inserter(condition)); - - Value result; - result.set_long(0); - eval_expression(condition.c_str(), condition.c_str() + condition.size(), &result); - - _M_true_test[iflevel] = !result.is_zero(); - _M_skipping[iflevel] = result.is_zero(); - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::handle_else(_InputIterator __first, _InputIterator /*__last*/) -{ - if (iflevel == 0 && !skipping()) { - std::cerr << "** WARNING #else without #if" << std::endl; - } else if (iflevel > 0 && _M_skipping[iflevel - 1]) { - _M_skipping[iflevel] = true; - } else { - _M_skipping[iflevel] = _M_true_test[iflevel]; - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::handle_elif(_InputIterator __first, _InputIterator __last) -{ - assert(iflevel > 0); - - if (iflevel == 0 && !skipping()) { - std::cerr << "** WARNING #else without #if" << std::endl; - } else if (!_M_true_test[iflevel] && !_M_skipping[iflevel - 1]) { - Value result; - __first = eval_expression(__first, __last, &result); - _M_true_test[iflevel] = !result.is_zero(); - _M_skipping[iflevel] = result.is_zero(); - } else { - _M_skipping[iflevel] = true; - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::handle_endif(_InputIterator __first, _InputIterator /*__last*/) -{ - if (iflevel == 0 && !skipping()) { - std::cerr << "** WARNING #endif without #if" << std::endl; - } else { - _M_skipping[iflevel] = 0; - _M_true_test[iflevel] = 0; - - --iflevel; - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::handle_ifdef(bool check_undefined, _InputIterator __first, _InputIterator __last) -{ - if (test_if_level()) { - _InputIterator end_macro_name = skip_identifier(__first, __last); - - std::size_t __size; -#if defined(__SUNPRO_CC) - std::distance(__first, end_macro_name, __size); -#else - __size = std::distance(__first, end_macro_name); -#endif - assert(__size < 256); - - char __buffer [256]; - std::copy(__first, end_macro_name, __buffer); - - bool value = env.resolve(__buffer, __size) != 0; - - __first = end_macro_name; - - if (check_undefined) - value = !value; - - _M_true_test[iflevel] = value; - _M_skipping[iflevel] = !value; - } - - return __first; -} - -template <typename _InputIterator> -_InputIterator pp::handle_undef(_InputIterator __first, _InputIterator __last) -{ - __first = skip_blanks(__first, __last); - _InputIterator end_macro_name = skip_identifier(__first, __last); - assert(end_macro_name != __first); - - std::size_t __size; -#if defined(__SUNPRO_CC) - std::distance(__first, end_macro_name, __size); -#else - __size = std::distance(__first, end_macro_name); -#endif - - assert(__size < 256); - - char __buffer [256]; - std::copy(__first, end_macro_name, __buffer); - - pp_fast_string const __tmp(__buffer, __size); - env.unbind(&__tmp); - - __first = end_macro_name; - - return __first; -} - -template <typename _InputIterator> -char pp::peek_char(_InputIterator __first, _InputIterator __last) -{ - if (__first == __last) - return 0; - - return *++__first; -} - -template <typename _InputIterator> -_InputIterator pp::next_token(_InputIterator __first, _InputIterator __last, int *kind) -{ - __first = skip_blanks(__first, __last); - - if (__first == __last) { - *kind = 0; - return __first; - } - - char ch = *__first; - char ch2 = peek_char(__first, __last); - - switch (ch) { - case '/': - if (ch2 == '/' || ch2 == '*') { - __first = skip_comment_or_divop(__first, __last); - return next_token(__first, __last, kind); - } - ++__first; - *kind = '/'; - break; - - case '<': - ++__first; - if (ch2 == '<') { - ++__first; - *kind = TOKEN_LT_LT; - } else if (ch2 == '=') { - ++__first; - *kind = TOKEN_LT_EQ; - } else - *kind = '<'; - - return __first; - - case '>': - ++__first; - if (ch2 == '>') { - ++__first; - *kind = TOKEN_GT_GT; - } else if (ch2 == '=') { - ++__first; - *kind = TOKEN_GT_EQ; - } else - *kind = '>'; - - return __first; - - case '!': - ++__first; - if (ch2 == '=') { - ++__first; - *kind = TOKEN_NOT_EQ; - } else - *kind = '!'; - - return __first; - - case '=': - ++__first; - if (ch2 == '=') { - ++__first; - *kind = TOKEN_EQ_EQ; - } else - *kind = '='; - - return __first; - - case '|': - ++__first; - if (ch2 == '|') { - ++__first; - *kind = TOKEN_OR_OR; - } else - *kind = '|'; - - return __first; - - case '&': - ++__first; - if (ch2 == '&') { - ++__first; - *kind = TOKEN_AND_AND; - } else - *kind = '&'; - - return __first; - - default: - if (pp_isalpha(ch) || ch == '_') { - _InputIterator end = skip_identifier(__first, __last); - _M_current_text.assign(__first, end); - - token_text = &_M_current_text; - __first = end; - - if (*token_text == "defined") - *kind = TOKEN_DEFINED; - else - *kind = TOKEN_IDENTIFIER; - } else if (pp_isdigit(ch)) { - _InputIterator end = skip_number(__first, __last); - std::string __str(__first, __last); - char ch = __str [__str.size() - 1]; - if (ch == 'u' || ch == 'U') { - token_uvalue = strtoul(__str.c_str(), 0, 0); - *kind = TOKEN_UNUMBER; - } else { - token_value = strtol(__str.c_str(), 0, 0); - *kind = TOKEN_NUMBER; - } - __first = end; - } else - *kind = *__first++; - } - - return __first; -} - -} // namespace rpp - -#endif // PP_ENGINE_BITS_H - -// kate: space-indent on; indent-width 2; replace-tabs on; |