• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2007-2008 The Android Open Source Project
2 **
3 ** This software is licensed under the terms of the GNU General Public
4 ** License version 2, as published by the Free Software Foundation, and
5 ** may be copied, distributed, and modified under those terms.
6 **
7 ** This program is distributed in the hope that it will be useful,
8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 ** GNU General Public License for more details.
11 */
12 
13 #include "qemu-common.h"
14 #include "android/utils/misc.h"
15 #include "android/utils/stralloc.h"
16 #include "android/utils/debug.h"
17 #include <string.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 
21 #define  E(...)    derror(__VA_ARGS__)
22 
23 extern void
print_tabular(const char ** strings,int count,const char * prefix,int width)24 print_tabular( const char** strings, int  count,
25                const char*  prefix,  int  width )
26 {
27     int  nrows, ncols, r, c, n, maxw = 0;
28 
29     for (n = 0; n < count; n++) {
30         int  len = strlen(strings[n]);
31         if (len > maxw)
32             maxw = len;
33     }
34     maxw += 2;
35     ncols = width/maxw;
36     nrows = (count + ncols-1)/ncols;
37 
38     for (r = 0; r < nrows; r++) {
39         printf( "%s", prefix );
40         for (c = 0; c < ncols; c++) {
41             int  index = c*nrows + r;
42             if (index >= count) {
43                 break;
44             }
45             printf( "%-*s", maxw, strings[index] );
46         }
47         printf( "\n" );
48     }
49 }
50 
51 extern void
string_translate_char(char * str,char from,char to)52 string_translate_char( char*  str, char from, char to )
53 {
54     char*  p = str;
55     while (p != NULL && (p = strchr(p, from)) != NULL)
56         *p++ = to;
57 }
58 
59 extern void
buffer_translate_char(char * buff,unsigned buffLen,const char * src,char fromChar,char toChar)60 buffer_translate_char( char*        buff,
61                        unsigned     buffLen,
62                        const char*  src,
63                        char         fromChar,
64                        char         toChar )
65 {
66     int    len = strlen(src);
67 
68     if (len >= buffLen)
69         len = buffLen-1;
70 
71     memcpy(buff, src, len);
72     buff[len] = 0;
73 
74     string_translate_char( buff, fromChar, toChar );
75 }
76 
77 
78 /** TEMP CHAR STRINGS
79  **
80  ** implement a circular ring of temporary string buffers
81  **/
82 
83 typedef struct Temptring {
84     struct TempString*  next;
85     char*               buffer;
86     int                 size;
87 } TempString;
88 
89 #define  MAX_TEMP_STRINGS   16
90 
91 static TempString  _temp_strings[ MAX_TEMP_STRINGS ];
92 static int         _temp_string_n;
93 
94 extern char*
tempstr_get(int size)95 tempstr_get( int  size )
96 {
97     TempString*  t = &_temp_strings[_temp_string_n];
98 
99     if ( ++_temp_string_n >= MAX_TEMP_STRINGS )
100         _temp_string_n = 0;
101 
102     size += 1;  /* reserve 1 char for terminating zero */
103 
104     if (t->size < size) {
105         t->buffer = realloc( t->buffer, size );
106         if (t->buffer == NULL) {
107             derror( "%s: could not allocate %d bytes",
108                     __FUNCTION__, size );
109             exit(1);
110         }
111         t->size   = size;
112     }
113     return  t->buffer;
114 }
115 
116 extern char*
tempstr_format(const char * fmt,...)117 tempstr_format( const char*  fmt, ... )
118 {
119     va_list  args;
120     char*    result;
121     STRALLOC_DEFINE(s);
122     va_start(args, fmt);
123     stralloc_formatv(s, fmt, args);
124     va_end(args);
125     result = stralloc_to_tempstr(s);
126     stralloc_reset(s);
127     return result;
128 }
129 
130 /** QUOTING
131  **
132  ** dumps a human-readable version of a string. this replaces
133  ** newlines with \n, etc...
134  **/
135 
136 extern const char*
quote_bytes(const char * str,int len)137 quote_bytes( const char*  str, int  len )
138 {
139     STRALLOC_DEFINE(s);
140     char*  q;
141 
142     stralloc_add_quote_bytes( s, str, len );
143     q = stralloc_to_tempstr( s );
144     stralloc_reset(s);
145     return q;
146 }
147 
148 extern const char*
quote_str(const char * str)149 quote_str( const char*  str )
150 {
151     int  len = strlen(str);
152     return quote_bytes( str, len );
153 }
154 
155 /** HEXADECIMAL CHARACTER SEQUENCES
156  **/
157 
158 static int
hexdigit(int c)159 hexdigit( int  c )
160 {
161     unsigned  d;
162 
163     d = (unsigned)(c - '0');
164     if (d < 10) return d;
165 
166     d = (unsigned)(c - 'a');
167     if (d < 6) return d+10;
168 
169     d = (unsigned)(c - 'A');
170     if (d < 6) return d+10;
171 
172     return -1;
173 }
174 
175 int
hex2int(const uint8_t * hex,int len)176 hex2int( const uint8_t*  hex, int  len )
177 {
178     int  result = 0;
179     while (len > 0) {
180         int  c = hexdigit(*hex++);
181         if (c < 0)
182             return -1;
183 
184         result = (result << 4) | c;
185         len --;
186     }
187     return result;
188 }
189 
190 void
int2hex(uint8_t * hex,int len,int val)191 int2hex( uint8_t*  hex, int  len, int  val )
192 {
193     static const uint8_t  hexchars[16] = "0123456789abcdef";
194     while ( --len >= 0 )
195         *hex++ = hexchars[(val >> (len*4)) & 15];
196 }
197 
198 /** STRING PARAMETER PARSING
199  **/
200 
201 int
strtoi(const char * nptr,char ** endptr,int base)202 strtoi(const char *nptr, char **endptr, int base)
203 {
204     long val;
205 
206     errno = 0;
207     val = strtol(nptr, endptr, base);
208     if (errno) {
209         return (val == LONG_MAX) ? INT_MAX : INT_MIN;
210     } else {
211         if (val == (int)val) {
212             return (int)val;
213         } else {
214             errno = ERANGE;
215             return val > 0 ? INT_MAX : INT_MIN;
216         }
217     }
218 }
219 
220 int
get_token_value(const char * params,const char * name,char * value,int val_size)221 get_token_value(const char* params, const char* name, char* value, int val_size)
222 {
223     const char* val_end;
224     int len = strlen(name);
225     const char* par_end = params + strlen(params);
226     const char* par_start = strstr(params, name);
227 
228     /* Search for 'name=' */
229     while (par_start != NULL) {
230         /* Make sure that we're within the parameters buffer. */
231         if ((par_end - par_start) < len) {
232             par_start = NULL;
233             break;
234         }
235         /* Make sure that par_start starts at the beginning of <name>, and only
236          * then check for '=' value separator. */
237         if ((par_start == params || (*(par_start - 1) == ' ')) &&
238                 par_start[len] == '=') {
239             break;
240         }
241         /* False positive. Move on... */
242         par_start = strstr(par_start + 1, name);
243     }
244     if (par_start == NULL) {
245         return -1;
246     }
247 
248     /* Advance past 'name=', and calculate value's string length. */
249     par_start += len + 1;
250     val_end = strchr(par_start, ' ');
251     if (val_end == NULL) {
252         val_end = par_start + strlen(par_start);
253     }
254     len = val_end - par_start;
255 
256     /* Check if fits... */
257     if ((len + 1) <= val_size) {
258         memcpy(value, par_start, len);
259         value[len] = '\0';
260         return 0;
261     } else {
262         return len + 1;
263     }
264 }
265 
266 int
get_token_value_alloc(const char * params,const char * name,char ** value)267 get_token_value_alloc(const char* params, const char* name, char** value)
268 {
269     char tmp;
270     int res;
271 
272     /* Calculate size of string buffer required for the value. */
273     const int val_size = get_token_value(params, name, &tmp, 0);
274     if (val_size < 0) {
275         *value = NULL;
276         return val_size;
277     }
278 
279     /* Allocate string buffer, and retrieve the value. */
280     *value = (char*)malloc(val_size);
281     if (*value == NULL) {
282         E("%s: Unable to allocated %d bytes for string buffer.",
283           __FUNCTION__, val_size);
284         return -2;
285     }
286     res = get_token_value(params, name, *value, val_size);
287     if (res) {
288         E("%s: Unable to retrieve value into allocated buffer.", __FUNCTION__);
289         free(*value);
290         *value = NULL;
291     }
292 
293     return res;
294 }
295 
296 int
get_token_value_int(const char * params,const char * name,int * value)297 get_token_value_int(const char* params, const char* name, int* value)
298 {
299     char val_str[64];   // Should be enough for all numeric values.
300     if (!get_token_value(params, name, val_str, sizeof(val_str))) {
301         errno = 0;
302         *value = strtoi(val_str, (char**)NULL, 10);
303         if (errno) {
304             E("%s: Value '%s' of the parameter '%s' in '%s' is not a decimal number.",
305               __FUNCTION__, val_str, name, params);
306             return -2;
307         } else {
308             return 0;
309         }
310     } else {
311         return -1;
312     }
313 }
314