xref: /haiku/headers/libs/zydis/Zycore/LibC.h (revision 909af08f4328301fbdef1ffb41f566c3b5bec0c7)
1 /***************************************************************************************************
2 
3   Zyan Core Library (Zycore-C)
4 
5   Original Author : Florian Bernd, Joel Hoener
6 
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24 
25 ***************************************************************************************************/
26 
27 /**
28  * @file
29  * Provides a simple LibC abstraction and fallback routines.
30  */
31 
32 #ifndef ZYCORE_LIBC_H
33 #define ZYCORE_LIBC_H
34 
35 #ifndef ZYAN_CUSTOM_LIBC
36 
37 // Include a custom LibC header and define `ZYAN_CUSTOM_LIBC` to provide your own LibC
38 // replacement functions
39 
40 #ifndef ZYAN_NO_LIBC
41 
42 /* ============================================================================================== */
43 /* LibC is available                                                                              */
44 /* ============================================================================================== */
45 
46 /* ---------------------------------------------------------------------------------------------- */
47 /* errno.h                                                                                        */
48 /* ---------------------------------------------------------------------------------------------- */
49 
50 #include <errno.h>
51 
52 #define ZYAN_ERRNO  errno
53 
54 /* ---------------------------------------------------------------------------------------------- */
55 /* stdarg.h                                                                                       */
56 /* ---------------------------------------------------------------------------------------------- */
57 
58 #include <stdarg.h>
59 
60 /**
61  * Defines the `ZyanVAList` datatype.
62  */
63 typedef va_list ZyanVAList;
64 
65 #define ZYAN_VA_START               va_start
66 #define ZYAN_VA_ARG                 va_arg
67 #define ZYAN_VA_END                 va_end
68 #define ZYAN_VA_COPY(dest, source)  va_copy((dest), (source))
69 
70 /* ---------------------------------------------------------------------------------------------- */
71 /* stdio.h                                                                                        */
72 /* ---------------------------------------------------------------------------------------------- */
73 
74 #include <stdio.h>
75 
76 #define ZYAN_FPUTS      fputs
77 #define ZYAN_FPUTC      fputc
78 #define ZYAN_FPRINTF    fprintf
79 #define ZYAN_PRINTF     printf
80 #define ZYAN_PUTC       putc
81 #define ZYAN_PUTS       puts
82 #define ZYAN_SCANF      scanf
83 #define ZYAN_SSCANF     sscanf
84 #define ZYAN_VSNPRINTF  vsnprintf
85 
86 /**
87  * Defines the `ZyanFile` datatype.
88  */
89 typedef FILE ZyanFile;
90 
91 #define ZYAN_STDIN      stdin
92 #define ZYAN_STDOUT     stdout
93 #define ZYAN_STDERR     stderr
94 
95 /* ---------------------------------------------------------------------------------------------- */
96 /* stdlib.h                                                                                       */
97 /* ---------------------------------------------------------------------------------------------- */
98 
99 #include <stdlib.h>
100 #define ZYAN_CALLOC     calloc
101 #define ZYAN_FREE       free
102 #define ZYAN_GETENV     getenv
103 #define ZYAN_MALLOC     malloc
104 #define ZYAN_REALLOC    realloc
105 
106 /* ---------------------------------------------------------------------------------------------- */
107 /* string.h                                                                                       */
108 /* ---------------------------------------------------------------------------------------------- */
109 
110 #include <string.h>
111 #define ZYAN_MEMCHR     memchr
112 #define ZYAN_MEMCMP     memcmp
113 #define ZYAN_MEMCPY     memcpy
114 #define ZYAN_MEMMOVE    memmove
115 #define ZYAN_MEMSET     memset
116 #define ZYAN_STRCAT     strcat
117 #define ZYAN_STRCHR     strchr
118 #define ZYAN_STRCMP     strcmp
119 #define ZYAN_STRCOLL    strcoll
120 #define ZYAN_STRCPY     strcpy
121 #define ZYAN_STRCSPN    strcspn
122 #define ZYAN_STRLEN     strlen
123 #define ZYAN_STRNCAT    strncat
124 #define ZYAN_STRNCMP    strncmp
125 #define ZYAN_STRNCPY    strncpy
126 #define ZYAN_STRPBRK    strpbrk
127 #define ZYAN_STRRCHR    strrchr
128 #define ZYAN_STRSPN     strspn
129 #define ZYAN_STRSTR     strstr
130 #define ZYAN_STRTOK     strtok
131 #define ZYAN_STRXFRM    strxfrm
132 
133 /* ---------------------------------------------------------------------------------------------- */
134 
135 #else  // if ZYAN_NO_LIBC
136 
137 /* ============================================================================================== */
138 /* No LibC available, use our own functions                                                       */
139 /* ============================================================================================== */
140 
141 #include <Zycore/Defines.h>
142 #include <Zycore/Types.h>
143 
144 /*
145  * These implementations are by no means optimized and will be outperformed by pretty much any
146  * libc implementation out there. We do not aim towards providing competetive implementations here,
147  * but towards providing a last resort fallback for environments without a working libc.
148  */
149 
150 /* ---------------------------------------------------------------------------------------------- */
151 /* stdarg.h                                                                                       */
152 /* ---------------------------------------------------------------------------------------------- */
153 
154 #if defined(ZYAN_MSVC) || defined(ZYAN_ICC)
155 
156 /**
157  * Defines the `ZyanVAList` datatype.
158  */
159 typedef char* ZyanVAList;
160 
161 #   define ZYAN_VA_START __crt_va_start
162 #   define ZYAN_VA_ARG   __crt_va_arg
163 #   define ZYAN_VA_END   __crt_va_end
164 #   define ZYAN_VA_COPY(destination, source) ((destination) = (source))
165 
166 #elif defined(ZYAN_GNUC)
167 
168 /**
169  * Defines the `ZyanVAList` datatype.
170  */
171 typedef __builtin_va_list  ZyanVAList;
172 
173 #   define ZYAN_VA_START(v, l)  __builtin_va_start(v, l)
174 #   define ZYAN_VA_END(v)       __builtin_va_end(v)
175 #   define ZYAN_VA_ARG(v, l)    __builtin_va_arg(v, l)
176 #   define ZYAN_VA_COPY(d, s)   __builtin_va_copy(d, s)
177 
178 #else
179 #   error "Unsupported compiler for no-libc mode."
180 #endif
181 
182 /* ---------------------------------------------------------------------------------------------- */
183 /* stdio.h                                                                                        */
184 /* ---------------------------------------------------------------------------------------------- */
185 
186 // ZYAN_INLINE int ZYAN_VSNPRINTF (char* const buffer, ZyanUSize const count,
187 //     char const* const format, ZyanVAList args)
188 // {
189 //      // We cant provide a fallback implementation for this function
190 //     ZYAN_UNUSED(buffer);
191 //     ZYAN_UNUSED(count);
192 //     ZYAN_UNUSED(format);
193 //     ZYAN_UNUSED(args);
194 //     return ZYAN_NULL;
195 // }
196 
197 /* ---------------------------------------------------------------------------------------------- */
198 /* stdlib.h                                                                                       */
199 /* ---------------------------------------------------------------------------------------------- */
200 
201 // ZYAN_INLINE void* ZYAN_CALLOC(ZyanUSize nitems, ZyanUSize size)
202 // {
203 //      // We cant provide a fallback implementation for this function
204 //     ZYAN_UNUSED(nitems);
205 //     ZYAN_UNUSED(size);
206 //     return ZYAN_NULL;
207 // }
208 //
209 // ZYAN_INLINE void ZYAN_FREE(void *p)
210 // {
211 //      // We cant provide a fallback implementation for this function
212 //     ZYAN_UNUSED(p);
213 // }
214 //
215 // ZYAN_INLINE void* ZYAN_MALLOC(ZyanUSize n)
216 // {
217 //     // We cant provide a fallback implementation for this function
218 //     ZYAN_UNUSED(n);
219 //     return ZYAN_NULL;
220 // }
221 //
222 // ZYAN_INLINE void* ZYAN_REALLOC(void* p, ZyanUSize n)
223 // {
224 //      // We cant provide a fallback implementation for this function
225 //     ZYAN_UNUSED(p);
226 //     ZYAN_UNUSED(n);
227 //     return ZYAN_NULL;
228 // }
229 
230 /* ---------------------------------------------------------------------------------------------- */
231 /* string.h                                                                                       */
232 /* ---------------------------------------------------------------------------------------------- */
233 
234 ZYAN_INLINE void* ZYAN_MEMCHR(const void* str, int c, ZyanUSize n)
235 {
236     const ZyanU8* p = (ZyanU8*)str;
237     while (n--)
238     {
239         if (*p != (ZyanU8)c)
240         {
241             p++;
242         } else
243         {
244             return (void*)p;
245         }
246     }
247     return 0;
248 }
249 
250 ZYAN_INLINE int ZYAN_MEMCMP(const void* s1, const void* s2, ZyanUSize n)
251 {
252     const ZyanU8* p1 = s1, *p2 = s2;
253     while (n--)
254     {
255         if (*p1 != *p2)
256         {
257             return *p1 - *p2;
258         }
259         p1++, p2++;
260     }
261     return 0;
262 }
263 
264 ZYAN_INLINE void* ZYAN_MEMCPY(void* dst, const void* src, ZyanUSize n)
265 {
266     volatile ZyanU8* dp = dst;
267     const ZyanU8* sp = src;
268     while (n--)
269     {
270         *dp++ = *sp++;
271     }
272     return dst;
273 }
274 
275 ZYAN_INLINE void* ZYAN_MEMMOVE(void* dst, const void* src, ZyanUSize n)
276 {
277     volatile ZyanU8* pd = dst;
278     const ZyanU8* ps = src;
279     if (ps < pd)
280     {
281         for (pd += n, ps += n; n--;)
282         {
283             *--pd = *--ps;
284         }
285     } else
286     {
287         while (n--)
288         {
289             *pd++ = *ps++;
290         }
291     }
292     return dst;
293 }
294 
295 ZYAN_INLINE void* ZYAN_MEMSET(void* dst, int val, ZyanUSize n)
296 {
297     volatile ZyanU8* p = dst;
298     while (n--)
299     {
300         *p++ = (unsigned char)val;
301     }
302     return dst;
303 }
304 
305 ZYAN_INLINE char* ZYAN_STRCAT(char* dest, const char* src)
306 {
307     char* ret = dest;
308     while (*dest)
309     {
310         dest++;
311     }
312     while ((*dest++ = *src++));
313     return ret;
314 }
315 
316 ZYAN_INLINE char* ZYAN_STRCHR(const char* s, int c)
317 {
318     while (*s != (char)c)
319     {
320         if (!*s++)
321         {
322             return 0;
323         }
324     }
325     return (char*)s;
326 }
327 
328 ZYAN_INLINE int ZYAN_STRCMP(const char* s1, const char* s2)
329 {
330     while (*s1 && (*s1 == *s2))
331     {
332         s1++, s2++;
333     }
334     return *(const ZyanU8*)s1 - *(const ZyanU8*)s2;
335 }
336 
337 ZYAN_INLINE int ZYAN_STRCOLL(const char *s1, const char *s2)
338 {
339     // TODO: Implement
340 
341     ZYAN_UNUSED(s1);
342     ZYAN_UNUSED(s2);
343 
344     return 0;
345 }
346 
347 ZYAN_INLINE char* ZYAN_STRCPY(char* dest, const char* src)
348 {
349     char* ret = dest;
350     while ((*dest++ = *src++));
351     return ret;
352 }
353 
354 ZYAN_INLINE ZyanUSize ZYAN_STRCSPN(const char *s1, const char *s2)
355 {
356     ZyanUSize ret = 0;
357     while (*s1)
358     {
359         if (ZYAN_STRCHR(s2, *s1))
360         {
361             return ret;
362         }
363         s1++, ret++;
364     }
365     return ret;
366 }
367 
368 ZYAN_INLINE ZyanUSize ZYAN_STRLEN(const char* str)
369 {
370     const char* p = str;
371     while (*str)
372     {
373         ++str;
374     }
375     return str - p;
376 }
377 
378 ZYAN_INLINE char* ZYAN_STRNCAT(char* dest, const char* src, ZyanUSize n)
379 {
380     char* ret = dest;
381     while (*dest)
382     {
383         dest++;
384     }
385     while (n--)
386     {
387         if (!(*dest++ = *src++))
388         {
389             return ret;
390         }
391     }
392     *dest = 0;
393     return ret;
394 }
395 
396 ZYAN_INLINE int ZYAN_STRNCMP(const char* s1, const char* s2, ZyanUSize n)
397 {
398     while (n--)
399     {
400         if (*s1++ != *s2++)
401         {
402             return *(unsigned char*)(s1 - 1) - *(unsigned char*)(s2 - 1);
403         }
404     }
405     return 0;
406 }
407 
408 ZYAN_INLINE char* ZYAN_STRNCPY(char* dest, const char* src, ZyanUSize n)
409 {
410     char* ret = dest;
411     do
412     {
413         if (!n--)
414         {
415             return ret;
416         }
417     } while ((*dest++ = *src++));
418     while (n--)
419     {
420         *dest++ = 0;
421     }
422     return ret;
423 }
424 
425 ZYAN_INLINE char* ZYAN_STRPBRK(const char* s1, const char* s2)
426 {
427     while (*s1)
428     {
429         if(ZYAN_STRCHR(s2, *s1++))
430         {
431             return (char*)--s1;
432         }
433     }
434     return 0;
435 }
436 
437 ZYAN_INLINE char* ZYAN_STRRCHR(const char* s, int c)
438 {
439     char* ret = 0;
440     do
441     {
442         if (*s == (char)c)
443         {
444             ret = (char*)s;
445         }
446     } while (*s++);
447     return ret;
448 }
449 
450 ZYAN_INLINE ZyanUSize ZYAN_STRSPN(const char* s1, const char* s2)
451 {
452     ZyanUSize ret = 0;
453     while (*s1 && ZYAN_STRCHR(s2, *s1++))
454     {
455         ret++;
456     }
457     return ret;
458 }
459 
460 ZYAN_INLINE char* ZYAN_STRSTR(const char* s1, const char* s2)
461 {
462     const ZyanUSize n = ZYAN_STRLEN(s2);
463     while (*s1)
464     {
465         if (!ZYAN_MEMCMP(s1++, s2, n))
466         {
467             return (char*)(s1 - 1);
468         }
469     }
470     return 0;
471 }
472 
473 ZYAN_INLINE char* ZYAN_STRTOK(char* str, const char* delim)
474 {
475     static char* p = 0;
476     if (str)
477     {
478         p = str;
479     } else
480     if (!p)
481     {
482         return 0;
483     }
484     str = p + ZYAN_STRSPN(p, delim);
485     p = str + ZYAN_STRCSPN(str, delim);
486     if (p == str)
487     {
488         return p = 0;
489     }
490     p = *p ? *p = 0, p + 1 : 0;
491     return str;
492 }
493 
494 ZYAN_INLINE ZyanUSize ZYAN_STRXFRM(char* dest, const char* src, ZyanUSize n)
495 {
496     const ZyanUSize n2 = ZYAN_STRLEN(src);
497     if (n > n2)
498     {
499         ZYAN_STRCPY(dest, src);
500     }
501     return n2;
502 }
503 
504 /* ---------------------------------------------------------------------------------------------- */
505 
506 #endif
507 
508 #endif
509 
510 /* ============================================================================================== */
511 
512 #endif /* ZYCORE_LIBC_H */
513