1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2013 David Chisnall
5 * All rights reserved.
6 *
7 * This software was developed by SRI International and the University of
8 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
9 * ("CTSRD"), as part of the DARPA CRASH research programme.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $FreeBSD$
33 */
34
35 #include <string>
36 #include <functional>
37 #include <cstdio>
38 #include <cstdlib>
39 #include <cstring>
40 #include <ctype.h>
41 #include <libgen.h>
42
43 #include "util.hh"
44
45 using std::string;
46
47 namespace dtc
48 {
49
50 void
push_string(byte_buffer & buffer,const string & s,bool escapes)51 push_string(byte_buffer &buffer, const string &s, bool escapes)
52 {
53 size_t length = s.size();
54 for (size_t i=0 ; i<length ; ++i)
55 {
56 uint8_t c = s[i];
57 if (escapes && c == '\\' && i+1 < length)
58 {
59 c = s[++i];
60 switch (c)
61 {
62 // For now, we just ignore invalid escape sequences.
63 default:
64 case '"':
65 case '\'':
66 case '\\':
67 break;
68 case 'a':
69 c = '\a';
70 break;
71 case 'b':
72 c = '\b';
73 break;
74 case 't':
75 c = '\t';
76 break;
77 case 'n':
78 c = '\n';
79 break;
80 case 'v':
81 c = '\v';
82 break;
83 case 'f':
84 c = '\f';
85 break;
86 case 'r':
87 c = '\r';
88 break;
89 case '0'...'7':
90 {
91 int v = digittoint(c);
92 if (i+1 < length && s[i+1] <= '7' && s[i+1] >= '0')
93 {
94 v <<= 3;
95 v |= digittoint(s[i+1]);
96 i++;
97 if (i+1 < length && s[i+1] <= '7' && s[i+1] >= '0')
98 {
99 v <<= 3;
100 v |= digittoint(s[i+1]);
101 }
102 }
103 c = (uint8_t)v;
104 break;
105 }
106 case 'x':
107 {
108 ++i;
109 if (i >= length)
110 {
111 break;
112 }
113 int v = digittoint(s[i]);
114 if (i+1 < length && ishexdigit(s[i+1]))
115 {
116 v <<= 4;
117 v |= digittoint(s[++i]);
118 }
119 c = (uint8_t)v;
120 break;
121 }
122 }
123 }
124 buffer.push_back(c);
125 }
126 }
127
128 namespace {
129 string
dirbasename(std::function<char * (char *)> fn,const string & s)130 dirbasename(std::function<char*(char*)> fn, const string &s)
131 {
132 if (s == string())
133 {
134 return string();
135 }
136 std::unique_ptr<char, decltype(free)*> str = {strdup(s.c_str()), free};
137 string dn(fn(str.get()));
138 return dn;
139 }
140 }
141
dirname(const string & s)142 string dirname(const string &s)
143 {
144 return dirbasename(::dirname, s);
145 }
146
basename(const string & s)147 string basename(const string &s)
148 {
149 return dirbasename(::basename, s);
150 }
151 } // namespace dtc
152
153