blob: 6d07292cb7233da5c1a5df3f0903ba42410ae27a [file] [log] [blame]
Jon Loeliger879e4d22008-10-03 11:12:33 -05001/*
2 * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
3 *
Simon Glass492f9d52011-07-05 12:02:49 -07004 * util_is_printable_string contributed by
5 * Pantelis Antoniou <pantelis.antoniou AT gmail.com>
6 *
Jon Loeliger879e4d22008-10-03 11:12:33 -05007 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 */
22
Simon Glass492f9d52011-07-05 12:02:49 -070023#include <ctype.h>
David Gibson87658742010-03-03 16:38:01 +110024#include <stdio.h>
25#include <stdlib.h>
26#include <stdarg.h>
27#include <string.h>
Anton Staafb43335a2011-09-09 12:16:29 -070028#include <assert.h>
David Gibson87658742010-03-03 16:38:01 +110029
30#include "util.h"
Jon Loeliger879e4d22008-10-03 11:12:33 -050031
32char *xstrdup(const char *s)
33{
34 int len = strlen(s) + 1;
35 char *dup = xmalloc(len);
36
37 memcpy(dup, s, len);
38
39 return dup;
40}
David Gibsond68cb362009-12-08 14:24:42 +110041
42char *join_path(const char *path, const char *name)
43{
44 int lenp = strlen(path);
45 int lenn = strlen(name);
46 int len;
47 int needslash = 1;
48 char *str;
49
50 len = lenp + lenn + 2;
51 if ((lenp > 0) && (path[lenp-1] == '/')) {
52 needslash = 0;
53 len--;
54 }
55
56 str = xmalloc(len);
57 memcpy(str, path, lenp);
58 if (needslash) {
59 str[lenp] = '/';
60 lenp++;
61 }
62 memcpy(str+lenp, name, lenn+1);
63 return str;
64}
Simon Glass492f9d52011-07-05 12:02:49 -070065
66int util_is_printable_string(const void *data, int len)
67{
68 const char *s = data;
69 const char *ss;
70
71 /* zero length is not */
72 if (len == 0)
73 return 0;
74
75 /* must terminate with zero */
76 if (s[len - 1] != '\0')
77 return 0;
78
79 ss = s;
80 while (*s && isprint(*s))
81 s++;
82
83 /* not zero, or not done yet */
84 if (*s != '\0' || (s + 1 - ss) < len)
85 return 0;
86
87 return 1;
88}
Anton Staafb43335a2011-09-09 12:16:29 -070089
90/*
91 * Parse a octal encoded character starting at index i in string s. The
92 * resulting character will be returned and the index i will be updated to
93 * point at the character directly after the end of the encoding, this may be
94 * the '\0' terminator of the string.
95 */
96static char get_oct_char(const char *s, int *i)
97{
98 char x[4];
99 char *endx;
100 long val;
101
102 x[3] = '\0';
103 strncpy(x, s + *i, 3);
104
105 val = strtol(x, &endx, 8);
106
107 assert(endx > x);
108
109 (*i) += endx - x;
110 return val;
111}
112
113/*
114 * Parse a hexadecimal encoded character starting at index i in string s. The
115 * resulting character will be returned and the index i will be updated to
116 * point at the character directly after the end of the encoding, this may be
117 * the '\0' terminator of the string.
118 */
119static char get_hex_char(const char *s, int *i)
120{
121 char x[3];
122 char *endx;
123 long val;
124
125 x[2] = '\0';
126 strncpy(x, s + *i, 2);
127
128 val = strtol(x, &endx, 16);
129 if (!(endx > x))
130 die("\\x used with no following hex digits\n");
131
132 (*i) += endx - x;
133 return val;
134}
135
136char get_escape_char(const char *s, int *i)
137{
138 char c = s[*i];
139 int j = *i + 1;
140 char val;
141
142 assert(c);
143 switch (c) {
144 case 'a':
145 val = '\a';
146 break;
147 case 'b':
148 val = '\b';
149 break;
150 case 't':
151 val = '\t';
152 break;
153 case 'n':
154 val = '\n';
155 break;
156 case 'v':
157 val = '\v';
158 break;
159 case 'f':
160 val = '\f';
161 break;
162 case 'r':
163 val = '\r';
164 break;
165 case '0':
166 case '1':
167 case '2':
168 case '3':
169 case '4':
170 case '5':
171 case '6':
172 case '7':
173 j--; /* need to re-read the first digit as
174 * part of the octal value */
175 val = get_oct_char(s, &j);
176 break;
177 case 'x':
178 val = get_hex_char(s, &j);
179 break;
180 default:
181 val = c;
182 }
183
184 (*i) = j;
185 return val;
186}