Mercurial > projects > qtd
view generator/parser/rpp/pp-engine-bits.h @ 389:d37abad3def9
Added missing ?const? to qt.core.QModelIndex.object.
Previously, QModelIndex.internalPointer was const, while QModelIndex.object was not, even if they in fact do the same thing.
author | David Nadlinger <code@klickverbot.at> |
---|---|
date | Fri, 27 Aug 2010 14:44:09 +0200 |
parents | 09a0f1d048f2 |
children |
line wrap: on
line source
/**************************************************************************** ** ** Copyright (C) 1992-2009 Nokia. All rights reserved. ** Copyright 2005 Roberto Raggi <roberto@kdevelop.org> ** ** This file is part of Qt Jambi. ** ** Commercial Usage Licensees holding valid Qt Commercial licenses may use this file in accordance with the Qt Commercial License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and Nokia. GNU Lesser General Public License Usage Alternatively, this file may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation and appearing in the file LICENSE.LGPL included in the packaging of this file. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. In addition, as a special exception, Nokia gives you certain additional rights. These rights are described in the Nokia Qt LGPL Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this package. GNU General Public License Usage Alternatively, this file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE.GPL included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. If you are unsure which license is appropriate for your use, please contact the sales department at qt-sales@nokia.com. ** ** 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_BITS_H #define PP_ENGINE_BITS_H #include <cstdio> 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 = 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 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 (__directive[0] == 'w' && !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 defined(PP_OS_WIN) if (stat(__filename.c_str (), &__st) == 0) return (__st.st_mode & _S_IFDIR) == _S_IFDIR; else return false; #else if (lstat (__filename.c_str (), &__st) == 0) return (__st.st_mode & S_IFDIR) == S_IFDIR; else return false; #endif } inline bool pp::file_exists (std::string const &__filename) const { struct stat __st; #if defined(PP_OS_WIN) return stat(__filename.c_str (), &__st) == 0; #else return lstat (__filename.c_str (), &__st) == 0; #endif } 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)) return 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 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 fopen (__filepath->c_str(), "r"); } 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_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 ()); assert (it != name.end () && (*it == '<' || *it == '"')); 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); while (__first != __last && *__first != '\n') { if (*__first == '/') { __first = skip_comment_or_divop(__first, __last); env.current_line += skip_comment_or_divop.lines; } if (*__first == '\\') { _InputIterator __begin = __first; __begin = skip_blanks (++__begin, __last); if (__begin != __last && *__begin == '\n') { ++macro.lines; __first = skip_blanks (++__begin, __last); definition += ' '; continue; } } 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 << 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;