xref: /freebsd/usr.bin/dtc/string.cc (revision 67b60a1b7d46d959bdd4925944b149eebbfb593f)
1af0dd31fSDavid Chisnall /*-
21de7b4b8SPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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  * $FreeBSD$
33af0dd31fSDavid Chisnall  */
34af0dd31fSDavid Chisnall 
35bbe31b70SEd Maste #include <string>
3621d5d37bSEd Maste #include <functional>
37bbe31b70SEd Maste #include <cstdio>
38bbe31b70SEd Maste #include <cstdlib>
39*67b60a1bSKyle Evans #include <cstring>
40009f7b42SDavid Chisnall #include <ctype.h>
41bbe31b70SEd Maste #include <libgen.h>
42af0dd31fSDavid Chisnall 
43bbe31b70SEd Maste #include "util.hh"
44af0dd31fSDavid Chisnall 
45bbe31b70SEd Maste using std::string;
46af0dd31fSDavid Chisnall 
47af0dd31fSDavid Chisnall namespace dtc
48af0dd31fSDavid Chisnall {
49af0dd31fSDavid Chisnall 
50af0dd31fSDavid Chisnall void
51bbe31b70SEd Maste push_string(byte_buffer &buffer, const string &s, bool escapes)
52af0dd31fSDavid Chisnall {
53bbe31b70SEd Maste 	size_t length = s.size();
54bbe31b70SEd Maste 	for (size_t i=0 ; i<length ; ++i)
55af0dd31fSDavid Chisnall 	{
56bbe31b70SEd Maste 		uint8_t c = s[i];
57af0dd31fSDavid Chisnall 		if (escapes && c == '\\' && i+1 < length)
58af0dd31fSDavid Chisnall 		{
59bbe31b70SEd Maste 			c = s[++i];
60af0dd31fSDavid Chisnall 			switch (c)
61af0dd31fSDavid Chisnall 			{
62af0dd31fSDavid Chisnall 				// For now, we just ignore invalid escape sequences.
63af0dd31fSDavid Chisnall 				default:
64af0dd31fSDavid Chisnall 				case '"':
65af0dd31fSDavid Chisnall 				case '\'':
66af0dd31fSDavid Chisnall 				case '\\':
67af0dd31fSDavid Chisnall 					break;
68af0dd31fSDavid Chisnall 				case 'a':
69af0dd31fSDavid Chisnall 					c = '\a';
70af0dd31fSDavid Chisnall 					break;
71af0dd31fSDavid Chisnall 				case 'b':
72af0dd31fSDavid Chisnall 					c = '\b';
73af0dd31fSDavid Chisnall 					break;
74af0dd31fSDavid Chisnall 				case 't':
75af0dd31fSDavid Chisnall 					c = '\t';
76af0dd31fSDavid Chisnall 					break;
77af0dd31fSDavid Chisnall 				case 'n':
78af0dd31fSDavid Chisnall 					c = '\n';
79af0dd31fSDavid Chisnall 					break;
80af0dd31fSDavid Chisnall 				case 'v':
81af0dd31fSDavid Chisnall 					c = '\v';
82af0dd31fSDavid Chisnall 					break;
83af0dd31fSDavid Chisnall 				case 'f':
84af0dd31fSDavid Chisnall 					c = '\f';
85af0dd31fSDavid Chisnall 					break;
86af0dd31fSDavid Chisnall 				case 'r':
87af0dd31fSDavid Chisnall 					c = '\r';
88af0dd31fSDavid Chisnall 					break;
89af0dd31fSDavid Chisnall 				case '0'...'7':
90af0dd31fSDavid Chisnall 				{
91af0dd31fSDavid Chisnall 					int v = digittoint(c);
92bbe31b70SEd Maste 					if (i+1 < length && s[i+1] <= '7' && s[i+1] >= '0')
93af0dd31fSDavid Chisnall 					{
94af0dd31fSDavid Chisnall 						v <<= 3;
95bbe31b70SEd Maste 						v |= digittoint(s[i+1]);
96af0dd31fSDavid Chisnall 						i++;
97bbe31b70SEd Maste 						if (i+1 < length && s[i+1] <= '7' && s[i+1] >= '0')
98af0dd31fSDavid Chisnall 						{
99af0dd31fSDavid Chisnall 							v <<= 3;
100bbe31b70SEd Maste 							v |= digittoint(s[i+1]);
101af0dd31fSDavid Chisnall 						}
102af0dd31fSDavid Chisnall 					}
103af0dd31fSDavid Chisnall 					c = (uint8_t)v;
104af0dd31fSDavid Chisnall 					break;
105af0dd31fSDavid Chisnall 				}
106af0dd31fSDavid Chisnall 				case 'x':
107af0dd31fSDavid Chisnall 				{
108af0dd31fSDavid Chisnall 					++i;
109af0dd31fSDavid Chisnall 					if (i >= length)
110af0dd31fSDavid Chisnall 					{
111af0dd31fSDavid Chisnall 						break;
112af0dd31fSDavid Chisnall 					}
113bbe31b70SEd Maste 					int v = digittoint(s[i]);
114bbe31b70SEd Maste 					if (i+1 < length && ishexdigit(s[i+1]))
115af0dd31fSDavid Chisnall 					{
116af0dd31fSDavid Chisnall 						v <<= 4;
117bbe31b70SEd Maste 						v |= digittoint(s[++i]);
118af0dd31fSDavid Chisnall 					}
119af0dd31fSDavid Chisnall 					c = (uint8_t)v;
120af0dd31fSDavid Chisnall 					break;
121af0dd31fSDavid Chisnall 				}
122af0dd31fSDavid Chisnall 			}
123af0dd31fSDavid Chisnall 		}
124af0dd31fSDavid Chisnall 		buffer.push_back(c);
125af0dd31fSDavid Chisnall 	}
126af0dd31fSDavid Chisnall }
127af0dd31fSDavid Chisnall 
12821d5d37bSEd Maste namespace {
12921d5d37bSEd Maste string
13021d5d37bSEd Maste dirbasename(std::function<char*(char*)> fn, const string &s)
131af0dd31fSDavid Chisnall {
132bbe31b70SEd Maste 	if (s == string())
133bbe31b70SEd Maste 	{
134bbe31b70SEd Maste 		return string();
135bbe31b70SEd Maste 	}
13621d5d37bSEd Maste 	std::unique_ptr<char, decltype(free)*> str = {strdup(s.c_str()), free};
13721d5d37bSEd Maste 	string dn(fn(str.get()));
138bbe31b70SEd Maste 	return dn;
139af0dd31fSDavid Chisnall }
140af0dd31fSDavid Chisnall }
14121d5d37bSEd Maste 
14221d5d37bSEd Maste string dirname(const string &s)
14321d5d37bSEd Maste {
14421d5d37bSEd Maste 	return dirbasename(::dirname, s);
14521d5d37bSEd Maste }
14621d5d37bSEd Maste 
14721d5d37bSEd Maste string basename(const string &s)
14821d5d37bSEd Maste {
14921d5d37bSEd Maste 	return dirbasename(::basename, s);
150bbe31b70SEd Maste }
151af0dd31fSDavid Chisnall } // namespace dtc
152af0dd31fSDavid Chisnall 
153