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 |