duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

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 */