Zycore  1.2.0.0
LibC.h
Go to the documentation of this file.
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 
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 
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 
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_MALLOC malloc
103 #define ZYAN_REALLOC realloc
104 
105 /* ---------------------------------------------------------------------------------------------- */
106 /* string.h */
107 /* ---------------------------------------------------------------------------------------------- */
108 
109 #include <string.h>
110 #define ZYAN_MEMCHR memchr
111 #define ZYAN_MEMCMP memcmp
112 #define ZYAN_MEMCPY memcpy
113 #define ZYAN_MEMMOVE memmove
114 #define ZYAN_MEMSET memset
115 #define ZYAN_STRCAT strcat
116 #define ZYAN_STRCHR strchr
117 #define ZYAN_STRCMP strcmp
118 #define ZYAN_STRCOLL strcoll
119 #define ZYAN_STRCPY strcpy
120 #define ZYAN_STRCSPN strcspn
121 #define ZYAN_STRLEN strlen
122 #define ZYAN_STRNCAT strncat
123 #define ZYAN_STRNCMP strncmp
124 #define ZYAN_STRNCPY strncpy
125 #define ZYAN_STRPBRK strpbrk
126 #define ZYAN_STRRCHR strrchr
127 #define ZYAN_STRSPN strspn
128 #define ZYAN_STRSTR strstr
129 #define ZYAN_STRTOK strtok
130 #define ZYAN_STRXFRM strxfrm
131 
132 /* ---------------------------------------------------------------------------------------------- */
133 
134 #else // if ZYAN_NO_LIBC
135 
136 /* ============================================================================================== */
137 /* No LibC available, use our own functions */
138 /* ============================================================================================== */
139 
140 #include <Zycore/Defines.h>
141 #include <Zycore/Types.h>
142 
143 /*
144  * These implementations are by no means optimized and will be outperformed by pretty much any
145  * libc implementation out there. We do not aim towards providing competetive implementations here,
146  * but towards providing a last resort fallback for environments without a working libc.
147  */
148 
149 /* ---------------------------------------------------------------------------------------------- */
150 /* stdarg.h */
151 /* ---------------------------------------------------------------------------------------------- */
152 
153 #if defined(ZYAN_MSVC) || defined(ZYAN_ICC)
154 
158 typedef char* ZyanVAList;
159 
160 # define ZYAN_VA_START __crt_va_start
161 # define ZYAN_VA_ARG __crt_va_arg
162 # define ZYAN_VA_END __crt_va_end
163 # define ZYAN_VA_COPY(destination, source) ((destination) = (source))
164 
165 #elif defined(ZYAN_GNUC)
166 
170 typedef __builtin_va_list ZyanVAList;
171 
172 # define ZYAN_VA_START(v, l) __builtin_va_start(v, l)
173 # define ZYAN_VA_END(v) __builtin_va_end(v)
174 # define ZYAN_VA_ARG(v, l) __builtin_va_arg(v, l)
175 # define ZYAN_VA_COPY(d, s) __builtin_va_copy(d, s)
176 
177 #else
178 # error "Unsupported compiler for no-libc mode."
179 #endif
180 
181 /* ---------------------------------------------------------------------------------------------- */
182 /* stdio.h */
183 /* ---------------------------------------------------------------------------------------------- */
184 
185 // ZYAN_INLINE int ZYAN_VSNPRINTF (char* const buffer, ZyanUSize const count,
186 // char const* const format, ZyanVAList args)
187 // {
188 // // We cant provide a fallback implementation for this function
189 // ZYAN_UNUSED(buffer);
190 // ZYAN_UNUSED(count);
191 // ZYAN_UNUSED(format);
192 // ZYAN_UNUSED(args);
193 // return ZYAN_NULL;
194 // }
195 
196 /* ---------------------------------------------------------------------------------------------- */
197 /* stdlib.h */
198 /* ---------------------------------------------------------------------------------------------- */
199 
200 // ZYAN_INLINE void* ZYAN_CALLOC(ZyanUSize nitems, ZyanUSize size)
201 // {
202 // // We cant provide a fallback implementation for this function
203 // ZYAN_UNUSED(nitems);
204 // ZYAN_UNUSED(size);
205 // return ZYAN_NULL;
206 // }
207 //
208 // ZYAN_INLINE void ZYAN_FREE(void *p)
209 // {
210 // // We cant provide a fallback implementation for this function
211 // ZYAN_UNUSED(p);
212 // }
213 //
214 // ZYAN_INLINE void* ZYAN_MALLOC(ZyanUSize n)
215 // {
216 // // We cant provide a fallback implementation for this function
217 // ZYAN_UNUSED(n);
218 // return ZYAN_NULL;
219 // }
220 //
221 // ZYAN_INLINE void* ZYAN_REALLOC(void* p, ZyanUSize n)
222 // {
223 // // We cant provide a fallback implementation for this function
224 // ZYAN_UNUSED(p);
225 // ZYAN_UNUSED(n);
226 // return ZYAN_NULL;
227 // }
228 
229 /* ---------------------------------------------------------------------------------------------- */
230 /* string.h */
231 /* ---------------------------------------------------------------------------------------------- */
232 
233 ZYAN_INLINE void* ZYAN_MEMCHR(const void* str, int c, ZyanUSize n)
234 {
235  const ZyanU8* p = (ZyanU8*)str;
236  while (n--)
237  {
238  if (*p != (ZyanU8)c)
239  {
240  p++;
241  } else
242  {
243  return (void*)p;
244  }
245  }
246  return 0;
247 }
248 
249 ZYAN_INLINE int ZYAN_MEMCMP(const void* s1, const void* s2, ZyanUSize n)
250 {
251  const ZyanU8* p1 = s1, *p2 = s2;
252  while (n--)
253  {
254  if (*p1 != *p2)
255  {
256  return *p1 - *p2;
257  }
258  p1++, p2++;
259  }
260  return 0;
261 }
262 
263 ZYAN_INLINE void* ZYAN_MEMCPY(void* dst, const void* src, ZyanUSize n)
264 {
265  volatile ZyanU8* dp = dst;
266  const ZyanU8* sp = src;
267  while (n--)
268  {
269  *dp++ = *sp++;
270  }
271  return dst;
272 }
273 
274 ZYAN_INLINE void* ZYAN_MEMMOVE(void* dst, const void* src, ZyanUSize n)
275 {
276  volatile ZyanU8* pd = dst;
277  const ZyanU8* ps = src;
278  if (ps < pd)
279  {
280  for (pd += n, ps += n; n--;)
281  {
282  *--pd = *--ps;
283  }
284  } else
285  {
286  while (n--)
287  {
288  *pd++ = *ps++;
289  }
290  }
291  return dst;
292 }
293 
294 ZYAN_INLINE void* ZYAN_MEMSET(void* dst, int val, ZyanUSize n)
295 {
296  volatile ZyanU8* p = dst;
297  while (n--)
298  {
299  *p++ = (unsigned char)val;
300  }
301  return dst;
302 }
303 
304 ZYAN_INLINE char* ZYAN_STRCAT(char* dest, const char* src)
305 {
306  char* ret = dest;
307  while (*dest)
308  {
309  dest++;
310  }
311  while ((*dest++ = *src++));
312  return ret;
313 }
314 
315 ZYAN_INLINE char* ZYAN_STRCHR(const char* s, int c)
316 {
317  while (*s != (char)c)
318  {
319  if (!*s++)
320  {
321  return 0;
322  }
323  }
324  return (char*)s;
325 }
326 
327 ZYAN_INLINE int ZYAN_STRCMP(const char* s1, const char* s2)
328 {
329  while (*s1 && (*s1 == *s2))
330  {
331  s1++, s2++;
332  }
333  return *(const ZyanU8*)s1 - *(const ZyanU8*)s2;
334 }
335 
336 ZYAN_INLINE int ZYAN_STRCOLL(const char *s1, const char *s2)
337 {
338  // TODO: Implement
339 
340  ZYAN_UNUSED(s1);
341  ZYAN_UNUSED(s2);
342 
343  return 0;
344 }
345 
346 ZYAN_INLINE char* ZYAN_STRCPY(char* dest, const char* src)
347 {
348  char* ret = dest;
349  while ((*dest++ = *src++));
350  return ret;
351 }
352 
353 ZYAN_INLINE ZyanUSize ZYAN_STRCSPN(const char *s1, const char *s2)
354 {
355  ZyanUSize ret = 0;
356  while (*s1)
357  {
358  if (ZYAN_STRCHR(s2, *s1))
359  {
360  return ret;
361  }
362  s1++, ret++;
363  }
364  return ret;
365 }
366 
367 ZYAN_INLINE ZyanUSize ZYAN_STRLEN(const char* str)
368 {
369  const char* p = str;
370  while (*str)
371  {
372  ++str;
373  }
374  return str - p;
375 }
376 
377 ZYAN_INLINE char* ZYAN_STRNCAT(char* dest, const char* src, ZyanUSize n)
378 {
379  char* ret = dest;
380  while (*dest)
381  {
382  dest++;
383  }
384  while (n--)
385  {
386  if (!(*dest++ = *src++))
387  {
388  return ret;
389  }
390  }
391  *dest = 0;
392  return ret;
393 }
394 
395 ZYAN_INLINE int ZYAN_STRNCMP(const char* s1, const char* s2, ZyanUSize n)
396 {
397  while (n--)
398  {
399  if (*s1++ != *s2++)
400  {
401  return *(unsigned char*)(s1 - 1) - *(unsigned char*)(s2 - 1);
402  }
403  }
404  return 0;
405 }
406 
407 ZYAN_INLINE char* ZYAN_STRNCPY(char* dest, const char* src, ZyanUSize n)
408 {
409  char* ret = dest;
410  do
411  {
412  if (!n--)
413  {
414  return ret;
415  }
416  } while ((*dest++ = *src++));
417  while (n--)
418  {
419  *dest++ = 0;
420  }
421  return ret;
422 }
423 
424 ZYAN_INLINE char* ZYAN_STRPBRK(const char* s1, const char* s2)
425 {
426  while (*s1)
427  {
428  if(ZYAN_STRCHR(s2, *s1++))
429  {
430  return (char*)--s1;
431  }
432  }
433  return 0;
434 }
435 
436 ZYAN_INLINE char* ZYAN_STRRCHR(const char* s, int c)
437 {
438  char* ret = 0;
439  do
440  {
441  if (*s == (char)c)
442  {
443  ret = (char*)s;
444  }
445  } while (*s++);
446  return ret;
447 }
448 
449 ZYAN_INLINE ZyanUSize ZYAN_STRSPN(const char* s1, const char* s2)
450 {
451  ZyanUSize ret = 0;
452  while (*s1 && ZYAN_STRCHR(s2, *s1++))
453  {
454  ret++;
455  }
456  return ret;
457 }
458 
459 ZYAN_INLINE char* ZYAN_STRSTR(const char* s1, const char* s2)
460 {
461  const ZyanUSize n = ZYAN_STRLEN(s2);
462  while (*s1)
463  {
464  if (!ZYAN_MEMCMP(s1++, s2, n))
465  {
466  return (char*)(s1 - 1);
467  }
468  }
469  return 0;
470 }
471 
472 ZYAN_INLINE char* ZYAN_STRTOK(char* str, const char* delim)
473 {
474  static char* p = 0;
475  if (str)
476  {
477  p = str;
478  } else
479  if (!p)
480  {
481  return 0;
482  }
483  str = p + ZYAN_STRSPN(p, delim);
484  p = str + ZYAN_STRCSPN(str, delim);
485  if (p == str)
486  {
487  return p = 0;
488  }
489  p = *p ? *p = 0, p + 1 : 0;
490  return str;
491 }
492 
493 ZYAN_INLINE ZyanUSize ZYAN_STRXFRM(char* dest, const char* src, ZyanUSize n)
494 {
495  const ZyanUSize n2 = ZYAN_STRLEN(src);
496  if (n > n2)
497  {
498  ZYAN_STRCPY(dest, src);
499  }
500  return n2;
501 }
502 
503 /* ---------------------------------------------------------------------------------------------- */
504 
505 #endif
506 
507 #endif
508 
509 /* ============================================================================================== */
510 
511 #endif /* ZYCORE_LIBC_H */
#define ZYAN_UNUSED(x)
Definition: Defines.h:331
va_list ZyanVAList
Definition: LibC.h:63
FILE ZyanFile
Definition: LibC.h:89