1 /* Copyright (C) 2002 Manuel Novoa III
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Library General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Library General Public License for more details.
13 * You should have received a copy of the GNU Library General Public
14 * License along with this library; if not, write to the Free
15 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 /* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
20 * Besides uClibc, I'm using this code in my libc for elks, which is
21 * a 16-bit environment with a fairly limited compiler. It would make
22 * things much easier for me if this file isn't modified unnecessarily.
23 * In particular, please put any new or replacement functions somewhere
24 * else, and modify the makefile to use your version instead.
27 * ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */
29 #define _STDIO_UTILITY
46 #define Wuchar __uwchar_t
53 typedef unsigned char __string_uchar_t;
54 #define Wuchar __string_uchar_t
59 /**********************************************************************/
60 /* NOTE: If we ever do internationalized syserr messages, this will
61 * have to be changed! */
63 #if _SYS_ERRMSG_MAXLEN < __UIM_BUFLEN_INT + 14
64 #define _STRERROR_BUFSIZE (__UIM_BUFLEN_INT + 14)
66 #define _STRERROR_BUFSIZE _SYS_ERRMSG_MAXLEN
70 #define _SYS_ERRMSG_MAXLEN 50
72 extern const char _string_syserrmsgs[];
74 /**********************************************************************/
75 #ifdef L__string_syserrmsgs
77 const char _string_syserrmsgs[] = {
78 /* 0: 0, 8 */ "Success\0"
79 /* 1: 8, 24 */ "Operation not permitted\0"
80 /* 2: 32, 26 */ "No such file or directory\0"
81 /* 3: 58, 16 */ "No such process\0"
82 /* 4: 74, 24 */ "Interrupted system call\0"
83 /* 5: 98, 19 */ "Input/output error\0"
84 /* 6: 117, 26 */ "No such device or address\0"
85 /* 7: 143, 23 */ "Argument list too long\0"
86 /* 8: 166, 18 */ "Exec format error\0"
87 /* 9: 184, 20 */ "Bad file descriptor\0"
88 /* 10: 204, 19 */ "No child processes\0"
89 /* 11: 223, 33 */ "Resource temporarily unavailable\0"
90 /* 12: 256, 23 */ "Cannot allocate memory\0"
91 /* 13: 279, 18 */ "Permission denied\0"
92 /* 14: 297, 12 */ "Bad address\0"
93 /* 15: 309, 22 */ "Block device required\0"
94 /* 16: 331, 24 */ "Device or resource busy\0"
95 /* 17: 355, 12 */ "File exists\0"
96 /* 18: 367, 26 */ "Invalid cross-device link\0"
97 /* 19: 393, 15 */ "No such device\0"
98 /* 20: 408, 16 */ "Not a directory\0"
99 /* 21: 424, 15 */ "Is a directory\0"
100 /* 22: 439, 17 */ "Invalid argument\0"
101 /* 23: 456, 30 */ "Too many open files in system\0"
102 /* 24: 486, 20 */ "Too many open files\0"
103 /* 25: 506, 31 */ "Inappropriate ioctl for device\0"
104 /* 26: 537, 15 */ "Text file busy\0"
105 /* 27: 552, 15 */ "File too large\0"
106 /* 28: 567, 24 */ "No space left on device\0"
107 /* 29: 591, 13 */ "Illegal seek\0"
108 /* 30: 604, 22 */ "Read-only file system\0"
109 /* 31: 626, 15 */ "Too many links\0"
110 /* 32: 641, 12 */ "Broken pipe\0"
111 /* 33: 653, 33 */ "Numerical argument out of domain\0"
112 /* 34: 686, 30 */ "Numerical result out of range\0"
113 /* 35: 716, 26 */ "Resource deadlock avoided\0"
114 /* 36: 742, 19 */ "File name too long\0"
115 /* 37: 761, 19 */ "No locks available\0"
116 /* 38: 780, 25 */ "Function not implemented\0"
117 /* 39: 805, 20 */ "Directory not empty\0"
118 /* 40: 825, 34 */ "Too many levels of symbolic links\0"
119 /* 41: 859, 1 */ "\0"
120 /* 42: 860, 27 */ "No message of desired type\0"
121 /* 43: 887, 19 */ "Identifier removed\0"
122 /* 44: 906, 28 */ "Channel number out of range\0"
123 /* 45: 934, 25 */ "Level 2 not synchronized\0"
124 /* 46: 959, 15 */ "Level 3 halted\0"
125 /* 47: 974, 14 */ "Level 3 reset\0"
126 /* 48: 988, 25 */ "Link number out of range\0"
127 /* 49: 1013, 29 */ "Protocol driver not attached\0"
128 /* 50: 1042, 27 */ "No CSI structure available\0"
129 /* 51: 1069, 15 */ "Level 2 halted\0"
130 /* 52: 1084, 17 */ "Invalid exchange\0"
131 /* 53: 1101, 27 */ "Invalid request descriptor\0"
132 /* 54: 1128, 14 */ "Exchange full\0"
133 /* 55: 1142, 9 */ "No anode\0"
134 /* 56: 1151, 21 */ "Invalid request code\0"
135 /* 57: 1172, 13 */ "Invalid slot\0"
136 /* 58: 1185, 1 */ "\0"
137 /* 59: 1186, 21 */ "Bad font file format\0"
138 /* 60: 1207, 20 */ "Device not a stream\0"
139 /* 61: 1227, 18 */ "No data available\0"
140 /* 62: 1245, 14 */ "Timer expired\0"
141 /* 63: 1259, 25 */ "Out of streams resources\0"
142 /* 64: 1284, 30 */ "Machine is not on the network\0"
143 /* 65: 1314, 22 */ "Package not installed\0"
144 /* 66: 1336, 17 */ "Object is remote\0"
145 /* 67: 1353, 22 */ "Link has been severed\0"
146 /* 68: 1375, 16 */ "Advertise error\0"
147 /* 69: 1391, 14 */ "Srmount error\0"
148 /* 70: 1405, 28 */ "Communication error on send\0"
149 /* 71: 1433, 15 */ "Protocol error\0"
150 /* 72: 1448, 19 */ "Multihop attempted\0"
151 /* 73: 1467, 19 */ "RFS specific error\0"
152 /* 74: 1486, 12 */ "Bad message\0"
153 /* 75: 1498, 38 */ "Value too large for defined data type\0"
154 /* 76: 1536, 27 */ "Name not unique on network\0"
155 /* 77: 1563, 29 */ "File descriptor in bad state\0"
156 /* 78: 1592, 23 */ "Remote address changed\0"
157 /* 79: 1615, 39 */ "Can not access a needed shared library\0"
158 /* 80: 1654, 37 */ "Accessing a corrupted shared library\0"
159 /* 81: 1691, 32 */ ".lib section in a.out corrupted\0"
160 /* 82: 1723, 48 */ "Attempting to link in too many shared libraries\0"
161 /* 83: 1771, 38 */ "Cannot exec a shared library directly\0"
162 /* 84: 1809, 50 */ "Invalid or incomplete multibyte or wide character\0"
163 /* 85: 1859, 44 */ "Interrupted system call should be restarted\0"
164 /* 86: 1903, 19 */ "Streams pipe error\0"
165 /* 87: 1922, 15 */ "Too many users\0"
166 /* 88: 1937, 31 */ "Socket operation on non-socket\0"
167 /* 89: 1968, 29 */ "Destination address required\0"
168 /* 90: 1997, 17 */ "Message too long\0"
169 /* 91: 2014, 31 */ "Protocol wrong type for socket\0"
170 /* 92: 2045, 23 */ "Protocol not available\0"
171 /* 93: 2068, 23 */ "Protocol not supported\0"
172 /* 94: 2091, 26 */ "Socket type not supported\0"
173 /* 95: 2117, 24 */ "Operation not supported\0"
174 /* 96: 2141, 30 */ "Protocol family not supported\0"
175 /* 97: 2171, 41 */ "Address family not supported by protocol\0"
176 /* 98: 2212, 23 */ "Address already in use\0"
177 /* 99: 2235, 32 */ "Cannot assign requested address\0"
178 /* 100: 2267, 16 */ "Network is down\0"
179 /* 101: 2283, 23 */ "Network is unreachable\0"
180 /* 102: 2306, 36 */ "Network dropped connection on reset\0"
181 /* 103: 2342, 33 */ "Software caused connection abort\0"
182 /* 104: 2375, 25 */ "Connection reset by peer\0"
183 /* 105: 2400, 26 */ "No buffer space available\0"
184 /* 106: 2426, 40 */ "Transport endpoint is already connected\0"
185 /* 107: 2466, 36 */ "Transport endpoint is not connected\0"
186 /* 108: 2502, 46 */ "Cannot send after transport endpoint shutdown\0"
187 /* 109: 2548, 35 */ "Too many references: cannot splice\0"
188 /* 110: 2583, 21 */ "Connection timed out\0"
189 /* 111: 2604, 19 */ "Connection refused\0"
190 /* 112: 2623, 13 */ "Host is down\0"
191 /* 113: 2636, 17 */ "No route to host\0"
192 /* 114: 2653, 30 */ "Operation already in progress\0"
193 /* 115: 2683, 26 */ "Operation now in progress\0"
194 /* 116: 2709, 22 */ "Stale NFS file handle\0"
195 /* 117: 2731, 25 */ "Structure needs cleaning\0"
196 /* 118: 2756, 28 */ "Not a XENIX named type file\0"
197 /* 119: 2784, 30 */ "No XENIX semaphores available\0"
198 /* 120: 2814, 21 */ "Is a named type file\0"
199 /* 121: 2835, 17 */ "Remote I/O error\0"
200 /* 122: 2852, 20 */ "Disk quota exceeded\0"
201 /* 123: 2872, 16 */ "No medium found\0"
202 /* 124: 2888, 18 */ "Wrong medium type"
206 /**********************************************************************/
209 link_warning(_sys_errlist, "sys_nerr and sys_errlist are obsolete and uClibc support for them (in at least some configurations) will probably be unavailable in the near future.")
211 int sys_nerr = _SYS_NERR;
213 const char *const sys_errlist[] = {
214 _string_syserrmsgs + 0,
215 _string_syserrmsgs + 8,
216 _string_syserrmsgs + 32,
217 _string_syserrmsgs + 58,
218 _string_syserrmsgs + 74,
219 _string_syserrmsgs + 98,
220 _string_syserrmsgs + 117,
221 _string_syserrmsgs + 143,
222 _string_syserrmsgs + 166,
223 _string_syserrmsgs + 184,
224 _string_syserrmsgs + 204,
225 _string_syserrmsgs + 223,
226 _string_syserrmsgs + 256,
227 _string_syserrmsgs + 279,
228 _string_syserrmsgs + 297,
229 _string_syserrmsgs + 309,
230 _string_syserrmsgs + 331,
231 _string_syserrmsgs + 355,
232 _string_syserrmsgs + 367,
233 _string_syserrmsgs + 393,
234 _string_syserrmsgs + 408,
235 _string_syserrmsgs + 424,
236 _string_syserrmsgs + 439,
237 _string_syserrmsgs + 456,
238 _string_syserrmsgs + 486,
239 _string_syserrmsgs + 506,
240 _string_syserrmsgs + 537,
241 _string_syserrmsgs + 552,
242 _string_syserrmsgs + 567,
243 _string_syserrmsgs + 591,
244 _string_syserrmsgs + 604,
245 _string_syserrmsgs + 626,
246 _string_syserrmsgs + 641,
247 _string_syserrmsgs + 653,
248 _string_syserrmsgs + 686,
249 _string_syserrmsgs + 716,
250 _string_syserrmsgs + 742,
251 _string_syserrmsgs + 761,
252 _string_syserrmsgs + 780,
253 _string_syserrmsgs + 805,
254 _string_syserrmsgs + 825,
255 /* _string_syserrmsgs + 859, */
256 NULL, /* glibc compatiblity :-( */
257 _string_syserrmsgs + 860,
258 _string_syserrmsgs + 887,
259 _string_syserrmsgs + 906,
260 _string_syserrmsgs + 934,
261 _string_syserrmsgs + 959,
262 _string_syserrmsgs + 974,
263 _string_syserrmsgs + 988,
264 _string_syserrmsgs + 1013,
265 _string_syserrmsgs + 1042,
266 _string_syserrmsgs + 1069,
267 _string_syserrmsgs + 1084,
268 _string_syserrmsgs + 1101,
269 _string_syserrmsgs + 1128,
270 _string_syserrmsgs + 1142,
271 _string_syserrmsgs + 1151,
272 _string_syserrmsgs + 1172,
273 /* _string_syserrmsgs + 1185, */
274 NULL, /* glibc compatiblity :-( */
275 _string_syserrmsgs + 1186,
276 _string_syserrmsgs + 1207,
277 _string_syserrmsgs + 1227,
278 _string_syserrmsgs + 1245,
279 _string_syserrmsgs + 1259,
280 _string_syserrmsgs + 1284,
281 _string_syserrmsgs + 1314,
282 _string_syserrmsgs + 1336,
283 _string_syserrmsgs + 1353,
284 _string_syserrmsgs + 1375,
285 _string_syserrmsgs + 1391,
286 _string_syserrmsgs + 1405,
287 _string_syserrmsgs + 1433,
288 _string_syserrmsgs + 1448,
289 _string_syserrmsgs + 1467,
290 _string_syserrmsgs + 1486,
291 _string_syserrmsgs + 1498,
292 _string_syserrmsgs + 1536,
293 _string_syserrmsgs + 1563,
294 _string_syserrmsgs + 1592,
295 _string_syserrmsgs + 1615,
296 _string_syserrmsgs + 1654,
297 _string_syserrmsgs + 1691,
298 _string_syserrmsgs + 1723,
299 _string_syserrmsgs + 1771,
300 _string_syserrmsgs + 1809,
301 _string_syserrmsgs + 1859,
302 _string_syserrmsgs + 1903,
303 _string_syserrmsgs + 1922,
304 _string_syserrmsgs + 1937,
305 _string_syserrmsgs + 1968,
306 _string_syserrmsgs + 1997,
307 _string_syserrmsgs + 2014,
308 _string_syserrmsgs + 2045,
309 _string_syserrmsgs + 2068,
310 _string_syserrmsgs + 2091,
311 _string_syserrmsgs + 2117,
312 _string_syserrmsgs + 2141,
313 _string_syserrmsgs + 2171,
314 _string_syserrmsgs + 2212,
315 _string_syserrmsgs + 2235,
316 _string_syserrmsgs + 2267,
317 _string_syserrmsgs + 2283,
318 _string_syserrmsgs + 2306,
319 _string_syserrmsgs + 2342,
320 _string_syserrmsgs + 2375,
321 _string_syserrmsgs + 2400,
322 _string_syserrmsgs + 2426,
323 _string_syserrmsgs + 2466,
324 _string_syserrmsgs + 2502,
325 _string_syserrmsgs + 2548,
326 _string_syserrmsgs + 2583,
327 _string_syserrmsgs + 2604,
328 _string_syserrmsgs + 2623,
329 _string_syserrmsgs + 2636,
330 _string_syserrmsgs + 2653,
331 _string_syserrmsgs + 2683,
332 _string_syserrmsgs + 2709,
333 _string_syserrmsgs + 2731,
334 _string_syserrmsgs + 2756,
335 _string_syserrmsgs + 2784,
336 _string_syserrmsgs + 2814,
337 _string_syserrmsgs + 2835,
338 _string_syserrmsgs + 2852,
339 _string_syserrmsgs + 2872,
340 _string_syserrmsgs + 2888,
344 /**********************************************************************/
347 #define Wmemcpy wmemcpy
349 #define Wmemcpy memcpy
354 Wvoid *Wmemcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n)
356 register Wchar *r1 = s1;
357 register const Wchar *r2 = s2;
374 /**********************************************************************/
377 #define Wmemmove wmemmove
379 #define Wmemmove memmove
384 Wvoid *Wmemmove(Wvoid *s1, const Wvoid *s2, size_t n)
387 register Wchar *s = (Wchar *) s1;
388 register const Wchar *p = (const Wchar *) s2;
404 register Wchar *s = (Wchar *) s1;
405 register const Wchar *p = (const Wchar *) s2;
424 /**********************************************************************/
427 #define Wstrcpy wcscpy
429 #define Wstrcpy strcpy
434 Wchar *Wstrcpy(Wchar * __restrict s1, const Wchar * __restrict s2)
436 register Wchar *s = s1;
443 while ( (*s++ = *s2++) != 0 );
450 /**********************************************************************/
453 #define Wstrncpy wcsncpy
455 #define Wstrncpy strncpy
460 Wchar *Wstrncpy(Wchar * __restrict s1, register const Wchar * __restrict s2,
463 register Wchar *s = s1;
467 if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
472 if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
482 /**********************************************************************/
485 #define Wstrcat wcscat
487 #define Wstrcat strcat
492 Wchar *Wstrcat(Wchar * __restrict s1, register const Wchar * __restrict s2)
494 register Wchar *s = s1;
498 while ((*s++ = *s2++) != 0);
504 /**********************************************************************/
507 #define Wstrncat wcsncat
509 #define Wstrncat strncat
514 Wchar *Wstrncat(Wchar * __restrict s1, register const Wchar * __restrict s2,
517 register Wchar *s = s1;
522 while (n-- && ((*s = *s2++) != 0)) ++s;
524 while (n && ((*s = *s2++) != 0)) {
535 /**********************************************************************/
538 #define Wmemcmp wmemcmp
540 #define Wmemcmp memcmp
546 weak_alias(memcmp,bcmp);
549 int Wmemcmp(const Wvoid *s1, const Wvoid *s2, size_t n)
551 register const Wuchar *r1 = (const Wuchar *) s1;
552 register const Wuchar *r2 = (const Wuchar *) s2;
555 while (n && (*r1 == *r2)) {
561 return (n == 0) ? 0 : ((*r1 < *r2) ? -1 : 1);
565 while (n-- && ((r = ((int)(*r1++)) - *r2++) == 0));
572 /**********************************************************************/
575 #define Wstrcmp wcscmp
577 #define Wstrcmp strcmp
583 #warning implement strcoll and remove weak alias (or enable for C locale only)
584 weak_alias(strcmp,strcoll);
587 int Wstrcmp(register const Wchar *s1, register const Wchar *s2)
590 while (*((Wuchar *)s1) == *((Wuchar *)s2)) {
597 return (*((Wuchar *)s1) < *((Wuchar *)s2)) ? -1 : 1;
601 while (((r = ((int)(*((Wuchar *)s1))) - *((Wuchar *)s2++))
608 /**********************************************************************/
610 #error implement strcoll and remove weak_alias!!
613 extern unsigned char *_ctype_collate;
614 int strcoll(register const char *s1, const char *s2)
618 while (!(r = (_ctype_collate[(int)(*s1++)]-_ctype_collate[(int)(*s2++)])));
625 /**********************************************************************/
628 #define Wstrncmp wcsncmp
630 #define Wstrncmp strncmp
635 int Wstrncmp(register const Wchar *s1, register const Wchar *s2, size_t n)
638 while (n && (*((Wuchar *)s1) == *((Wuchar *)s2))) {
646 return (n == 0) ? 0 : ((*((Wuchar *)s1) < *((Wuchar *)s2)) ? -1 : 1);
651 && ((r = ((int)(*((unsigned char *)s1))) - *((unsigned char *)s2++))
660 /**********************************************************************/
662 #error implement strxfrm
663 /* size_t strxfrm(char *dst, const char *src, size_t len); */
665 /**********************************************************************/
668 #define Wmemchr wmemchr
670 #define Wmemchr memchr
675 Wvoid *Wmemchr(const Wvoid *s, Wint c, size_t n)
677 register const Wuchar *r = (const Wuchar *) s;
679 /* bcc can optimize the counter if it thinks it is a pointer... */
680 register const char *np = (const char *) n;
686 if (*r == ((Wuchar)c)) {
687 return (Wvoid *) r; /* silence the warning */
698 /**********************************************************************/
701 #define Wstrchr wcschr
703 #define Wstrchr strchr
709 weak_alias(strchr,index);
712 Wchar *Wstrchr(register const Wchar *s, Wint c)
715 if (*s == ((Wchar)c)) {
716 return (Wchar *) s; /* silence the warning */
724 /**********************************************************************/
727 #define Wstrcspn wcscspn
729 #define Wstrcspn strcspn
734 size_t Wstrcspn(const Wchar *s1, const Wchar *s2)
736 register const Wchar *s;
737 register const Wchar *p;
739 for ( s=s1 ; *s ; s++ ) {
740 for ( p=s2 ; *p ; p++ ) {
741 if (*p == *s) goto done;
749 /**********************************************************************/
752 #define Wstrpbrk wcspbrk
754 #define Wstrpbrk strpbrk
759 Wchar *Wstrpbrk(const Wchar *s1, const Wchar *s2)
761 register const Wchar *s;
762 register const Wchar *p;
764 for ( s=s1 ; *s ; s++ ) {
765 for ( p=s2 ; *p ; p++ ) {
766 if (*p == *s) return (Wchar *) s; /* silence the warning */
772 /**********************************************************************/
775 #define Wstrrchr wcsrchr
777 #define Wstrrchr strrchr
783 weak_alias(strrchr,rindex);
786 Wchar *Wstrrchr(register const Wchar *s, Wint c)
788 register const Wchar *p;
792 if (*s == (Wchar) c) {
797 return (Wchar *) p; /* silence the warning */
801 /**********************************************************************/
804 #define Wstrspn wcsspn
806 #define Wstrspn strspn
811 size_t Wstrspn(const Wchar *s1, const Wchar *s2)
813 register const Wchar *s = s1;
814 register const Wchar *p = s2;
826 /**********************************************************************/
829 #define Wstrstr wcsstr
831 #define Wstrstr strstr
836 /* NOTE: This is the simple-minded O(len(s1) * len(s2)) worst-case approach. */
839 weak_alias(wcsstr,wcswcs);
842 Wchar *Wstrstr(const Wchar *s1, const Wchar *s2)
844 register const Wchar *s = s1;
845 register const Wchar *p = s2;
849 return (Wchar *) s1;;
865 /**********************************************************************/
868 #define Wstrtok_r wcstok
869 #define Wstrspn wcsspn
870 #define Wstrpbrk wcspbrk
872 #define Wstrtok_r strtok_r
873 #define Wstrspn strspn
874 #define Wstrpbrk strpbrk
879 Wchar *Wstrtok_r(Wchar * __restrict s1, const Wchar * __restrict s2,
880 Wchar ** __restrict next_start)
886 if (((s = s1) != NULL) || ((s = *next_start) != NULL)) {
887 if (*(s += Wstrspn(s, s2))) {
888 if ((p = Wstrpbrk(s, s2)) != NULL) {
901 if (s && *(s += Wstrspn(s, s2))) {
902 if (*(p = s + Wstrcspn(s, s2))) {
908 return NULL; /* TODO: set *next_start = NULL for safety? */
913 /**********************************************************************/
914 /* #ifdef L_wcstok */
915 /* #define L_strtok */
916 /* #define Wstrtok wcstok */
917 /* #define Wstrtok_r wcstok_r */
919 /* #define Wstrtok strtok */
920 /* #define Wstrtok_r strtok_r */
924 #define Wstrtok strtok
925 #define Wstrtok_r strtok_r
927 Wchar *Wstrtok(Wchar * __restrict s1, const Wchar * __restrict s2)
929 static Wchar *next_start; /* Initialized to 0 since in bss. */
930 return Wstrtok_r(s1, s2, &next_start);
934 /**********************************************************************/
937 #define Wmemset wmemset
939 #define Wmemset memset
944 Wvoid *Wmemset(Wvoid *s, Wint c, size_t n)
946 register Wuchar *p = (Wuchar *) s;
948 /* bcc can optimize the counter if it thinks it is a pointer... */
949 register const char *np = (const char *) n;
964 /**********************************************************************/
967 #define Wstrlen wcslen
969 #define Wstrlen strlen
974 size_t Wstrlen(const Wchar *s)
976 register const Wchar *p;
978 for (p=s ; *p ; p++);
984 /**********************************************************************/
985 /* ANSI/ISO end here */
986 /**********************************************************************/
992 /* inlined binary search method */
994 #if UINT_MAX == 0xffffU
995 /* nothing to do here -- just trying to avoiding possible problems */
996 #elif UINT_MAX == 0xffffffffU
1002 #error ffs needs rewriting!
1017 return (i) ? (n + ((i+1) & 0x01)) : 0;
1020 /* linear search -- slow, but small */
1023 for (n = 0 ; i ; ++n) {
1032 /**********************************************************************/
1034 #define L_strcasecmp
1035 #define Wstrcasecmp wcscasecmp
1037 #define Wstrcasecmp strcasecmp
1042 int Wstrcasecmp(register const Wchar *s1, register const Wchar *s2)
1045 while ((*s1 == *s2) || (towlower(*s1) == towlower(*s2))) {
1052 return (((Wuchar)towlower(*s1)) < ((Wuchar)towlower(*s2))) ? -1 : 1;
1053 /* TODO -- should wide cmp funcs do wchar or Wuchar compares? */
1057 while ( ((s1 == s2) ||
1058 !(r = ((int)( tolower(*((Wuchar *)s1))))
1059 - tolower(*((Wuchar *)s2))))
1067 /**********************************************************************/
1068 #ifdef L_wcsncasecmp
1069 #define L_strncasecmp
1070 #define Wstrncasecmp wcsncasecmp
1072 #define Wstrncasecmp strncasecmp
1075 #ifdef L_strncasecmp
1077 int Wstrncasecmp(register const Wchar *s1, register const Wchar *s2, size_t n)
1080 while (n && ((*s1 == *s2) || (towlower(*s1) == towlower(*s2)))) {
1090 : ((((Wuchar)towlower(*s1)) < ((Wuchar)towlower(*s2))) ? -1 : 1);
1091 /* TODO -- should wide cmp funcs do wchar or Wuchar compares? */
1097 !(r = ((int)( tolower(*((unsigned char *)s1))))
1098 - tolower(*((unsigned char *)s2))))
1099 && (--n, ++s2, *s1++));
1104 /**********************************************************************/
1107 #define Wstrnlen wcsnlen
1109 #define Wstrnlen strnlen
1114 size_t Wstrnlen(const Wchar *s, size_t max)
1116 register const Wchar *p = s;
1118 /* bcc can optimize the counter if it thinks it is a pointer... */
1119 register const char *maxp = (const char *) max;
1124 while (maxp && *p) {
1133 /**********************************************************************/
1134 /* No wide analog. */
1138 void *memccpy(void * __restrict s1, const void * __restrict s2, int c, size_t n)
1140 register char *r1 = s1;
1141 register const char *r2 = s2;
1143 while (n-- && (((unsigned char)(*r1++ = *r2++)) != ((unsigned char) c)));
1145 return (n == (size_t) -1) ? NULL : r1;
1149 /**********************************************************************/
1152 #define Wstrdup wcsdup
1153 #define Wstrlen wcslen
1154 #define Wstrcpy wcscpy
1156 #define Wstrdup strdup
1157 #define Wstrlen strlen
1158 #define Wstrcpy strcpy
1163 Wchar *Wstrdup(register const Wchar *s1)
1167 if ((s = malloc((Wstrlen(s1) + 1) * sizeof(Wchar))) != NULL) {
1175 /**********************************************************************/
1178 char *strerror(int errnum)
1180 static char buf[_SYS_ERRMSG_MAXLEN];
1182 return (_susv3_strerror_r(errnum, buf, sizeof(buf)) == 0) ? buf : NULL;
1186 /**********************************************************************/
1187 /* SUSv3 functions. */
1188 /**********************************************************************/
1189 #ifdef L__susv3_strerror_r
1191 int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen)
1195 char buf[_SYS_ERRMSG_MAXLEN];
1196 static const char unknown[14] = {
1197 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
1202 if (((unsigned int) errnum) < _SYS_NERR) {
1203 /* Trade time for space. This function should rarely be called
1204 * so rather than keeping an array of pointers for the different
1205 * messages, just run through the buffer until we find the
1206 * correct string. */
1207 for (s = (char *) _string_syserrmsgs, i = errnum ; i ; ++s) {
1212 if (*s) { /* Make sure we have an actual message. */
1218 s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
1219 memcpy(s, unknown, sizeof(unknown));
1222 if (!strerrbuf) { /* SUSv3 */
1232 memcpy(strerrbuf, s, i);
1233 strerrbuf[i-1] = 0; /* In case buf was too small. */
1237 __set_errno(retval);
1244 /**********************************************************************/
1245 /* GNU extension functions. */
1246 /**********************************************************************/
1247 #ifdef L__glibc_strerror_r
1249 weak_alias(_glibc_strerror_r,__strerror_r);
1251 char *_glibc_strerror_r(int errnum, char *strerrbuf, size_t buflen)
1253 _susv3_strerror_r(errnum, strerrbuf, buflen);
1259 /**********************************************************************/
1262 #define Wmempcpy wmempcpy
1264 #define Wmempcpy mempcpy
1270 /* uClibc's old string implementation did this to cater to some app. */
1271 weak_alias(mempcpy,__mempcpy);
1274 Wvoid *Wmempcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n)
1276 register Wchar *r1 = s1;
1277 register const Wchar *r2 = s2;
1294 /**********************************************************************/
1297 void *memrchr(const void *s, int c, size_t n)
1299 register const unsigned char *r;
1301 /* bcc can optimize the counter if it thinks it is a pointer... */
1302 register const char *np = (const char *) n;
1307 r = ((unsigned char *)s) + ((size_t) np);
1310 if (*--r == ((unsigned char)c)) {
1311 return (void *) r; /* silence the warning */
1321 /**********************************************************************/
1324 #define Wstpcpy wcpcpy
1326 #define Wstpcpy stpcpy
1331 Wchar *Wstpcpy(register Wchar * __restrict s1, const Wchar * __restrict s2)
1336 } while (*s1++ != 0);
1338 while ( (*s1++ = *s2++) != 0 );
1345 /**********************************************************************/
1348 #define Wstpncpy wcpncpy
1350 #define Wstpncpy stpncpy
1355 Wchar *Wstpncpy(register Wchar * __restrict s1,
1356 register const Wchar * __restrict s2,
1360 const Wchar *p = s2;
1364 if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
1367 return s1 + (s2 - p);
1370 if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
1374 return s1 + (s2 - p);
1379 /**********************************************************************/
1382 void bzero(void *s, size_t n)
1384 register unsigned char *p = s;
1386 /* bcc can optimize the counter if it thinks it is a pointer... */
1387 register const char *np = (const char *) n;
1400 /**********************************************************************/
1403 void bcopy(const void *s2, void *s1, size_t n)
1410 register const char *p;
1427 register const char *p;
1447 /**********************************************************************/
1450 char *strcasestr(const char *s1, const char *s2)
1452 register const char *s = s1;
1453 register const char *p = s2;
1458 return (char *) s1;;
1461 || (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
1476 || (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
1486 return (*p) ? NULL : (char *) s1;
1491 /**********************************************************************/
1494 char *strndup(register const char *s1, size_t n)
1498 n = strnlen(s1,n); /* Avoid problems if s1 not nul-terminated. */
1500 if ((s = malloc(n + 1)) != NULL) {
1509 /**********************************************************************/
1512 char *strsep(char ** __restrict s1, const char * __restrict s2)
1514 register char *s = *s1;
1519 if (s && *s && (p = strpbrk(s, s2))) {
1523 if (s && *s && *(p = s + strcspn(s, s2))) {
1534 /**********************************************************************/
1537 #define Wstrchrnul wcschrnul
1539 #define Wstrchrnul strchrnul
1544 Wchar *Wstrchrnul(register const Wchar *s, Wint c)
1547 while (*++s && (*s != ((Wchar)c)));
1552 /**********************************************************************/
1555 void *rawmemchr(const void *s, int c)
1557 register const unsigned char *r = s;
1559 while (*r != ((unsigned char)c)) ++r;
1561 return (void *) r; /* silence the warning */
1565 /**********************************************************************/
1568 char *basename(const char *path)
1570 register const char *s;
1571 register const char *p;
1585 /**********************************************************************/
1586 #ifdef L___xpg_basename
1588 char *__xpg_basename(register char *path)
1590 static const char null_or_empty[] = ".";
1592 register char *last;
1594 first = (char *) null_or_empty;
1596 if (path && *path) {
1601 if ((*path != '/') && (path > ++last)) {
1602 last = first = path;
1606 if (*first == '/') {
1616 /**********************************************************************/
1619 char *dirname(char *path)
1621 static const char null_or_empty_or_noslash[] = ".";
1623 register char *last;
1631 while (*s && (*s != '/')) ++s;
1633 while (*s == '/') ++s;
1643 if ((*++last == '/') && (last[1] == 0)) {
1651 return (char *) null_or_empty_or_noslash;
1655 /**********************************************************************/
1658 /* OpenBSD function:
1659 * Append at most n-1-strlen(dst) chars from src to dst and nul-terminate dst.
1660 * Returns strlen(src) + strlen({original} dst), so truncation occurred if the
1661 * return val is >= n.
1662 * Note: If dst doesn't contain a nul in the first n chars, strlen(dst) is
1665 size_t strlcat(register char *__restrict dst,
1666 register const char *__restrict src,
1686 while ((*dst = *src) != 0) {
1697 /**********************************************************************/
1700 /* OpenBSD function:
1701 * Copy at most n-1 chars from src to dst and nul-terminate dst.
1702 * Returns strlen(src), so truncation occurred if the return value is >= n. */
1704 size_t strlcpy(register char *__restrict dst,
1705 register const char *__restrict src,
1708 const char *src0 = src;
1717 while ((*dst = *src) != 0) {
1729 /**********************************************************************/