-
Notifications
You must be signed in to change notification settings - Fork 157
Smaller C Standard Library Wiki
Supported headers and functions
The standard library is mostly complete for DOS and Windows and is already usable. In fact, the precompiled Smaller C binaries have been compiled with Smaller C and linked with the Smaller C standard library. Most of the compiler tests in this repository also successfully work with the library. This shows some maturity. The Linux version of the standard library is planned, but there's no ETA.
The library is implemented on top of system calls of DOS, Windows and Linux (Linux version is still TBD).
The DOS version of the library requires one of:
- MS-DOS 4.01 or better, i80386 CPU or better
- Windows 95/98/Me/2000/XP or 32-bit Windows Vista/7
- DOSBox 0.74 or better
The Windows version of the library requires one of:
- Client OS: Windows XP or better
- Server OS: Windows Server 2003 or better
NDEBUG
assert()
isalnum(), isalpha(), isblank(), iscntrl(), isdigit(), isgraph(), islower()
isprint(), ispunct(), isspace(), isupper(), isxdigit(), tolower(), toupper()
ERANGE
errno
Note that the C standard does not define most of the E* macros, which are system-specific. As of now, there's only ERANGE supported and errno is never set to anything else than 0 and ERANGE.
O_RDONLY, O_WRONLY, O_RDWR, O_ACCMODE
O_CREAT, O_EXCL, O_TRUNC, O_APPEND
mode_t
off_t
creat()
open() (doesn't fully support O_APPEND since it's not directly supported by DOS/Windows system calls)
and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor, xor_eq
CHAR_BIT, CHAR_MIN, CHAR_MAX (char is signed by default)
SCHAR_MIN, SCHAR_MAX, UCHAR_MAX
SHRT_MIN, SHRT_MAX, USHRT_MAX
INT_MIN, INT_MAX, UINT_MAX
LONG_MIN, LONG_MAX, ULONG_MAX
Note that long/32-bit types available in 32-bit and huge memory models only.
NULL
LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME
struct lconv
setlocale(), localeconv()
Note that only the "C" locale is supported.
jmp_buf
setjmp(), longjmp()
sig_atomic_t
SIG_DFL, SIG_ERR, SIG_IGN
SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM
signal(), raise()
Note that currently signal() and raise() do nothing and return an error.
va_list
Note that the macros va_start(), va_arg(), va_end() and va_copy() aren't available at the moment because they can only be implemented with a more or less complete preprocessor, which Smaller C does not have at the moment. If you want to implement a function with a variable number of parameters like printf(), see how printf() is implemented.
NULL
size_t, ptrdiff_t
Note that the offsetof(type, member) macro requires a more or less complete preprocessor, which Smaller C does not have at the moment. But you can implement it in-place as simply ((unsigned)&((type*)0)->member).
intptr_t, uintptr_t
INTPTR_MIN, INTPTR_MAX, UINTPTR_MAX
PTRDIFF_MIN, PTRDIFF_MAX
SIZE_MAX
intmax_t, uintmax_t
INTMAX_MIN, INTMAX_MAX, UINTMAX_MAX
Note that [u]intmax_t is not a 64-bit or larger type, which it should be. It's a 16-bit integer in 16-bit memory models (tiny and small) and 32-bit in 32-bit and huge memory models.
int8_t, int_least8_t, int_fast8_t
uint8_t, uint_least8_t, uint_fast8_t
int16_t, int_least16_t, int_fast16_t
uint16_t, uint_least16_t, uint_fast16_t
int32_t, int_least32_t, int_fast32_t (32-bit types available in 32-bit and huge memory models only)
uint32_t, uint_least32_t, uint_fast32_t
[U]INT_*8_MIN, [U]INT_*8_MAX
[U]INT_*16_MIN, [U]INT_*16_MAX
[U]INT_*32_MIN, [U]INT_*32_MAX
Note there are no [u]int64*_t types.
NULL
size_t
EOF
SEEK_SET, SEEK_CUR, SEEK_END
fpos_t (contains unsigned short halves[2], the least significant (halves[0]) and the most significant (halves[1]) 16 bits of 32-bit file offsets/positions)
FILE
stdin, stdout, stderr
_IOFBF, _IONBF, _IOLBF, BUFSIZ
FOPEN_MAX, TMP_MAX
FILENAME_MAX, L_tmpnam
fopen() (doesn't support "a+" mode because it's not supported by DOS/Windows directly. "a" should work, though)
freopen() (doesn't support "a+"; doesn't support changing file mode when filename==NULL)
fflush()
fclose()
remove(), rename()
fread(), fwrite()
fgetc(), getc(), getchar()
ungetc() (you must first successfully read a character before calling ungetc())
fgets(), gets()
fputc(), putc(), putchar()
fputs(), puts()
ftell(), fseek() (available in 32-bit and huge memory models only since they provide the long/32-bit type, but you might use __ftell() and __fseek() instead, however, these two latter functions have not been thoroughly tested; also you may use fgetpos() and fsetpos() instead)
fgetpos(), fsetpos()
rewind()
clearerr(), ferror(), feof()
perror() (always prints "Unknown error <value of errno>")
setvbuf(), setbuf()
tmpnam(), tmpfile()
vfprintf(), fprintf()
vprintf(), printf()
vsprintf(), sprintf()
vsnprintf(), snprintf()
vfscanf(), fscanf() (scanf functions do not support ranges, e.g. "[a-z]")
vscanf(), scanf()
vsscanf(), sscanf()
fileno() (POSIX)
__ftell(), __fseek() (Smaller C-specific; these are similar to ftell() and fseek(), but offsets are passed/returned via a pointer to fpos_t and fpos_t consists of 2 16-bit integers as opposed to 1 32-bit integer; these functions are intended for the tiny and small memory models in which 32-bit/long types aren't supported; these two functions haven't been thoroughly tested)
NULL
size_t
EXIT_SUCCESS, EXIT_FAILURE
abort() (uses exit(EXIT_FAILURE) instead of raise(SIGABRT))
_Exit() (does not flush/close open files)
exit()
atexit()
malloc(), calloc(), free(), realloc()
abs()
labs() (available in 32-bit and huge memory models only)
atoi()
atol(), strtol(), strtoul() (available in 32-bit and huge memory models only)
rand(), srand()
bsearch(), qsort()
getenv()
system() (the DOS version will try to execute your .COM/.EXE directly, not via COMMAND.COM; this was done in order to receive termination status from smlrc.exe, smlrl.exe and nasm.exe since "COMMAND.COM /C program" would always terminate with status 0, no matter how the program exits)
NULL
size_t
memset(), memcpy(), memmove()
memchr(), memcmp()
strcpy(), strncpy()
strxfrm()
strcat(), strncat()
strlen()
strchr(), strrchr(), strstr()
strcmp(), strncmp(), strcoll() (strcoll() is the same as strcmp())
strspn(), strcspn(), strpbrk()
strtok()
strerror() (always returns "Unknown error <value of errno>")
NULL
size_t
time_t, clock_t
CLOCKS_PER_SEC
struct tm
clock()
time()
gmtime(), localtime()
mktime()
ctime()
asctime()
strftime()
Note that most of functions operate with the type time_t, which is 32-bit. 32-bit/long types are available in 32-bit and huge memory models only and so are most of the functions in time.h.
Note that difftime() cannot be implemented correctly in Smaller C because it returns a double. Floating point types aren't supported by Smaller C.
Note that DOS implementations of all time functions operate with local time (and never UTC/GMT) since there's no standard way to set and maintain time zones and such in DOS. In the future these functions could be re-implemented to rely on the value of the environment variable TZ, commonly found in UNIX-like systems.
NULL
size_t, ssize_t
intptr_t
off_t
SEEK_SET, SEEK_CUR, SEEK_END
STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO
lseek() (available in 32-bit and huge memory models only since they provide the long/32-bit type, but you might use __lseek() instead, however, the latter has not been tested)
read(), write()
unlink() (has basic semantics of remove())
isatty()
__lseek() (Smaller C-specific; similar to lseek() but offsets are passed/returned via a pointer to fpos_t and fpos_t consists of 2 16-bit integers as opposed to 1 32-bit integer; this function is intended for the tiny and small memory models in which 32-bit/long types aren't supported; this function hasn't been thoroughly tested)
S_IR*, S_IW*, S_IX*, S_IRWX*
mode_t
off_t
time_t
mode_t
off_t
fpos_t
size_t, ssize_t
time_t
The following functions implement poor-man's 32-bit arithmetic using pairs of 16-bit short unsigned ints.
__lngFromUnsigned() (creates a 32-bit value in 2 unsigned shorts from 1 unsigned int)
__lngFromSigned() (creates a 32-bit value in 2 unsigned shorts from 1 signed int)
__lngToUnsigned() (converts/truncates 32-bit value of a pair of 2 unsigned shorts to an unsigned int)
__lngToSigned() (converts/truncates 32-bit value of a pair of 2 unsigned shorts to a signed int)
__lngAdd() (adds 2 pairs of 2 unsigned shorts as 32-bit integers)
__lngSub() (subtracts 2 pairs of 2 unsigned shorts as 32-bit integers)
__lngEq() (compares 2 pairs of 2 unsigned shorts for equality)
__lngUnsignedLess() (tests if the first pair of 2 unsigned shorts is less than the second pair; the 32-bit values are treated as unsigned)
__lngSignedLess() (tests if the first pair of 2 unsigned shorts is less than the second pair; the 32-bit values are treated as signed)
__lngLessThan0() (tests the 32-bit value of a pair of 2 unsigned shorts is less than zero; the 32-bit value is treated as signed)
Note, these functions haven't been thoroughly tested.
Floating point types aren't supported by Smaller C.
Floating point types aren't supported by Smaller C.
Floating point types aren't supported by Smaller C.
Some of the functions can be implemented, but most macros require a more or less complete preprocessor, which Smaller C does not have at the moment.
Floating point types aren't supported by Smaller C.
The type bool requires a special type, _Bool, to be supported by the compiler internally. This may be implemented in the future.
Floating point types aren't supported by Smaller C.
The type wchar_t and wide characters and wide string literals aren't supported by Smaller C. Further, it looks like this functionality may need to be implemented differently for different platforms.
The type wchar_t and wide characters and wide string literals aren't supported by Smaller C. Further, it looks like this functionality may need to be implemented differently for different platforms.
POSIX compatibility is rudimentary. It is not planned to extend it much beyond what's already supported. Some basic functions like access(), stat(), chmod(), opendir(), readdir(), etc may be implemented in the future.
Some of conio.h, dos.h, etc functionality (e.g. clrscr(), kbhit(), getche(), intr(), etc), commonly found in compilers for DOS such as Borland/Turbo C/C++, Open Watcom C/C++ and Microsoft C/Visual C++, may be implemented in the future.
DOS, Windows and Linux provide a lot of system calls with documented public APIs. Many of them are usually accessible with other compilers via dedicated system header files. However, there's no goal to make all of them accessible via e.g. <Windows.h> in the library or in some other way. The primary focus of Smaller C is on what's defined in the language standard and thus on what is required in the standard library. Everything else is secondary.
The library does not support multithreading.
You can recompile the library. First, make sure you can successfully compile a hello-world-type of simple application. If that works, that means the compiler can successfully find system header files, which will be needed.
Change the current directory to srclib and then do:
smlrcc @lcw.txt
smlrcc @lcdh.txt
smlrcc @lcds.txt
This will produce files lcdh.a, lcds.a and lcw.a. You can then copy them into directory lib and try to use.