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