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