xref: /freebsd/usr.bin/dtc/string.cc (revision 076ad2f836d5f49dc1375f1677335a48fe0d4b82)
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 
149