2 * Copyright (c) 2005 Martin Decky
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 /* Dummy implementation of mem/ functions */
44 void *memset(void *s
, int c
, size_t n
)
56 } __attribute__ ((packed
));
58 static void *unaligned_memcpy(void *dst
, const void *src
, size_t n
)
61 struct along
*adst
= dst
;
62 const struct along
*asrc
= src
;
64 for (i
= 0; i
< n
/ sizeof(unsigned long); i
++)
65 adst
[i
].n
= asrc
[i
].n
;
67 for (j
= 0; j
< n
% sizeof(unsigned long); j
++)
68 ((unsigned char *) (((unsigned long *) dst
) + i
))[j
] = ((unsigned char *) (((unsigned long *) src
) + i
))[j
];
73 void *memcpy(void *dst
, const void *src
, size_t n
)
77 if (((long) dst
& (sizeof(long) - 1)) || ((long) src
& (sizeof(long) - 1)))
78 return unaligned_memcpy(dst
, src
, n
);
80 for (i
= 0; i
< n
/ sizeof(unsigned long); i
++)
81 ((unsigned long *) dst
)[i
] = ((unsigned long *) src
)[i
];
83 for (j
= 0; j
< n
% sizeof(unsigned long); j
++)
84 ((unsigned char *) (((unsigned long *) dst
) + i
))[j
] = ((unsigned char *) (((unsigned long *) src
) + i
))[j
];
89 void *memmove(void *dst
, const void *src
, size_t n
)
94 return memcpy(dst
, src
, n
);
96 for (j
= (n
% sizeof(unsigned long)) - 1; j
>= 0; j
--)
97 ((unsigned char *) ((unsigned long *) dst
))[j
] = ((unsigned char *) ((unsigned long *) src
))[j
];
99 for (i
= n
/ sizeof(unsigned long) - 1; i
>=0 ; i
--)
100 ((unsigned long *) dst
)[i
] = ((unsigned long *) src
)[i
];
106 /** Count the number of characters in the string, not including terminating 0.
108 * @return number of characters in string.
110 size_t strlen(const char *str
)
114 while (str
[counter
] != 0)
120 int strcmp(const char *a
, const char *b
)
124 while (a
[c
] && b
[c
] && (!(a
[c
] - b
[c
])))
127 return (a
[c
] - b
[c
]);
132 /** Return pointer to the first occurence of character c in string
133 * @param str scanned string
134 * @param c searched character (taken as one byte)
135 * @return pointer to the matched character or NULL if it is not found in given string.
137 char *strchr(const char *str
, int c
)
139 while (*str
!= '\0') {
140 if (*str
== (char) c
)
148 /** Return pointer to the last occurence of character c in string
149 * @param str scanned string
150 * @param c searched character (taken as one byte)
151 * @return pointer to the matched character or NULL if it is not found in given string.
153 char *strrchr(const char *str
, int c
)
157 while (*str
!= '\0') {
158 if (*str
== (char) c
)
159 retval
= (char *) str
;
163 return (char *) retval
;
166 /** Convert string to a number.
167 * Core of strtol and strtoul functions.
168 * @param nptr pointer to string
169 * @param endptr if not NULL, function stores here pointer to the first invalid character
170 * @param base zero or number between 2 and 36 inclusive
171 * @param sgn its set to 1 if minus found
172 * @return result of conversion.
174 static unsigned long _strtoul(const char *nptr
, char **endptr
, int base
, char *sgn
)
177 unsigned long result
= 0;
179 const char *str
= nptr
;
182 while (isspace(*str
))
188 } else if (*str
== '+')
192 if ((base
== 1) || (base
> 36)) {
193 /* FIXME: set errno to EINVAL */
196 if ((base
== 16) && (*str
== '0') && ((str
[1] == 'x') || (str
[1] == 'X'))) {
204 if ((str
[1] == 'X') || (str
[1] == 'x')) {
215 c
= (c
>= 'a' ? c
- 'a' + 10 : (c
>= 'A' ? c
- 'A' + 10 : (c
<= '9' ? c
- '0' : 0xff)));
220 a
= (result
& 0xff) * base
+ c
;
221 b
= (result
>> 8) * base
+ (a
>> 8);
223 if (b
> (ULONG_MAX
>> 8)) {
225 /* FIXME: errno = ERANGE*/
229 result
= (b
<< 8) + (a
& 0xff);
234 /* no number was found => first invalid character is the first character of the string */
235 /* FIXME: set errno to EINVAL */
241 *endptr
= (char *) str
;
244 /*FIXME: errno = EINVAL*/
251 /** Convert initial part of string to long int according to given base.
252 * The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-').
253 * If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one.
254 * If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8).
255 * Otherwise the base 0 is taken as decimal.
256 * @param nptr pointer to string
257 * @param endptr if not NULL, function stores here pointer to the first invalid character
258 * @param base zero or number between 2 and 36 inclusive
259 * @return result of conversion.
261 long int strtol(const char *nptr
, char **endptr
, int base
)
264 unsigned long number
= 0;
266 number
= _strtoul(nptr
, endptr
, base
, &sgn
);
268 if (number
> LONG_MAX
) {
269 if ((sgn
) && (number
== (unsigned long) (LONG_MAX
) + 1)) {
270 /* FIXME: set 0 to errno */
273 /* FIXME: set ERANGE to errno */
274 return (sgn
? LONG_MIN
: LONG_MAX
);
277 return (sgn
? -number
: number
);
281 /** Convert initial part of string to unsigned long according to given base.
282 * The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-').
283 * If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one.
284 * If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8).
285 * Otherwise the base 0 is taken as decimal.
286 * @param nptr pointer to string
287 * @param endptr if not NULL, function stores here pointer to the first invalid character
288 * @param base zero or number between 2 and 36 inclusive
289 * @return result of conversion.
291 unsigned long strtoul(const char *nptr
, char **endptr
, int base
)
294 unsigned long number
= 0;
296 number
= _strtoul(nptr
, endptr
, base
, &sgn
);
298 return (sgn
? -number
: number
);
301 char *strcpy(char *dest
, const char *src
)
305 while ((*(dest
++) = *(src
++)));
309 char *strncpy(char *dest
, const char *src
, size_t n
)
313 while ((*(dest
++) = *(src
++)) && --n
);