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