Skip to content
/ stdr Public

stdr - or "stutter" (C Standard Library Replacement) - is a (fairly) modular subset replacement for a variety of C standard library functions

License

Notifications You must be signed in to change notification settings

rewtnull/stdr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 

Repository files navigation

stdr

-- ABOUT --

stdr - or "stutter" (C Standard Library Replacement) - is a (fairly) modular subset replacement for a variety of
C standard library functions. If you aim at using that elusive -nostdlib flag in gcc, and/or want
to size optimize your executables, these could be for you!


The goal of this project is to allow for drop-in replacements for various C Standard
Library functions without the need to include a complete library; you can lift out and use only the
functions you require for your project.

-- PLATFORM DEPENDENCY --

There are a collection of low level functions included that are win32 api specific. These are,
however, structured in such a way that they can be ported to other platforms without having to
rewrite functions they depend on, or that depend on them.


The platform specific functions make api calls directly from kernel32.dll. stdr uses a
bootstrapping mechanism that allows for this, so there is no need to #include anything. It
should also be failry easy to include code for any other dll you wish to use functions from.


I have chosen to typedef various data types so to not create conflicts with other possible
definitions. Any platform agnostic typedefs use a stdr_ prefix (STDR_ for macro definitions).
As for platform dependent typedefs and macros, (only windows for now), I have chosen win_,
and WIN_ prefixes respectively. This should make it  easy to identify any platform dependent
functions and definitions.


I am avoiding internal/cross dependencies when ever possible, but sometimes these are a
necessity. I have left comments for the function prototypes that will give you an idea on
what internal dependencies functions may have.

-- TARGETED HEADERS --

The targeted headers are:


ctype.h, math.h, stdio.h, stddef.h, stdlib.h, string.h, unistd.h, wchar.h

-- HELPERS --

The following type conversion helper functions are included:


void  stdr_i2str(int value, char* buffer);                                       int to string
void  stdr_f2str(float value, char* buffer, int precision);                      float to string
void  stdr_l2hex(unsigned long value, char* buffer);                             long to hex
void  stdr_l2str(long value, char* buffer);                                      long to string
void  stdr_ptr2str(void* ptr, char* buffer);                                     memory pointer to string
void  stdr_sz_t2hex(stdr_size_t value, char* hex, stdr_size_t hex_size);         size_t to hex
void  stdr_sz_t2str(stdr_size_t value, char* buffer);                            size_t to string
char* stdr_str2c(const char* str, int c);                                        string to char
long  stdr_str2l(const char* str, char** endptr, int base);                      string to long
void  stdr_ui2hex(unsigned int value, char* buffer);                             uint to hex
void  stdr_ui2str(stdr_size_t value, char* buffer);                              uint to string
void  stdr_ul2hex(unsigned long value, char* buffer);                            ulong to hex
void  stdr_ul2str(unsigned long value, char* buffer);                            ulong to string
void  stdr_uc2str(unsigned char value, char* buffer);                            uchar to string
void  stdr_us2str(unsigned short value, char* buffer);                           ushort to string


There is also this:


void stdr_str_out(const char* message);     - outputs string to console using
                                              the kernel32.dll WriteConsoleA()

-- HEADER --

The following macros are defined and replace the ones of the standard library:


    STDR_NULL                                                          replaces NULL
    stdr_offsetof()                                                    replaces offsetof()


An (incomplete) implemetation of variadic definitions:


    stdr_va_list                                                       replaces va_list
    stdr_va_start                                                      replaces va_start
    stdr_va_arg                                                        replaces va_arg
    stdr_va_end                                                        replaces va_end


For more information, browse stdr.h

-- WIN32 API LOW-LEVEL FUNCTIONS --

These low-level functions are availble for use. Check the header for compatible data types:


    __GetModuleHandleA()
    __GetProcAddress()
    __GetStdHandle()
    __SetFilePointer()
    __FlushFileBuffers()
    __CreateFileA()
    __ReadFile()
    __WriteFile()
    __GetFileSize()
    __CloseHandle()
    __VirtualAlloc()
    __LocalFree()
    __FormatMessageA()
    __WriteConsoleA()
    __MAKELANGID()
    __GetLastError()
    __ExitProcess()

--CODE--

The included drop-in replacement functions:


ctype.h:
-----------------------------------------------------------------------------------------------------------


    int stdr_isdigit(int c);
    int stdr_isspace(int c);
    int stdr_isxdigit(int c);


math.h:
-----------------------------------------------------------------------------------------------------------


    float stdr_asin(float x);
    float stdr_atan2(float y, float x);
    float stdr_cos(float x);
    float stdr_fabs(float x);
    float stdr_pow(float base, int exp);
    float stdr_sin(float x);
    float stdr_sqrt(float x);
    float stdr_tanf(float x);


stdio.h:
-----------------------------------------------------------------------------------------------------------


    * WIN_VOID   stdr_fclose(WIN_FILE* stream)
    * WIN_INT    stdr_feof(WIN_FILE* stream);
    * WIN_INT    stdr_fgetc(WIN_FILE* stream);
    * WIN_PCHR   stdr_fgets(WIN_PCHR str, WIN_INT n, WIN_FILE* stream);
    * WIN_INT    stdr_fprintf(WIN_HANDLE file, WIN_PCCHR format, ...);
    * WIN_INT    stdr_fscanf(WIN_FILE* stream, WIN_PCCHR format, ...);
    * WIN_FILE*  stdr_fopen(WIN_PCCHR filename, WIN_PCCHR mode);
    * WIN_SIZE_T stdr_fread(WIN_PVOID ptr, WIN_SIZE_T size, WIN_SIZE_T count, WIN_FILE* stream);
    * WIN_INT    stdr_fseek(WIN_FILE* stream, long offset, int whence);
    * WIN_LONG   stdr_ftell(WIN_FILE* stream);
    * WIN_SIZE_T stdr_fwrite(WIN_PCVOID ptr, WIN_SIZE_T size, WIN_SIZE_T count, WIN_FILE* stream);
    * WIN_VOID   stdr_perror(WIN_PCCHR s);
      int        stdr_printf(const char* format, ...);
    * WIN_VOID   stdr_rewind(WIN_FILE* stream);
      int        stdr_sprintf(char* buffer, const char* format, ...);
      int        stdr_sscanf_hex(const char* str, unsigned long* value);
      int        stdr_vsnprintf(char* buffer, stdr_size_t count, const char* format, stdr_va_list args);


stdlib.h:
-----------------------------------------------------------------------------------------------------------


      void*       stdr_calloc(stdr_size_t num, stdr_size_t size);
      void        stdr_exit(int status);
      void        stdr_free(void* ptr);
    * WIN_PVOID   stdr_malloc(WIN_SIZE_T size);
      stdr_size_t stdr_malloc_block_size(void* ptr);
      void*       stdr_realloc(void* ptr, stdr_size_t new_size);


string.h:
-----------------------------------------------------------------------------------------------------------


    int         stdr_memcmp(const void* s1, const void* s2, stdr_size_t n);
    void*       stdr_memcpy(void* dst, const void* src, stdr_size_t n);
    void*       stdr_memset(void* s, int c, stdr_size_t n);
    char*       stdr_strcat(char* dst, const char* src);
    char*       stdr_strchr(const char* str, int c);
    int         stdr_strcmp(const char* str1, const char* str2);
    char*       stdr_strcpy(char* dst, const char* src);
    char*       stdr_strdup(const char* str);
    stdr_size_t stdr_strlen(const char* str);
    int         stdr_strncmp(const char* s1, const char* s2, stdr_size_t n);
    char*       stdr_strrchr(const char* str, int c);
    char*       stdr_strstr(const char* haystack, const char* needle);


unistd.h:
-----------------------------------------------------------------------------------------------------------


    * WIN_SIZE_T stdr_read(WIN_PVOID ptr, WIN_SIZE_T count, WIN_FILE* stream);


wchar.h:
-----------------------------------------------------------------------------------------------------------


    stdr_size_t stdr_wcslen(const stdr_wchar_t* s);
    stdr_size_t stdr_wcstombs(char* dst, const stdr_wchar_t* src, stdr_size_t max);


-----------------------------------------------------------------------------------------------------------


* = Windows only

-- U MAD, BRO? WHY NOT JUST USE THE STANDARD LIBRARY? --

My goal is to generate as small executables as possible. When making demo scene productions,
there are sometimes demo- and intro competition rules that limit the size a demo scene
production can be.

A few common size limitations can be 64kb, 40kb, and 4kb. This is the total size a self contained
executable is allowed to be, excluding api calls accessible directly in a newly installed
operating system.

These size limitations will sometimes force demo scene developers to be creative, and this is one
of the creative ways I aim to utilize for this challenge!

-- USAGE --

As these are drop-in replacements, just use them in the same way you would use the standard library
functions. Just copy any definitions and functions you want to use with your code and go from there.


To try this out you can build it like so:

        gcc -o stdr.exe stdr.c -m32 -nostdlib -lkernel32 "-Wl,-e,__start"

I have included some test cases in main_entry(), but you can of course add more if you wish to try
various functions out.


There are tons of size related optimization flags that can be used with gcc, but be careful using
the -flto flag with this one as it can possibly break the variadic functions. It's a sneaky one
and can appear to work under certain conditions but will likely make kernel32.dll segfault under
others. There is no error handling here if api call arguments would be null when they shouldn't.
You have been warned.


As the scope is focused on size optimization over efficiency, I strongly recommend you to do your
own benchmark tests to compare these with stdlib

-- Are these feature complete? --

As I have only included the functionality I need for my current project, some things may be missing
or lacking compared to their standard library relatives. My goal here is not to make a full
replacement to the standard library.

License

This project is released under the MIT license. If you are a demo scener and choose to use any of
this code in your productions, additional conditions apply as follows: Greetings to dMG and the mighty
crews of diViNE sTYLERs, UP ROUGH, and TiTAN in your production! :D

Cheerios!

About

stdr - or "stutter" (C Standard Library Replacement) - is a (fairly) modular subset replacement for a variety of C standard library functions

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages