]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/dtc/string.cc
MFV r313676: libpcap 1.8.1
[FreeBSD/FreeBSD.git] / usr.bin / dtc / string.cc
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  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
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>
34 #include <cstdio>
35 #include <cstdlib>
36 #include <ctype.h>
37 #include <libgen.h>
38
39 #include "util.hh"
40
41 using std::string;
42
43 namespace dtc
44 {
45
46 void
47 push_string(byte_buffer &buffer, const string &s, bool escapes)
48 {
49         size_t length = s.size();
50         for (size_t i=0 ; i<length ; ++i)
51         {
52                 uint8_t c = s[i];
53                 if (escapes && c == '\\' && i+1 < length)
54                 {
55                         c = s[++i];
56                         switch (c)
57                         {
58                                 // For now, we just ignore invalid escape sequences.
59                                 default:
60                                 case '"':
61                                 case '\'':
62                                 case '\\':
63                                         break;
64                                 case 'a':
65                                         c = '\a';
66                                         break;
67                                 case 'b':
68                                         c = '\b';
69                                         break;
70                                 case 't':
71                                         c = '\t';
72                                         break;
73                                 case 'n':
74                                         c = '\n';
75                                         break;
76                                 case 'v':
77                                         c = '\v';
78                                         break;
79                                 case 'f':
80                                         c = '\f';
81                                         break;
82                                 case 'r':
83                                         c = '\r';
84                                         break;
85                                 case '0'...'7':
86                                 {
87                                         int v = digittoint(c);
88                                         if (i+1 < length && s[i+1] <= '7' && s[i+1] >= '0')
89                                         {
90                                                 v <<= 3;
91                                                 v |= digittoint(s[i+1]);
92                                                 i++;
93                                                 if (i+1 < length && s[i+1] <= '7' && s[i+1] >= '0')
94                                                 {
95                                                         v <<= 3;
96                                                         v |= digittoint(s[i+1]);
97                                                 }
98                                         }
99                                         c = (uint8_t)v;
100                                         break;
101                                 }
102                                 case 'x':
103                                 {
104                                         ++i;
105                                         if (i >= length)
106                                         {
107                                                 break;
108                                         }
109                                         int v = digittoint(s[i]);
110                                         if (i+1 < length && ishexdigit(s[i+1]))
111                                         {
112                                                 v <<= 4;
113                                                 v |= digittoint(s[++i]);
114                                         }
115                                         c = (uint8_t)v;
116                                         break;
117                                 }
118                         }
119                 }
120                 buffer.push_back(c);
121         }
122 }
123
124 std::string dirname(const string &s)
125 {
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;
134 }
135
136 std::string basename(const string &s)
137 {
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;
146 }
147 } // namespace dtc
148