Subversion Repositories HelenOS

Rev

Rev 3022 | Rev 4296 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3022 Rev 4055
Line 1... Line 1...
1
/*
1
/*
2
 * Copyright (c) 2005 Martin Decky
2
 * Copyright (c) 2005 Martin Decky
-
 
3
 * Copyright (c) 2008 Jiri Svoboda
3
 * All rights reserved.
4
 * All rights reserved.
4
 *
5
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * are met:
Line 31... Line 32...
31
 */
32
 */
32
/** @file
33
/** @file
33
 */
34
 */
34
 
35
 
35
#include <string.h>
36
#include <string.h>
36
#include <unistd.h>
-
 
37
#include <ctype.h>
37
#include <stdlib.h>
38
#include <limits.h>
38
#include <limits.h>
39
#include <align.h>
39
#include <ctype.h>
40
#include <sys/types.h>
40
#include <malloc.h>
41
 
-
 
42
 
-
 
43
/* Dummy implementation of mem/ functions */
-
 
44
 
-
 
45
void *memset(void *s, int c, size_t n)
-
 
46
{
-
 
47
    char *os = s;
-
 
48
   
-
 
49
    while (n--)
-
 
50
        *(os++) = c;
-
 
51
   
-
 
52
    return s;
-
 
53
}
-
 
54
 
-
 
55
struct along {
-
 
56
    unsigned long n;
-
 
57
} __attribute__ ((packed));
-
 
58
 
-
 
59
static void *unaligned_memcpy(void *dst, const void *src, size_t n)
-
 
60
{
-
 
61
    int i, j;
-
 
62
    struct along *adst = dst;
-
 
63
    const struct along *asrc = src;
-
 
64
 
-
 
65
    for (i = 0; i < n / sizeof(unsigned long); i++)
-
 
66
        adst[i].n = asrc[i].n;
-
 
67
       
-
 
68
    for (j = 0; j < n % sizeof(unsigned long); j++)
-
 
69
        ((unsigned char *) (((unsigned long *) dst) + i))[j] = ((unsigned char *) (((unsigned long *) src) + i))[j];
-
 
70
       
-
 
71
    return (char *) src;
-
 
72
}
-
 
73
 
-
 
74
void *memcpy(void *dst, const void *src, size_t n)
-
 
75
{
-
 
76
    int i, j;
-
 
77
 
-
 
78
    if (((long) dst & (sizeof(long) - 1)) || ((long) src & (sizeof(long) - 1)))
-
 
79
        return unaligned_memcpy(dst, src, n);
-
 
80
 
-
 
81
    for (i = 0; i < n / sizeof(unsigned long); i++)
-
 
82
        ((unsigned long *) dst)[i] = ((unsigned long *) src)[i];
-
 
83
       
-
 
84
    for (j = 0; j < n % sizeof(unsigned long); j++)
-
 
85
        ((unsigned char *) (((unsigned long *) dst) + i))[j] = ((unsigned char *) (((unsigned long *) src) + i))[j];
-
 
86
       
-
 
87
    return (char *) src;
-
 
88
}
-
 
89
 
-
 
90
void *memmove(void *dst, const void *src, size_t n)
-
 
91
{
-
 
92
    int i, j;
-
 
93
   
-
 
94
    if (src > dst)
-
 
95
        return memcpy(dst, src, n);
-
 
96
 
-
 
97
    for (j = (n % sizeof(unsigned long)) - 1; j >= 0; j--)
-
 
98
        ((unsigned char *) ((unsigned long *) dst))[j] = ((unsigned char *) ((unsigned long *) src))[j];
-
 
99
 
-
 
100
    for (i = n / sizeof(unsigned long) - 1; i >=0 ; i--)
-
 
101
        ((unsigned long *) dst)[i] = ((unsigned long *) src)[i];
-
 
102
       
-
 
103
    return (char *) src;
-
 
104
}
-
 
105
 
-
 
106
/** Compare two memory areas.
-
 
107
 *
-
 
108
 * @param s1    Pointer to the first area to compare.
-
 
109
 * @param s2    Pointer to the second area to compare.
-
 
110
 * @param len   Size of the first area in bytes. Both areas must have the same
-
 
111
 *      length.
-
 
112
 * @return  If len is 0, return zero. If the areas match, return zero.
-
 
113
 *      Otherwise return non-zero.
-
 
114
 */
-
 
115
int bcmp(const char *s1, const char *s2, size_t len)
-
 
116
{
-
 
117
    for (; len && *s1++ == *s2++; len--)
-
 
118
        ;
-
 
119
    return len;
-
 
120
}
-
 
121
 
41
 
122
/** Count the number of characters in the string, not including terminating 0.
42
/** Count the number of characters in the string, not including terminating 0.
-
 
43
 *
123
 * @param str string
44
 * @param str       String.
124
 * @return number of characters in string.
45
 * @return      Number of characters in string.
125
 */
46
 */
126
size_t strlen(const char *str)
47
size_t strlen(const char *str)
127
{
48
{
128
    size_t counter = 0;
49
    size_t counter = 0;
129
 
50
 
Line 139... Line 60...
139
   
60
   
140
    while (a[c] && b[c] && (!(a[c] - b[c])))
61
    while (a[c] && b[c] && (!(a[c] - b[c])))
141
        c++;
62
        c++;
142
   
63
   
143
    return (a[c] - b[c]);
64
    return (a[c] - b[c]);
144
   
-
 
145
}
65
}
146
 
66
 
147
int strncmp(const char *a, const char *b, size_t n)
67
int strncmp(const char *a, const char *b, size_t n)
148
{
68
{
149
    size_t c = 0;
69
    size_t c = 0;
Line 153... Line 73...
153
   
73
   
154
    return ( c < n ? a[c] - b[c] : 0);
74
    return ( c < n ? a[c] - b[c] : 0);
155
   
75
   
156
}
76
}
157
 
77
 
-
 
78
int stricmp(const char *a, const char *b)
-
 
79
{
-
 
80
    int c = 0;
-
 
81
   
-
 
82
    while (a[c] && b[c] && (!(tolower(a[c]) - tolower(b[c]))))
-
 
83
        c++;
-
 
84
   
-
 
85
    return (tolower(a[c]) - tolower(b[c]));
-
 
86
}
-
 
87
 
158
/** Return pointer to the first occurence of character c in string
88
/** Return pointer to the first occurence of character c in string.
-
 
89
 *
159
 * @param str scanned string
90
 * @param str       Scanned string.
160
 * @param c searched character (taken as one byte)
91
 * @param c     Searched character (taken as one byte).
161
 * @return pointer to the matched character or NULL if it is not found in given string.
92
 * @return      Pointer to the matched character or NULL if it is not
-
 
93
 *          found in given string.
162
 */
94
 */
163
char *strchr(const char *str, int c)
95
char *strchr(const char *str, int c)
164
{
96
{
165
    while (*str != '\0') {
97
    while (*str != '\0') {
166
        if (*str == (char) c)
98
        if (*str == (char) c)
Line 169... Line 101...
169
    }
101
    }
170
 
102
 
171
    return NULL;
103
    return NULL;
172
}
104
}
173
 
105
 
174
/** Return pointer to the last occurence of character c in string
106
/** Return pointer to the last occurence of character c in string.
-
 
107
 *
175
 * @param str scanned string
108
 * @param str       Scanned string.
176
 * @param c searched character (taken as one byte)
109
 * @param c     Searched character (taken as one byte).
177
 * @return pointer to the matched character or NULL if it is not found in given string.
110
 * @return      Pointer to the matched character or NULL if it is not
-
 
111
 *          found in given string.
178
 */
112
 */
179
char *strrchr(const char *str, int c)
113
char *strrchr(const char *str, int c)
180
{
114
{
181
    char *retval = NULL;
115
    char *retval = NULL;
182
 
116
 
Line 189... Line 123...
189
    return (char *) retval;
123
    return (char *) retval;
190
}
124
}
191
 
125
 
192
/** Convert string to a number.
126
/** Convert string to a number.
193
 * Core of strtol and strtoul functions.
127
 * Core of strtol and strtoul functions.
-
 
128
 *
194
 * @param nptr pointer to string
129
 * @param nptr      Pointer to string.
195
 * @param endptr if not NULL, function stores here pointer to the first invalid character
130
 * @param endptr    If not NULL, function stores here pointer to the first
-
 
131
 *          invalid character.
196
 * @param base zero or number between 2 and 36 inclusive
132
 * @param base      Zero or number between 2 and 36 inclusive.
197
 * @param sgn its set to 1 if minus found
133
 * @param sgn       It's set to 1 if minus found.
198
 * @return result of conversion.
134
 * @return      Result of conversion.
199
 */
135
 */
-
 
136
static unsigned long
200
static unsigned long _strtoul(const char *nptr, char **endptr, int base, char *sgn)
137
_strtoul(const char *nptr, char **endptr, int base, char *sgn)
201
{
138
{
202
    unsigned char c;
139
    unsigned char c;
203
    unsigned long result = 0;
140
    unsigned long result = 0;
204
    unsigned long a, b;
141
    unsigned long a, b;
205
    const char *str = nptr;
142
    const char *str = nptr;
Line 217... Line 154...
217
    if (base) {
154
    if (base) {
218
        if ((base == 1) || (base > 36)) {
155
        if ((base == 1) || (base > 36)) {
219
            /* FIXME: set errno to EINVAL */
156
            /* FIXME: set errno to EINVAL */
220
            return 0;
157
            return 0;
221
        }
158
        }
222
        if ((base == 16) && (*str == '0') && ((str[1] == 'x') || (str[1] == 'X'))) {
159
        if ((base == 16) && (*str == '0') && ((str[1] == 'x') ||
-
 
160
            (str[1] == 'X'))) {
223
            str += 2;
161
            str += 2;
224
        }
162
        }
225
    } else {
163
    } else {
226
        base = 10;
164
        base = 10;
227
       
165
       
Line 236... Line 174...
236
   
174
   
237
    tmpptr = str;
175
    tmpptr = str;
238
 
176
 
239
    while (*str) {
177
    while (*str) {
240
        c = *str;
178
        c = *str;
241
        c = (c >= 'a' ? c - 'a' + 10 : (c >= 'A' ? c - 'A' + 10 : (c <= '9' ? c - '0' : 0xff)));
179
        c = (c >= 'a' ? c - 'a' + 10 : (c >= 'A' ? c - 'A' + 10 :
-
 
180
            (c <= '9' ? c - '0' : 0xff)));
242
        if (c > base) {
181
        if (c > base) {
243
            break;
182
            break;
244
        }
183
        }
245
       
184
       
246
        a = (result & 0xff) * base + c;
185
        a = (result & 0xff) * base + c;
Line 255... Line 194...
255
        result = (b << 8) + (a & 0xff);
194
        result = (b << 8) + (a & 0xff);
256
        ++str;
195
        ++str;
257
    }
196
    }
258
   
197
   
259
    if (str == tmpptr) {
198
    if (str == tmpptr) {
-
 
199
        /*
260
        /* no number was found => first invalid character is the first character of the string */
200
         * No number was found => first invalid character is the first
-
 
201
         * character of the string.
-
 
202
         */
261
        /* FIXME: set errno to EINVAL */
203
        /* FIXME: set errno to EINVAL */
262
        str = nptr;
204
        str = nptr;
263
        result = 0;
205
        result = 0;
264
    }
206
    }
265
   
207
   
Line 273... Line 215...
273
 
215
 
274
    return result;
216
    return result;
275
}
217
}
276
 
218
 
277
/** Convert initial part of string to long int according to given base.
219
/** Convert initial part of string to long int according to given base.
278
 * The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-').
220
 * The number may begin with an arbitrary number of whitespaces followed by
-
 
221
 * optional sign (`+' or `-'). If the base is 0 or 16, the prefix `0x' may be
279
 * If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one.
222
 * inserted and the number will be taken as hexadecimal one. If the base is 0
280
 * If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8).
223
 * and the number begin with a zero, number will be taken as octal one (as with
281
 * Otherwise the base 0 is taken as decimal.
224
 * base 8). Otherwise the base 0 is taken as decimal.
-
 
225
 *
282
 * @param nptr pointer to string
226
 * @param nptr      Pointer to string.
283
 * @param endptr if not NULL, function stores here pointer to the first invalid character
227
 * @param endptr    If not NULL, function stores here pointer to the first
-
 
228
 *          invalid character.
284
 * @param base zero or number between 2 and 36 inclusive
229
 * @param base      Zero or number between 2 and 36 inclusive.
285
 * @return result of conversion.
230
 * @return      Result of conversion.
286
 */
231
 */
287
long int strtol(const char *nptr, char **endptr, int base)
232
long int strtol(const char *nptr, char **endptr, int base)
288
{
233
{
289
    char sgn = 0;
234
    char sgn = 0;
290
    unsigned long number = 0;
235
    unsigned long number = 0;
Line 303... Line 248...
303
    return (sgn ? -number : number);
248
    return (sgn ? -number : number);
304
}
249
}
305
 
250
 
306
 
251
 
307
/** Convert initial part of string to unsigned long according to given base.
252
/** Convert initial part of string to unsigned long according to given base.
308
 * The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-').
253
 * The number may begin with an arbitrary number of whitespaces followed by
-
 
254
 * optional sign (`+' or `-'). If the base is 0 or 16, the prefix `0x' may be
309
 * If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one.
255
 * inserted and the number will be taken as hexadecimal one. If the base is 0
310
 * If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8).
256
 * and the number begin with a zero, number will be taken as octal one (as with
311
 * Otherwise the base 0 is taken as decimal.
257
 * base 8). Otherwise the base 0 is taken as decimal.
-
 
258
 *
312
 * @param nptr pointer to string
259
 * @param nptr      Pointer to string.
313
 * @param endptr if not NULL, function stores here pointer to the first invalid character
260
 * @param endptr    If not NULL, function stores here pointer to the first
-
 
261
 *          invalid character
314
 * @param base zero or number between 2 and 36 inclusive
262
 * @param base      Zero or number between 2 and 36 inclusive.
315
 * @return result of conversion.
263
 * @return      Result of conversion.
316
 */
264
 */
317
unsigned long strtoul(const char *nptr, char **endptr, int base)
265
unsigned long strtoul(const char *nptr, char **endptr, int base)
318
{
266
{
319
    char sgn = 0;
267
    char sgn = 0;
320
    unsigned long number = 0;
268
    unsigned long number = 0;
Line 351... Line 299...
351
    while ((*dest++ = *src++))
299
    while ((*dest++ = *src++))
352
        ;
300
        ;
353
    return orig;
301
    return orig;
354
}
302
}
355
 
303
 
-
 
304
char * strdup(const char *s1)
-
 
305
{
-
 
306
    size_t len = strlen(s1) + 1;
-
 
307
    void *ret = malloc(len);
-
 
308
 
-
 
309
    if (ret == NULL)
-
 
310
        return (char *) NULL;
-
 
311
 
-
 
312
    return (char *) memcpy(ret, s1, len);
-
 
313
}
-
 
314
 
-
 
315
char *strtok(char *s, const char *delim)
-
 
316
{
-
 
317
    static char *next;
-
 
318
 
-
 
319
    return strtok_r(s, delim, &next);
-
 
320
}
-
 
321
 
-
 
322
char *strtok_r(char *s, const char *delim, char **next)
-
 
323
{
-
 
324
    char *start, *end;
-
 
325
 
-
 
326
    if (s == NULL)
-
 
327
        s = *next;
-
 
328
 
-
 
329
    /* Skip over leading delimiters. */
-
 
330
    while (*s && (strchr(delim, *s) != NULL)) ++s;
-
 
331
    start = s;
-
 
332
 
-
 
333
    /* Skip over token characters. */
-
 
334
    while (*s && (strchr(delim, *s) == NULL)) ++s;
-
 
335
    end = s;
-
 
336
    *next = (*s ? s + 1 : s);
-
 
337
 
-
 
338
    if (start == end) {
-
 
339
        return NULL;    /* No more tokens. */
-
 
340
    }
-
 
341
 
-
 
342
    /* Overwrite delimiter with NULL terminator. */
-
 
343
    *end = '\0';
-
 
344
    return start;
-
 
345
}
-
 
346
 
356
/** @}
347
/** @}
357
 */
348
 */