1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  String routines				File: lib_string.c
5    *
6    *  Some standard routines for messing with strings.
7    *
8    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
9    *
10    *********************************************************************
11    *
12    *  Copyright 2000,2001,2002,2003
13    *  Broadcom Corporation. All rights reserved.
14    *
15    *  This software is furnished under license and may be used and
16    *  copied only in accordance with the following terms and
17    *  conditions.  Subject to these conditions, you may download,
18    *  copy, install, use, modify and distribute modified or unmodified
19    *  copies of this software in source and/or binary form.  No title
20    *  or ownership is transferred hereby.
21    *
22    *  1) Any source code used, modified or distributed must reproduce
23    *     and retain this copyright notice and list of conditions
24    *     as they appear in the source file.
25    *
26    *  2) No right is granted to use any trade name, trademark, or
27    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
28    *     name may not be used to endorse or promote products derived
29    *     from this software without the prior written permission of
30    *     Broadcom Corporation.
31    *
32    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44    *     THE POSSIBILITY OF SUCH DAMAGE.
45    ********************************************************************* */
46
47
48
49
50#include "lib_types.h"
51#define _LIB_NO_MACROS_
52#include "lib_string.h"
53
54char *lib_strcpy(char *dest,const char *src)
55{
56    char *ptr = dest;
57
58    while (*src) *ptr++ = *src++;
59    *ptr = '\0';
60
61    return dest;
62}
63
64char *lib_strncpy(char *dest,const char *src,size_t cnt)
65{
66    char *ptr = dest;
67
68    while (*src && (cnt > 0)) {
69	*ptr++ = *src++;
70	cnt--;
71	}
72    if (cnt > 0) *ptr = '\0';
73
74    return dest;
75}
76
77
78size_t lib_xstrncpy(char *dest,const char *src,size_t cnt)
79{
80    char *ptr = dest;
81    size_t copied = 0;
82
83    while (*src && (cnt > 1)) {
84	*ptr++ = *src++;
85	cnt--;
86	copied++;
87	}
88    *ptr = '\0';
89
90    return copied;
91}
92
93size_t lib_strlen(const char *str)
94{
95    size_t cnt = 0;
96
97    while (*str) {
98	str++;
99	cnt++;
100	}
101
102    return cnt;
103}
104
105
106int lib_strcmp(const char *dest,const char *src)
107{
108    while (*src && *dest) {
109	if (*dest < *src) return -1;
110	if (*dest > *src) return 1;
111	dest++;
112	src++;
113	}
114
115    if (*dest && !*src) return 1;
116    if (!*dest && *src) return -1;
117    return 0;
118}
119
120int lib_strncmp(const char *dest, const char *src, size_t cnt )
121{
122    while (*src && *dest && cnt) {
123	if (*dest < *src ) return -1;
124	if (*dest > *src) return 1;
125	dest++;
126	src++;
127	cnt--;
128	}
129
130    if (!cnt) return 0;
131    if (*dest && !*src) return 1;
132    if (!*dest && *src) return -1;
133    return 0;
134}
135
136int lib_strcmpi(const char *dest,const char *src)
137{
138    char dc,sc;
139
140    while (*src && *dest) {
141	dc = lib_toupper(*dest);
142	sc = lib_toupper(*src);
143	if (dc < sc) return -1;
144	if (dc > sc) return 1;
145	dest++;
146	src++;
147	}
148
149    if (*dest && !*src) return 1;
150    if (!*dest && *src) return -1;
151    return 0;
152}
153
154
155char *lib_strchr(const char *dest,int c)
156{
157    while (*dest) {
158	if (*dest == c) return (char *) dest;
159	dest++;
160	}
161    return NULL;
162}
163
164char *lib_strnchr(const char *dest,int c,size_t cnt)
165{
166    while (*dest && (cnt > 0)) {
167	if (*dest == c) return (char *) dest;
168	dest++;
169	cnt--;
170	}
171    return NULL;
172}
173
174char *lib_strrchr(const char *dest,int c)
175{
176    char *ret = NULL;
177
178    while (*dest) {
179	if (*dest == c) ret = (char *) dest;
180	dest++;
181	}
182
183    return ret;
184}
185
186
187int lib_memcmp(const void *dest,const void *src,size_t cnt)
188{
189    const unsigned char *d;
190    const unsigned char *s;
191
192    d = (const unsigned char *) dest;
193    s = (const unsigned char *) src;
194
195    while (cnt) {
196	if (*d < *s) return -1;
197	if (*d > *s) return 1;
198	d++; s++; cnt--;
199	}
200
201    return 0;
202}
203
204void *lib_memcpy(void *dest,const void *src,size_t cnt)
205{
206    unsigned char *d;
207    const unsigned char *s;
208
209    d = (unsigned char *) dest;
210    s = (const unsigned char *) src;
211
212    while (cnt) {
213	*d++ = *s++;
214	cnt--;
215	}
216
217    return dest;
218}
219
220void *lib_memset(void *dest,int c,size_t cnt)
221{
222    unsigned char *d;
223
224    d = dest;
225
226    while (cnt) {
227	*d++ = (unsigned char) c;
228	cnt--;
229	}
230
231    return d;
232}
233
234#ifdef __GNUC__
235/* gcc may generate calls to memcmp, memset, and memcpy */
236int memcmp(const void *dest,const void *src,size_t cnt) __attribute__((alias("lib_memcmp")));
237void *memcpy(void *dest,const void *src,size_t cnt) __attribute__((alias("lib_memcpy")));
238void *memset(void *dest,int c,size_t cnt) __attribute__((alias("lib_memset")));
239#endif
240
241char lib_toupper(char c)
242{
243    if ((c >= 'a') && (c <= 'z')) c -= 32;
244    return c;
245}
246
247void lib_strupr(char *str)
248{
249    while (*str) {
250	*str = lib_toupper(*str);
251	str++;
252	}
253}
254
255char *lib_strcat(char *dest,const char *src)
256{
257    char *ptr = dest;
258
259    while (*ptr) ptr++;
260    while (*src) *ptr++ = *src++;
261    *ptr = '\0';
262
263    return dest;
264}
265
266#define isspace(x) (((x) == ' ') || ((x) == '\t'))
267
268char *lib_gettoken(char **ptr)
269{
270    char *p = *ptr;
271    char *ret;
272
273    /* skip white space */
274
275    while (*p && isspace(*p)) p++;
276    ret = p;
277
278    /* check for end of string */
279
280    if (!*p) {
281	*ptr = p;
282	return NULL;
283	}
284
285    /* skip non-whitespace */
286
287    while (*p) {
288	if (isspace(*p)) break;
289
290	/* do quoted strings */
291
292	if (*p == '"') {
293	    p++;
294	    ret = p;
295	    while (*p && (*p != '"')) p++;
296	    if (*p == '"') *p = '\0';
297	    }
298
299        p++;
300
301	}
302
303    if (*p) {
304        *p++ = '\0';
305        }
306    *ptr = p;
307
308    return ret;
309}
310
311
312int lib_atoi(const char *dest)
313{
314    int x = 0;
315    int digit;
316
317    if ((*dest == '0') && (*(dest+1) == 'x')) {
318	return lib_xtoi(dest+2);
319	}
320
321    while (*dest) {
322	if ((*dest >= '0') && (*dest <= '9')) {
323	    digit = *dest - '0';
324	    }
325	else {
326	    break;
327	    }
328	x *= 10;
329	x += digit;
330	dest++;
331	}
332
333    return x;
334}
335
336uint64_t lib_xtoq(const char *dest)
337{
338    uint64_t x = 0;
339    unsigned int digit;
340
341    if ((*dest == '0') && (*(dest+1) == 'x')) dest += 2;
342
343    while (*dest) {
344	if ((*dest >= '0') && (*dest <= '9')) {
345	    digit = *dest - '0';
346	    }
347	else if ((*dest >= 'A') && (*dest <= 'F')) {
348	    digit = 10 + *dest - 'A';
349	    }
350	else if ((*dest >= 'a') && (*dest <= 'f')) {
351	    digit = 10 + *dest - 'a';
352	    }
353	else {
354	    break;
355	    }
356	x *= 16;
357	x += digit;
358	dest++;
359	}
360
361    return x;
362}
363
364int lib_xtoi(const char *dest)
365{
366    int x = 0;
367    int digit;
368
369    if ((*dest == '0') && (*(dest+1) == 'x')) dest += 2;
370
371    while (*dest) {
372	if ((*dest >= '0') && (*dest <= '9')) {
373	    digit = *dest - '0';
374	    }
375	else if ((*dest >= 'A') && (*dest <= 'F')) {
376	    digit = 10 + *dest - 'A';
377	    }
378	else if ((*dest >= 'a') && (*dest <= 'f')) {
379	    digit = 10 + *dest - 'a';
380	    }
381	else {
382	    break;
383	    }
384	x *= 16;
385	x += digit;
386	dest++;
387	}
388
389    return x;
390}
391