1 /*============================================================================= 2 Boost.Wave: A Standard compliant C++ preprocessor library 3 4 Grammar for universal character validation (see C++ standard: Annex E) 5 6 http://www.boost.org/ 7 8 Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost 9 Software License, Version 1.0. (See accompanying file 10 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 11 =============================================================================*/ 12 #if !defined(BOOST_CONVERT_TRIGRAPHS_HK050403_INCLUDED) 13 #define BOOST_CONVERT_TRIGRAPHS_HK050403_INCLUDED 14 15 #include <boost/wave/wave_config.hpp> 16 #include <boost/wave/cpplexer/cpplexer_exceptions.hpp> 17 18 // this must occur after all of the includes and before any code appears 19 #ifdef BOOST_HAS_ABI_HEADERS 20 #include BOOST_ABI_PREFIX 21 #endif 22 23 /////////////////////////////////////////////////////////////////////////////// 24 namespace boost { 25 namespace wave { 26 namespace cpplexer { 27 namespace impl { 28 29 /////////////////////////////////////////////////////////////////////////////// 30 // 31 // Test, whether the given string represents a valid trigraph sequence 32 // 33 /////////////////////////////////////////////////////////////////////////////// 34 template <typename StringT> 35 inline bool is_trigraph(StringT const & trigraph)36is_trigraph(StringT const& trigraph) 37 { 38 if (trigraph.size() < 3 || '?' != trigraph[0] || '?' != trigraph[1]) 39 return false; 40 41 switch (trigraph[2]) { 42 case '\'': case '=': case '/': case '(': 43 case ')': case '<': case '>': case '!': 44 case '-': 45 break; 46 47 default: 48 return false; 49 } 50 51 return true; 52 } 53 54 /////////////////////////////////////////////////////////////////////////////// 55 // 56 // convert_trigraph 57 // 58 // The function convert_trigraph() converts a single trigraph character 59 // sequence into the corresponding character. 60 // 61 // If the given character sequence doesn't form a valid trigraph sequence 62 // no conversion is performed. 63 // 64 /////////////////////////////////////////////////////////////////////////////// 65 template <typename StringT> 66 inline StringT convert_trigraph(StringT const & trigraph)67convert_trigraph(StringT const &trigraph) 68 { 69 StringT result (trigraph); 70 71 if (is_trigraph(trigraph)) { 72 switch (trigraph[2]) { 73 case '\'': result = "^"; break; 74 case '=': result = "#"; break; 75 case '/': result = "\\"; break; 76 case '(': result = "["; break; 77 case ')': result = "]"; break; 78 case '<': result = "{"; break; 79 case '>': result = "}"; break; 80 case '!': result = "|"; break; 81 case '-': result = "~"; break; 82 } 83 } 84 return result; 85 } 86 87 /////////////////////////////////////////////////////////////////////////////// 88 // 89 // convert_trigraphs 90 // 91 // The function convert_trigraph() converts all trigraphs in the given 92 // string into the corresponding characters. 93 // 94 // If one of the given character sequences doesn't form a valid trigraph 95 // sequence no conversion is performed. 96 // 97 /////////////////////////////////////////////////////////////////////////////// 98 template <typename StringT> 99 inline StringT convert_trigraphs(StringT const & value)100convert_trigraphs(StringT const &value) 101 { 102 StringT result; 103 typename StringT::size_type pos = 0; 104 typename StringT::size_type pos1 = value.find_first_of ("?", 0); 105 if (StringT::npos != pos1) { 106 do { 107 result += value.substr(pos, pos1-pos); 108 StringT trigraph (value.substr(pos1)); 109 if (is_trigraph(trigraph)) { 110 result += convert_trigraph(trigraph); 111 pos1 = value.find_first_of ("?", pos = pos1+3); 112 } 113 else { 114 result += value[pos1]; 115 pos1 = value.find_first_of ("?", pos = pos1+1); 116 } 117 } while (StringT::npos != pos1); 118 result += value.substr(pos); 119 } 120 else { 121 result = value; 122 } 123 return result; 124 } 125 126 /////////////////////////////////////////////////////////////////////////////// 127 } // namespace impl 128 } // namespace cpplexer 129 } // namespace wave 130 } // namespace boost 131 132 // the suffix header occurs after all of the code 133 #ifdef BOOST_HAS_ABI_HEADERS 134 #include BOOST_ABI_SUFFIX 135 #endif 136 137 #endif // !defined(BOOST_CONVERT_TRIGRAPHS_HK050403_INCLUDED) 138 139 140