• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2003 Daniel Nuffer
3     Copyright (c) 2001-2003 Hartmut Kaiser
4     http://spirit.sourceforge.net/
5 
6     Use, modification and distribution is subject to the Boost Software
7     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8     http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 #include <boost/spirit/include/classic_core.hpp>
11 #include <boost/spirit/include/classic_assign_actor.hpp>
12 #include <boost/spirit/include/classic_escape_char.hpp>
13 
14 #include <iostream>
15 #include <boost/core/ignore_unused.hpp>
16 #include <boost/detail/lightweight_test.hpp>
17 #include <cstdio>       // for sprintf
18 
19 #if !defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_SWPRINTF)
20 # include <cwchar>      // for swprintf
21 #endif
22 
23 ///////////////////////////////////////////////////////////////////////////////
24 using namespace std;
25 using namespace BOOST_SPIRIT_CLASSIC_NS;
26 
27 ///////////////////////////////////////////////////////////////////////////////
28 int
main()29 main()
30 {
31     char c;
32 
33     // testing good C escapes
34     BOOST_TEST(parse("a", c_escape_ch_p[assign_a(c)]).full);
35     BOOST_TEST(c == 'a');
36     BOOST_TEST(parse("\\b", c_escape_ch_p[assign_a(c)]).full);
37     BOOST_TEST(c == '\b');
38     BOOST_TEST(parse("\\t", c_escape_ch_p[assign_a(c)]).full);
39     BOOST_TEST(c == '\t');
40     BOOST_TEST(parse("\\n", c_escape_ch_p[assign_a(c)]).full);
41     BOOST_TEST(c == '\n');
42     BOOST_TEST(parse("\\f", c_escape_ch_p[assign_a(c)]).full);
43     BOOST_TEST(c == '\f');
44     BOOST_TEST(parse("\\r", c_escape_ch_p[assign_a(c)]).full);
45     BOOST_TEST(c == '\r');
46     BOOST_TEST(parse("\\\"", c_escape_ch_p[assign_a(c)]).full);
47     BOOST_TEST(c == '\"');
48     BOOST_TEST(parse("\\'", c_escape_ch_p[assign_a(c)]).full);
49     BOOST_TEST(c == '\'');
50     BOOST_TEST(parse("\\\\", c_escape_ch_p[assign_a(c)]).full);
51     BOOST_TEST(c == '\\');
52     BOOST_TEST(parse("\\120", c_escape_ch_p[assign_a(c)]).full);
53     BOOST_TEST(c == '\120');
54     BOOST_TEST(parse("\\x2e", c_escape_ch_p[assign_a(c)]).full);
55     BOOST_TEST(c == '\x2e');
56 
57     // test bad C escapes
58     BOOST_TEST(!parse("\\z", c_escape_ch_p[assign_a(c)]).hit);
59 
60     // testing good lex escapes
61     BOOST_TEST(parse("a", lex_escape_ch_p[assign_a(c)]).full);
62     BOOST_TEST(c == 'a');
63     BOOST_TEST(parse("\\b", lex_escape_ch_p[assign_a(c)]).full);
64     BOOST_TEST(c == '\b');
65     BOOST_TEST(parse("\\t", lex_escape_ch_p[assign_a(c)]).full);
66     BOOST_TEST(c == '\t');
67     BOOST_TEST(parse("\\n", lex_escape_ch_p[assign_a(c)]).full);
68     BOOST_TEST(c == '\n');
69     BOOST_TEST(parse("\\f", lex_escape_ch_p[assign_a(c)]).full);
70     BOOST_TEST(c == '\f');
71     BOOST_TEST(parse("\\r", lex_escape_ch_p[assign_a(c)]).full);
72     BOOST_TEST(c == '\r');
73     BOOST_TEST(parse("\\\"", lex_escape_ch_p[assign_a(c)]).full);
74     BOOST_TEST(c == '\"');
75     BOOST_TEST(parse("\\'", lex_escape_ch_p[assign_a(c)]).full);
76     BOOST_TEST(c == '\'');
77     BOOST_TEST(parse("\\\\", lex_escape_ch_p[assign_a(c)]).full);
78     BOOST_TEST(c == '\\');
79     BOOST_TEST(parse("\\120", lex_escape_ch_p[assign_a(c)]).full);
80     BOOST_TEST(c == '\120');
81     BOOST_TEST(parse("\\x2e", lex_escape_ch_p[assign_a(c)]).full);
82     BOOST_TEST(c == '\x2e');
83     BOOST_TEST(parse("\\z", lex_escape_ch_p[assign_a(c)]).full);
84     BOOST_TEST(c == 'z');
85     BOOST_TEST(parse("\\a", lex_escape_ch_p[assign_a(c)]).full);
86     BOOST_TEST(c == 'a');
87 
88     // test bad lex escapes
89     BOOST_TEST(!parse("\\xz", lex_escape_ch_p[assign_a(c)]).hit);
90 
91     // test out of range octal escape
92     BOOST_TEST(!parse("\\777", lex_escape_ch_p[assign_a(c)]).hit);
93 
94 #if CHAR_MAX == 127
95     BOOST_TEST(!parse("\\200", lex_escape_ch_p[assign_a(c)]).hit);
96 
97     BOOST_TEST(parse("\\177", lex_escape_ch_p[assign_a(c)]).full);
98     BOOST_TEST(c == '\177');
99 #elif CHAR_MAX == 255
100     BOOST_TEST(!parse("\\400", lex_escape_ch_p[assign_a(c)]).hit);
101 
102     BOOST_TEST(parse("\\377", lex_escape_ch_p[assign_a(c)]).full);
103     BOOST_TEST(c == '\377');
104 #endif
105 
106     // test out of range hex escape
107     BOOST_TEST(!parse("\\xFFF", lex_escape_ch_p[assign_a(c)]).hit);
108 
109 #if CHAR_MAX == 127
110     BOOST_TEST(!parse("\\X80", lex_escape_ch_p[assign_a(c)]).hit);
111 
112     BOOST_TEST(parse("\\X7F", lex_escape_ch_p[assign_a(c)]).full);
113     BOOST_TEST(c == '\x7f');
114 #elif CHAR_MAX == 255
115     BOOST_TEST(!parse("\\X100", lex_escape_ch_p[assign_a(c)]).hit);
116 
117     BOOST_TEST(parse("\\XFf", lex_escape_ch_p[assign_a(c)]).full);
118     BOOST_TEST(c == '\xff');
119 #endif
120 
121 #ifndef BOOST_NO_CWCHAR
122 
123     // test wide chars
124     typedef escape_char_parser<lex_escapes, wchar_t> wlep_t;
125     wlep_t wlep = wlep_t();
126 
127     typedef escape_char_parser<c_escapes, wchar_t> wcep_t;
128     wcep_t wcep = wcep_t();
129 
130     //wchar_t const* wstr = L"a\\b\\t\\n\\f\\r\\\"\\'\\\\\\120\\x2e";
131     //wchar_t const* wend(wstr + wcslen(wstr));
132 
133     wchar_t wc;
134     BOOST_TEST(parse(L"a", wcep[assign_a(wc)]).hit);
135     BOOST_TEST(wc == L'a');
136     BOOST_TEST(parse(L"\\b", wcep[assign_a(wc)]).full);
137     BOOST_TEST(wc == L'\b');
138     BOOST_TEST(parse(L"\\t", wcep[assign_a(wc)]).full);
139     BOOST_TEST(wc == L'\t');
140     BOOST_TEST(parse(L"\\n", wcep[assign_a(wc)]).full);
141     BOOST_TEST(wc == L'\n');
142     BOOST_TEST(parse(L"\\f", wcep[assign_a(wc)]).full);
143     BOOST_TEST(wc == L'\f');
144     BOOST_TEST(parse(L"\\r", wcep[assign_a(wc)]).full);
145     BOOST_TEST(wc == L'\r');
146     BOOST_TEST(parse(L"\\\"", wcep[assign_a(wc)]).full);
147     BOOST_TEST(wc == L'\"');
148     BOOST_TEST(parse(L"\\'", wcep[assign_a(wc)]).full);
149     BOOST_TEST(wc == L'\'');
150     BOOST_TEST(parse(L"\\\\", wcep[assign_a(wc)]).full);
151     BOOST_TEST(wc == L'\\');
152     BOOST_TEST(parse(L"\\120", wcep[assign_a(wc)]).full);
153     BOOST_TEST(wc == L'\120');
154     BOOST_TEST(parse(L"\\x2e", wcep[assign_a(wc)]).full);
155     BOOST_TEST(wc == L'\x2e');
156 
157     // test bad wc escapes
158     BOOST_TEST(!parse(L"\\z", wcep[assign_a(wc)]).hit);
159 
160 #if !defined(BOOST_NO_SWPRINTF)
161     unsigned long ulwcmax(WCHAR_MAX);
162 
163     // test out of range octal escape
164     size_t const octmax_size = 16;
165     wchar_t octmax[octmax_size];
166 
167     swprintf(octmax, octmax_size,
168       L"\\%lo", (unsigned long)(std::numeric_limits<wchar_t>::max)());
169     BOOST_TEST(parse(octmax, wlep[assign_a(wc)]).full);
170     //BOOST_TEST(lex_escape_ch_p[assign_a(wc)].parse(str, end));
171     BOOST_TEST(wc == (std::numeric_limits<wchar_t>::max)());
172 
173     // WCHAR_MAX + 1
174     swprintf(octmax, octmax_size,
175       L"\\%lo%lo", ulwcmax / 8 + (ulwcmax % 8 == 7), (ulwcmax - 7) % 8);
176     BOOST_TEST(!parse(octmax, wlep[assign_a(wc)]).hit);
177 
178     // test out of range hex escape
179     size_t const hexmax_size = 16;
180     wchar_t hexmax[hexmax_size];
181 
182     swprintf(hexmax, hexmax_size,
183       L"\\x%lx", (unsigned long)(std::numeric_limits<wchar_t>::max)());
184     BOOST_TEST(parse(hexmax, wlep[assign_a(wc)]).full);
185     BOOST_TEST(wc == (std::numeric_limits<wchar_t>::max)());
186 
187     // WCHAR_MAX + 1
188     swprintf(hexmax, hexmax_size,
189       L"\\x%lx%lx", ulwcmax / 16 + (ulwcmax % 16 == 15), (ulwcmax - 15) % 16);
190     BOOST_TEST(!parse(hexmax, wlep[assign_a(wc)]).hit);
191 #else
192     boost::ignore_unused(wlep);
193 #endif // !defined(BOOST_NO_SWPRINTF)
194 
195 #endif
196 
197     return boost::report_errors();
198 }
199