Zycore  1.5.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_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 
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 
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 */
#define ZYAN_UNUSED(x)
Definition: Defines.h:342
va_list ZyanVAList
Definition: LibC.h:63
FILE ZyanFile
Definition: LibC.h:89