LibC.h (13767B)
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_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 155 /** 156 * Defines the `ZyanVAList` datatype. 157 */ 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 167 /** 168 * Defines the `ZyanVAList` datatype. 169 */ 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 */