Chris@16: /*============================================================================= Chris@16: Boost.Wave: A Standard compliant C++ preprocessor library Chris@16: Chris@16: Grammar for universal character validation (see C++ standard: Annex E) Chris@16: Chris@16: http://www.boost.org/ Chris@16: Chris@16: Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost Chris@16: Software License, Version 1.0. (See accompanying file Chris@16: LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: =============================================================================*/ Chris@16: #if !defined(CONVERT_TRIGRAPHS_HK050403_INCLUDED) Chris@16: #define CONVERT_TRIGRAPHS_HK050403_INCLUDED Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: // this must occur after all of the includes and before any code appears Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: #include BOOST_ABI_PREFIX Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { Chris@16: namespace wave { Chris@16: namespace cpplexer { Chris@16: namespace impl { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // Test, whether the given string represents a valid trigraph sequence Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: inline bool Chris@16: is_trigraph(StringT const& trigraph) Chris@16: { Chris@16: if (trigraph.size() < 3 || '?' != trigraph[0] || '?' != trigraph[1]) Chris@16: return false; Chris@16: Chris@16: switch (trigraph[2]) { Chris@16: case '\'': case '=': case '/': case '(': Chris@16: case ')': case '<': case '>': case '!': Chris@16: case '-': Chris@16: break; Chris@16: Chris@16: default: Chris@16: return false; Chris@16: } Chris@16: Chris@16: return true; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // convert_trigraph Chris@16: // Chris@16: // The function convert_trigraph() converts a single trigraph character Chris@16: // sequence into the corresponding character. Chris@16: // Chris@16: // If the given character sequence doesn't form a valid trigraph sequence Chris@16: // no conversion is performed. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: inline StringT Chris@16: convert_trigraph(StringT const &trigraph) Chris@16: { Chris@16: StringT result (trigraph); Chris@16: Chris@16: if (is_trigraph(trigraph)) { Chris@16: switch (trigraph[2]) { Chris@16: case '\'': result = "^"; break; Chris@16: case '=': result = "#"; break; Chris@16: case '/': result = "\\"; break; Chris@16: case '(': result = "["; break; Chris@16: case ')': result = "]"; break; Chris@16: case '<': result = "{"; break; Chris@16: case '>': result = "}"; break; Chris@16: case '!': result = "|"; break; Chris@16: case '-': result = "~"; break; Chris@16: } Chris@16: } Chris@16: return result; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // convert_trigraphs Chris@16: // Chris@16: // The function convert_trigraph() converts all trigraphs in the given Chris@16: // string into the corresponding characters. Chris@16: // Chris@16: // If one of the given character sequences doesn't form a valid trigraph Chris@16: // sequence no conversion is performed. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: inline StringT Chris@16: convert_trigraphs(StringT const &value) Chris@16: { Chris@16: StringT result; Chris@16: typename StringT::size_type pos = 0; Chris@16: typename StringT::size_type pos1 = value.find_first_of ("?", 0); Chris@16: if (StringT::npos != pos1) { Chris@16: do { Chris@16: result += value.substr(pos, pos1-pos); Chris@16: StringT trigraph (value.substr(pos1)); Chris@16: if (is_trigraph(trigraph)) { Chris@16: result += convert_trigraph(trigraph); Chris@16: pos1 = value.find_first_of ("?", pos = pos1+3); Chris@16: } Chris@16: else { Chris@16: result += value[pos1]; Chris@16: pos1 = value.find_first_of ("?", pos = pos1+1); Chris@16: } Chris@16: } while (StringT::npos != pos1); Chris@16: result += value.substr(pos); Chris@16: } Chris@16: else { Chris@16: result = value; Chris@16: } Chris@16: return result; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: } // namespace impl Chris@16: } // namespace cpplexer Chris@16: } // namespace wave Chris@16: } // namespace boost Chris@16: Chris@16: // the suffix header occurs after all of the code Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: #include BOOST_ABI_SUFFIX Chris@16: #endif Chris@16: Chris@16: #endif // !defined(CONVERT_TRIGRAPHS_HK050403_INCLUDED) Chris@16: Chris@16: