These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / core / string.c
1 /*
2  * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <stddef.h>
27 #include <stdint.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <ctype.h>
31
32 /** @file
33  *
34  * String functions
35  *
36  */
37
38 /**
39  * Fill memory region
40  *
41  * @v dest              Destination region
42  * @v character         Fill character
43  * @v len               Length
44  * @ret dest            Destination region
45  */
46 void * generic_memset ( void *dest, int character, size_t len ) {
47         uint8_t *dest_bytes = dest;
48
49         while ( len-- )
50                 *(dest_bytes++) = character;
51         return dest;
52 }
53
54 /**
55  * Copy memory region
56  *
57  * @v dest              Destination region
58  * @v src               Source region
59  * @v len               Length
60  * @ret dest            Destination region
61  */
62 void * generic_memcpy ( void *dest, const void *src, size_t len ) {
63         const uint8_t *src_bytes = src;
64         uint8_t *dest_bytes = dest;
65
66         while ( len-- )
67                 *(dest_bytes++) = *(src_bytes++);
68         return dest;
69 }
70
71 /**
72  * Copy (possibly overlapping) memory region
73  *
74  * @v dest              Destination region
75  * @v src               Source region
76  * @v len               Length
77  * @ret dest            Destination region
78  */
79 void * generic_memmove ( void *dest, const void *src, size_t len ) {
80         const uint8_t *src_bytes = ( src + len );
81         uint8_t *dest_bytes = ( dest + len );
82
83         if ( dest < src )
84                 return memcpy ( dest, src, len );
85         while ( len-- )
86                 *(--dest_bytes) = *(--src_bytes);
87         return dest;
88 }
89
90 /**
91  * Compare memory regions
92  *
93  * @v first             First region
94  * @v second            Second region
95  * @v len               Length
96  * @ret diff            Difference
97  */
98 int memcmp ( const void *first, const void *second, size_t len ) {
99         const uint8_t *first_bytes = first;
100         const uint8_t *second_bytes = second;
101         int diff;
102
103         while ( len-- ) {
104                 diff = ( *(second_bytes++) - *(first_bytes++) );
105                 if ( diff )
106                         return diff;
107         }
108         return 0;
109 }
110
111 /**
112  * Find character within a memory region
113  *
114  * @v src               Source region
115  * @v character         Character to find
116  * @v len               Length
117  * @ret found           Found character, or NULL if not found
118  */
119 void * memchr ( const void *src, int character, size_t len ) {
120         const uint8_t *src_bytes = src;
121
122         for ( ; len-- ; src_bytes++ ) {
123                 if ( *src_bytes == character )
124                         return ( ( void * ) src_bytes );
125         }
126         return NULL;
127 }
128
129 /**
130  * Swap memory regions
131  *
132  * @v first             First region
133  * @v second            Second region
134  * @v len               Length
135  * @ret first           First region
136  */
137 void * memswap ( void *first, void *second, size_t len ) {
138         uint8_t *first_bytes = first;
139         uint8_t *second_bytes = second;
140         uint8_t temp;
141
142         for ( ; len-- ; first_bytes++, second_bytes++ ) {
143                 temp = *first_bytes;
144                 *first_bytes = *second_bytes;
145                 *second_bytes = temp;
146         }
147         return first;
148 }
149
150 /**
151  * Compare strings
152  *
153  * @v first             First string
154  * @v second            Second string
155  * @ret diff            Difference
156  */
157 int strcmp ( const char *first, const char *second ) {
158
159         return strncmp ( first, second, ~( ( size_t ) 0 ) );
160 }
161
162 /**
163  * Compare strings
164  *
165  * @v first             First string
166  * @v second            Second string
167  * @v max               Maximum length to compare
168  * @ret diff            Difference
169  */
170 int strncmp ( const char *first, const char *second, size_t max ) {
171         const uint8_t *first_bytes = ( ( const uint8_t * ) first );
172         const uint8_t *second_bytes = ( ( const uint8_t * ) second );
173         int diff;
174
175         for ( ; max-- ; first_bytes++, second_bytes++ ) {
176                 diff = ( *second_bytes - *first_bytes );
177                 if ( diff )
178                         return diff;
179                 if ( ! *first_bytes )
180                         return 0;
181         }
182         return 0;
183 }
184
185 /**
186  * Compare case-insensitive strings
187  *
188  * @v first             First string
189  * @v second            Second string
190  * @ret diff            Difference
191  */
192 int strcasecmp ( const char *first, const char *second ) {
193         const uint8_t *first_bytes = ( ( const uint8_t * ) first );
194         const uint8_t *second_bytes = ( ( const uint8_t * ) second );
195         int diff;
196
197         for ( ; ; first_bytes++, second_bytes++ ) {
198                 diff = ( toupper ( *second_bytes ) -
199                          toupper ( *first_bytes ) );
200                 if ( diff )
201                         return diff;
202                 if ( ! *first_bytes )
203                         return 0;
204         }
205 }
206
207 /**
208  * Get length of string
209  *
210  * @v src               String
211  * @ret len             Length
212  */
213 size_t strlen ( const char *src ) {
214
215         return strnlen ( src, ~( ( size_t ) 0 ) );
216 }
217
218 /**
219  * Get length of string
220  *
221  * @v src               String
222  * @v max               Maximum length
223  * @ret len             Length
224  */
225 size_t strnlen ( const char *src, size_t max ) {
226         const uint8_t *src_bytes = ( ( const uint8_t * ) src );
227         size_t len = 0;
228
229         while ( max-- && *(src_bytes++) )
230                 len++;
231         return len;
232 }
233
234 /**
235  * Find character within a string
236  *
237  * @v src               String
238  * @v character         Character to find
239  * @ret found           Found character, or NULL if not found
240  */
241 char * strchr ( const char *src, int character ) {
242         const uint8_t *src_bytes = ( ( const uint8_t * ) src );
243
244         for ( ; ; src_bytes++ ) {
245                 if ( *src_bytes == character )
246                         return ( ( char * ) src_bytes );
247                 if ( ! *src_bytes )
248                         return NULL;
249         }
250 }
251
252 /**
253  * Find rightmost character within a string
254  *
255  * @v src               String
256  * @v character         Character to find
257  * @ret found           Found character, or NULL if not found
258  */
259 char * strrchr ( const char *src, int character ) {
260         const uint8_t *src_bytes = ( ( const uint8_t * ) src );
261         const uint8_t *start = src_bytes;
262
263         while ( *src_bytes )
264                 src_bytes++;
265         for ( src_bytes-- ; src_bytes >= start ; src_bytes-- ) {
266                 if ( *src_bytes == character )
267                         return ( ( char * ) src_bytes );
268         }
269         return NULL;
270 }
271
272 /**
273  * Find substring
274  *
275  * @v haystack          String
276  * @v needle            Substring
277  * @ret found           Found substring, or NULL if not found
278  */
279 char * strstr ( const char *haystack, const char *needle ) {
280         size_t len = strlen ( needle );
281
282         for ( ; *haystack ; haystack++ ) {
283                 if ( memcmp ( haystack, needle, len ) == 0 )
284                         return ( ( char * ) haystack );
285         }
286         return NULL;
287 }
288
289 /**
290  * Copy string
291  *
292  * @v dest              Destination string
293  * @v src               Source string
294  * @ret dest            Destination string
295  */
296 char * strcpy ( char *dest, const char *src ) {
297         const uint8_t *src_bytes = ( ( const uint8_t * ) src );
298         uint8_t *dest_bytes = ( ( uint8_t * ) dest );
299
300         /* We cannot use strncpy(), since that would pad the destination */
301         for ( ; ; src_bytes++, dest_bytes++ ) {
302                 *dest_bytes = *src_bytes;
303                 if ( ! *dest_bytes )
304                         break;
305         }
306         return dest;
307 }
308
309 /**
310  * Copy string
311  *
312  * @v dest              Destination string
313  * @v src               Source string
314  * @v max               Maximum length
315  * @ret dest            Destination string
316  */
317 char * strncpy ( char *dest, const char *src, size_t max ) {
318         const uint8_t *src_bytes = ( ( const uint8_t * ) src );
319         uint8_t *dest_bytes = ( ( uint8_t * ) dest );
320
321         for ( ; max ; max--, src_bytes++, dest_bytes++ ) {
322                 *dest_bytes = *src_bytes;
323                 if ( ! *dest_bytes )
324                         break;
325         }
326         while ( max-- )
327                 *(dest_bytes++) = '\0';
328         return dest;
329 }
330
331 /**
332  * Concatenate string
333  *
334  * @v dest              Destination string
335  * @v src               Source string
336  * @ret dest            Destination string
337  */
338 char * strcat ( char *dest, const char *src ) {
339
340         strcpy ( ( dest + strlen ( dest ) ), src );
341         return dest;
342 }
343
344 /**
345  * Duplicate string
346  *
347  * @v src               Source string
348  * @ret dup             Duplicated string, or NULL if allocation failed
349  */
350 char * strdup ( const char *src ) {
351
352         return strndup ( src, ~( ( size_t ) 0 ) );
353 }
354
355 /**
356  * Duplicate string
357  *
358  * @v src               Source string
359  * @v max               Maximum length
360  * @ret dup             Duplicated string, or NULL if allocation failed
361  */
362 char * strndup ( const char *src, size_t max ) {
363         size_t len = strnlen ( src, max );
364         char *dup;
365
366         dup = malloc ( len + 1 /* NUL */ );
367         if ( dup ) {
368                 memcpy ( dup, src, len );
369                 dup[len] = '\0';
370         }
371         return dup;
372 }
373
374 /**
375  * Calculate digit value
376  *
377  * @v character         Digit character
378  * @ret digit           Digit value
379  *
380  * Invalid digits will be returned as a value greater than or equal to
381  * the numeric base.
382  */
383 unsigned int digit_value ( unsigned int character ) {
384
385         if ( character >= 'a' )
386                 return ( character - ( 'a' - 10 ) );
387         if ( character >= 'A' )
388                 return ( character - ( 'A' - 10 ) );
389         if ( character <= '9' )
390                 return ( character - '0' );
391         return character;
392 }
393
394 /**
395  * Preprocess string for strtoul() or strtoull()
396  *
397  * @v string            String
398  * @v negate            Final value should be negated
399  * @v base              Numeric base
400  * @ret string          Remaining string
401  */
402 static const char * strtoul_pre ( const char *string, int *negate, int *base ) {
403
404         /* Skip any leading whitespace */
405         while ( isspace ( *string ) )
406                 string++;
407
408         /* Process arithmetic sign, if present */
409         *negate = 0;
410         if ( *string == '-' ) {
411                 string++;
412                 *negate = 1;
413         } else if ( *string == '+' ) {
414                 string++;
415         }
416
417         /* Process base, if present */
418         if ( *base == 0 ) {
419                 *base = 10;
420                 if ( *string == '0' ) {
421                         string++;
422                         *base = 8;
423                         if ( ( *string & ~0x20 ) == 'X' ) {
424                                 string++;
425                                 *base = 16;
426                         }
427                 }
428         }
429
430         return string;
431 }
432
433 /**
434  * Convert string to numeric value
435  *
436  * @v string            String
437  * @v endp              End pointer (or NULL)
438  * @v base              Numeric base (or zero to autodetect)
439  * @ret value           Numeric value
440  */
441 unsigned long strtoul ( const char *string, char **endp, int base ) {
442         unsigned long value = 0;
443         unsigned int digit;
444         int negate;
445
446         /* Preprocess string */
447         string = strtoul_pre ( string, &negate, &base );
448
449         /* Process digits */
450         for ( ; ; string++ ) {
451                 digit = digit_value ( *string );
452                 if ( digit >= ( unsigned int ) base )
453                         break;
454                 value = ( ( value * base ) + digit );
455         }
456
457         /* Negate value if, applicable */
458         if ( negate )
459                 value = -value;
460
461         /* Fill in end pointer, if applicable */
462         if ( endp )
463                 *endp = ( ( char * ) string );
464
465         return value;
466 }
467
468 /**
469  * Convert string to numeric value
470  *
471  * @v string            String
472  * @v endp              End pointer (or NULL)
473  * @v base              Numeric base (or zero to autodetect)
474  * @ret value           Numeric value
475  */
476 unsigned long long strtoull ( const char *string, char **endp, int base ) {
477         unsigned long long value = 0;
478         unsigned int digit;
479         int negate;
480
481         /* Preprocess string */
482         string = strtoul_pre ( string, &negate, &base );
483
484         /* Process digits */
485         for ( ; ; string++ ) {
486                 digit = digit_value ( *string );
487                 if ( digit >= ( unsigned int ) base )
488                         break;
489                 value = ( ( value * base ) + digit );
490         }
491
492         /* Negate value if, applicable */
493         if ( negate )
494                 value = -value;
495
496         /* Fill in end pointer, if applicable */
497         if ( endp )
498                 *endp = ( ( char * ) string );
499
500         return value;
501 }