• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)36 is_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)67 convert_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)100 convert_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