string.cc (cfe30d02adda7c3b5c76156ac52d50d8cab325d9) string.cc (bbe31b709a653884e18995a1c97cdafd7392999a)
1/*-
2 * Copyright (c) 2013 David Chisnall
3 * All rights reserved.
4 *
5 * This software was developed by SRI International and the University of
6 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7 * ("CTSRD"), as part of the DARPA CRASH research programme.
8 *

--- 16 unchanged lines hidden (view full) ---

25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $FreeBSD$
31 */
32
1/*-
2 * Copyright (c) 2013 David Chisnall
3 * All rights reserved.
4 *
5 * This software was developed by SRI International and the University of
6 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7 * ("CTSRD"), as part of the DARPA CRASH research programme.
8 *

--- 16 unchanged lines hidden (view full) ---

25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $FreeBSD$
31 */
32
33#include "string.hh"
33#include <string>
34#include <cstdio>
35#include <cstdlib>
34#include <ctype.h>
36#include <ctype.h>
35#include <stdio.h>
37#include <libgen.h>
36
38
37namespace
38{
39/**
40 * The source files are ASCII, so we provide a non-locale-aware version of
41 * isalpha. This is a class so that it can be used with a template function
42 * for parsing strings.
43 */
44struct is_alpha
45{
46 static inline bool check(const char c)
47 {
48 return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') &&
49 (c <= 'Z'));
50 }
51};
52/**
53 * Check whether a character is in the set allowed for node names. This is a
54 * class so that it can be used with a template function for parsing strings.
55 */
56struct is_node_name_character
57{
58 static inline bool check(const char c)
59 {
60 switch(c)
61 {
62 default:
63 return false;
64 case 'a'...'z': case 'A'...'Z': case '0'...'9':
65 case ',': case '.': case '+': case '-':
66 case '_':
67 return true;
68 }
69 }
70};
71/**
72 * Check whether a character is in the set allowed for property names. This is
73 * a class so that it can be used with a template function for parsing strings.
74 */
75struct is_property_name_character
76{
77 static inline bool check(const char c)
78 {
79 switch(c)
80 {
81 default:
82 return false;
83 case 'a'...'z': case 'A'...'Z': case '0'...'9':
84 case ',': case '.': case '+': case '-':
85 case '_': case '#':
86 return true;
87 }
88 }
89};
39#include "util.hh"
90
40
91}
41using std::string;
92
93namespace dtc
94{
95
42
43namespace dtc
44{
45
96template<class T> string
97string::parse(input_buffer &s)
98{
99 const char *start = s;
100 int l=0;
101 while (T::check(*s)) { l++; ++s; }
102 return string(start, l);
103}
104
105string::string(input_buffer &s) : start((const char*)s), length(0)
106{
107 while(s[length] != '\0')
108 {
109 length++;
110 }
111}
112
113string
114string::parse_node_name(input_buffer &s)
115{
116 return parse<is_node_name_character>(s);
117}
118
119string
120string::parse_property_name(input_buffer &s)
121{
122 return parse<is_property_name_character>(s);
123}
124string
125string::parse_node_or_property_name(input_buffer &s, bool &is_property)
126{
127 if (is_property)
128 {
129 return parse_property_name(s);
130 }
131 const char *start = s;
132 int l=0;
133 while (is_node_name_character::check(*s))
134 {
135 l++;
136 ++s;
137 }
138 while (is_property_name_character::check(*s))
139 {
140 l++;
141 ++s;
142 is_property = true;
143 }
144 return string(start, l);
145}
146
147bool
148string::operator==(const string& other) const
149{
150 return (length == other.length) &&
151 (memcmp(start, other.start, length) == 0);
152}
153
154bool
155string::operator==(const char *other) const
156{
157 return strncmp(other, start, length) == 0;
158}
159
160bool
161string::operator<(const string& other) const
162{
163 if (length < other.length) { return true; }
164 if (length > other.length) { return false; }
165 return memcmp(start, other.start, length) < 0;
166}
167
168void
46void
169string::push_to_buffer(byte_buffer &buffer, bool escapes)
47push_string(byte_buffer &buffer, const string &s, bool escapes)
170{
48{
171 for (int i=0 ; i<length ; ++i)
49 size_t length = s.size();
50 for (size_t i=0 ; i<length ; ++i)
172 {
51 {
173 uint8_t c = start[i];
52 uint8_t c = s[i];
174 if (escapes && c == '\\' && i+1 < length)
175 {
53 if (escapes && c == '\\' && i+1 < length)
54 {
176 c = start[++i];
55 c = s[++i];
177 switch (c)
178 {
179 // For now, we just ignore invalid escape sequences.
180 default:
181 case '"':
182 case '\'':
183 case '\\':
184 break;

--- 16 unchanged lines hidden (view full) ---

201 c = '\f';
202 break;
203 case 'r':
204 c = '\r';
205 break;
206 case '0'...'7':
207 {
208 int v = digittoint(c);
56 switch (c)
57 {
58 // For now, we just ignore invalid escape sequences.
59 default:
60 case '"':
61 case '\'':
62 case '\\':
63 break;

--- 16 unchanged lines hidden (view full) ---

80 c = '\f';
81 break;
82 case 'r':
83 c = '\r';
84 break;
85 case '0'...'7':
86 {
87 int v = digittoint(c);
209 if (i+1 < length && start[i+1] <= '7' && start[i+1] >= '0')
88 if (i+1 < length && s[i+1] <= '7' && s[i+1] >= '0')
210 {
211 v <<= 3;
89 {
90 v <<= 3;
212 v |= digittoint(start[i+1]);
91 v |= digittoint(s[i+1]);
213 i++;
92 i++;
214 if (i+1 < length && start[i+1] <= '7' && start[i+1] >= '0')
93 if (i+1 < length && s[i+1] <= '7' && s[i+1] >= '0')
215 {
216 v <<= 3;
94 {
95 v <<= 3;
217 v |= digittoint(start[i+1]);
96 v |= digittoint(s[i+1]);
218 }
219 }
220 c = (uint8_t)v;
221 break;
222 }
223 case 'x':
224 {
225 ++i;
226 if (i >= length)
227 {
228 break;
229 }
97 }
98 }
99 c = (uint8_t)v;
100 break;
101 }
102 case 'x':
103 {
104 ++i;
105 if (i >= length)
106 {
107 break;
108 }
230 int v = digittoint(start[i]);
231 if (i+1 < length && ishexdigit(start[i+1]))
109 int v = digittoint(s[i]);
110 if (i+1 < length && ishexdigit(s[i+1]))
232 {
233 v <<= 4;
111 {
112 v <<= 4;
234 v |= digittoint(start[++i]);
113 v |= digittoint(s[++i]);
235 }
236 c = (uint8_t)v;
237 break;
238 }
239 }
240 }
241 buffer.push_back(c);
242 }
243}
244
114 }
115 c = (uint8_t)v;
116 break;
117 }
118 }
119 }
120 buffer.push_back(c);
121 }
122}
123
245void
246string::print(FILE *file)
124std::string dirname(const string &s)
247{
125{
248 fwrite(start, length, 1, file);
126 if (s == string())
127 {
128 return string();
129 }
130 char *str = strdup(s.c_str());
131 string dn(::dirname(str));
132 free(str);
133 return dn;
249}
250
134}
135
251void
252string::dump()
136std::string basename(const string &s)
253{
137{
254 print(stderr);
138 if (s == string())
139 {
140 return string();
141 }
142 char *str = strdup(s.c_str());
143 string bn(::basename(str));
144 free(str);
145 return bn;
255}
146}
256
257} // namespace dtc
258
147} // namespace dtc
148