mirror of https://github.com/flysand7/ciabatta.git
Merge branch 'main' of https://github.com/bumbread/ciabatta into main
This commit is contained in:
commit
454a2cc78d
2
bake.cmd
2
bake.cmd
|
@ -16,7 +16,7 @@ shift /1
|
|||
set CIABATTA_OPTIONS=-Iinc -Wall -g -gcodeview -nodefaultlibs -D_CRT_SECURE_NO_WARNINGS
|
||||
set PLATFORM=win
|
||||
|
||||
if "%1"=="fast" (
|
||||
if "%1"=="test" (
|
||||
goto :skip_crt_compilation
|
||||
)
|
||||
:: For each C file in code/ we check whether it's OS-dependent.
|
||||
|
|
|
@ -20,5 +20,5 @@ extern void _assert_error(
|
|||
}
|
||||
printf("\tFile: %s\n", file);
|
||||
printf("\tLine: %s\n", line);
|
||||
_compiler_brk();
|
||||
abort();
|
||||
}
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
|
||||
#include <stdlib.h>
|
|
@ -1,10 +1,12 @@
|
|||
|
||||
#include <_os.h>
|
||||
|
||||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "win32.h"
|
||||
#include "win.h"
|
||||
|
||||
extern int main(int argc, char** argv);
|
||||
|
||||
|
@ -71,6 +73,7 @@ void mainCRTStartup() {
|
|||
|
||||
srand(0);
|
||||
setlocale(LC_ALL, "C");
|
||||
_os_init_eh();
|
||||
int exit_code = main(arg_count, args);
|
||||
|
||||
ExitProcess(exit_code);
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "win.h"
|
||||
|
||||
_Noreturn void _os_exit(int code)
|
||||
{
|
||||
ExitProcess(code);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
#include <_os.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include<Windows.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <_macros.h>
|
||||
|
||||
typedef struct SignalMapping {
|
||||
DWORD code;
|
||||
int signal;
|
||||
} SignalMapping;
|
||||
|
||||
static SignalMapping map[] = {
|
||||
{EXCEPTION_ACCESS_VIOLATION, SIGSEGV},
|
||||
{EXCEPTION_IN_PAGE_ERROR, SIGSEGV},
|
||||
{EXCEPTION_ARRAY_BOUNDS_EXCEEDED, SIGSEGV},
|
||||
{EXCEPTION_DATATYPE_MISALIGNMENT, SIGALIGN},
|
||||
{EXCEPTION_BREAKPOINT, SIGBREAK},
|
||||
{EXCEPTION_FLT_DENORMAL_OPERAND, SIGFPE},
|
||||
{EXCEPTION_FLT_DIVIDE_BY_ZERO, SIGFPE},
|
||||
{EXCEPTION_FLT_INEXACT_RESULT, SIGFPE},
|
||||
{EXCEPTION_FLT_INVALID_OPERATION, SIGFPE},
|
||||
{EXCEPTION_FLT_OVERFLOW, SIGFPE},
|
||||
{EXCEPTION_FLT_STACK_CHECK, SIGFPE},
|
||||
{EXCEPTION_FLT_UNDERFLOW, SIGFPE},
|
||||
{EXCEPTION_ILLEGAL_INSTRUCTION, SIGILL},
|
||||
{EXCEPTION_INT_DIVIDE_BY_ZERO, SIGFPE},
|
||||
{EXCEPTION_INT_OVERFLOW, SIGFPE},
|
||||
{EXCEPTION_PRIV_INSTRUCTION, SIGILL},
|
||||
{EXCEPTION_SINGLE_STEP, SIGSTEP},
|
||||
};
|
||||
|
||||
static LONG _win32_handler(EXCEPTION_POINTERS *ExceptionInfo) {
|
||||
EXCEPTION_RECORD *exception = ExceptionInfo->ExceptionRecord;
|
||||
DWORD code = exception->ExceptionCode;
|
||||
int signal = -1;
|
||||
for(int mapping = 0; mapping != _countof(map); ++mapping) {
|
||||
if(code == map[mapping].code) {
|
||||
signal = map[mapping].signal;
|
||||
}
|
||||
}
|
||||
if(signal != -1) {
|
||||
raise(signal);
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void _os_init_eh() {
|
||||
void *res = AddVectoredExceptionHandler(1, &_win32_handler);
|
||||
if(res == NULL) {
|
||||
ExitProcess(-69420);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#include "win.h"
|
||||
|
||||
// It's just mapped directly to HANDLE
|
||||
struct FILE {
|
||||
int unused;
|
||||
};
|
||||
|
||||
void _os_file_write(void* ctx, size_t n, const char str[]) {
|
||||
DWORD written = 0;
|
||||
WriteFile((HANDLE) ctx, str, n, &written, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "win32.h"
|
||||
#include "win.h"
|
||||
|
||||
// TODO: lock the heap before allocation (?)
|
||||
|
|
@ -75,6 +75,12 @@ inline static int FMT_FUNC_NAME (void *ctx, OutputFunc out, const FMT_CHAR_TYPE
|
|||
|
||||
FMT_CHAR_TYPE ch = *fmt++;
|
||||
switch (ch) {
|
||||
case 'c': {
|
||||
const char chr = va_arg(args, int);
|
||||
out(ctx, 1, &chr);
|
||||
full_length ++;
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
const FMT_CHAR_TYPE *str = va_arg(args, FMT_CHAR_TYPE*);
|
||||
size_t len = FMT_STRLEN_S(str, precision ? precision : SIZE_MAX);
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
#include <_os.h>
|
||||
#include <signal.h>
|
||||
|
||||
void _signal_default_handler(int sig)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void _signal_ignore_handler(int sig)
|
||||
{
|
||||
// ignore :kekw:
|
||||
}
|
||||
|
||||
static void (*(handlers[]))(int) = {
|
||||
[SIGINT] = _signal_ignore_handler,
|
||||
[SIGILL] = _signal_ignore_handler,
|
||||
[SIGFPE] = _signal_ignore_handler,
|
||||
[SIGSEGV] = _signal_ignore_handler,
|
||||
[SIGTERM] = _signal_ignore_handler,
|
||||
[SIGABRT] = _signal_ignore_handler,
|
||||
[SIGBREAK] = _signal_ignore_handler,
|
||||
[SIGALIGN] = _signal_ignore_handler,
|
||||
[SIGSTEP] = _signal_ignore_handler,
|
||||
};
|
||||
|
||||
void (*signal(int sig, void (*func)(int)))(int)
|
||||
{
|
||||
if(_SIG_MIN <= sig && sig <= _SIG_MAX) {
|
||||
handlers[sig] = func;
|
||||
return func;
|
||||
}
|
||||
return SIG_ERR;
|
||||
}
|
||||
|
||||
int raise(int sig)
|
||||
{
|
||||
if(_SIG_MIN <= sig && sig <= _SIG_MAX) {
|
||||
handlers[sig](sig);
|
||||
if(sig == SIGFPE || sig == SIGILL || sig == SIGSEGV) {
|
||||
_os_exit(-69420);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
33
code/stdio.c
33
code/stdio.c
|
@ -7,6 +7,8 @@
|
|||
#define __STDC_WANT_LIB_EXT1__ 1
|
||||
#include <string.h>
|
||||
|
||||
#include <_os.h>
|
||||
|
||||
typedef void(*OutputFunc)(void* ctx, size_t n, const char str[]);
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
@ -18,29 +20,6 @@ typedef void(*OutputFunc)(void* ctx, size_t n, const char str[]);
|
|||
#define FMT_STRLEN_S(s, maxsize) strnlen_s(s, maxsize)
|
||||
#include "printf.h"
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Platform dependent
|
||||
///////////////////////////////////////////////
|
||||
#if defined(_os_win)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
// It's just mapped directly to HANDLE
|
||||
struct FILE {
|
||||
int unused;
|
||||
};
|
||||
|
||||
static void file_write(void* ctx, size_t n, const char str[]) {
|
||||
DWORD written = 0;
|
||||
WriteFile((HANDLE) ctx, str, n, &written, NULL);
|
||||
}
|
||||
#else
|
||||
#error "TODO: Implement this"
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Platform indenpendent
|
||||
///////////////////////////////////////////////
|
||||
typedef struct {
|
||||
size_t used, capacity;
|
||||
char* string;
|
||||
|
@ -61,12 +40,12 @@ static void string_write(void *ctx, size_t n, const char *restrict str) {
|
|||
}
|
||||
|
||||
int fprintf(FILE *file, const char *restrict fmt, ...) {
|
||||
CALL_PRINTF(fmt_print_char, file, file_write, fmt);
|
||||
CALL_PRINTF(fmt_print_char, file, _os_file_write, fmt);
|
||||
return result;
|
||||
}
|
||||
|
||||
int printf(const char *restrict fmt, ...) {
|
||||
CALL_PRINTF(fmt_print_char, stdout, file_write, fmt);
|
||||
CALL_PRINTF(fmt_print_char, stdout, _os_file_write, fmt);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -83,11 +62,11 @@ int sprintf(char *restrict s, const char *restrict fmt, ...) {
|
|||
}
|
||||
|
||||
int vfprintf(FILE *file, const char *restrict fmt, va_list args) {
|
||||
return fmt_print_char(file, file_write, fmt, args);
|
||||
return fmt_print_char(file, _os_file_write, fmt, args);
|
||||
}
|
||||
|
||||
int vprintf(const char *restrict fmt, va_list args) {
|
||||
return fmt_print_char(stdout, file_write, fmt, args);
|
||||
return fmt_print_char(stdout, _os_file_write, fmt, args);
|
||||
}
|
||||
|
||||
int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list args) {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <_os.h>
|
||||
|
||||
_Noreturn void abort(void) {
|
||||
raise(SIGABRT);
|
||||
_os_exit(-69);
|
||||
}
|
||||
|
||||
// TODO: at_exit handling
|
||||
|
||||
_Noreturn void exit(int status) {
|
||||
_os_exit(status);
|
||||
}
|
||||
|
||||
_Noreturn void _Exit(int status) {
|
||||
_os_exit(status);
|
||||
}
|
||||
|
155
code/string.c
155
code/string.c
|
@ -20,8 +20,7 @@ void *memcpy(void *restrict s1, const void *restrict s2, size_t n) {
|
|||
return s1;
|
||||
}
|
||||
|
||||
void *memmove(void *s1, const void *s2, size_t n)
|
||||
{
|
||||
void *memmove(void *s1, const void *s2, size_t n) {
|
||||
void *buffer = malloc(n);
|
||||
memcpy(buffer, s2, n);
|
||||
memcpy(s1, buffer, n);
|
||||
|
@ -29,16 +28,7 @@ void *memmove(void *s1, const void *s2, size_t n)
|
|||
return s1;
|
||||
}
|
||||
|
||||
void *memset(void *s, int c, size_t n) {
|
||||
byte *restrict buf = s;
|
||||
while (n--) {
|
||||
*buf++ = c;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
char *strcpy(char *restrict s1, const char *restrict s2)
|
||||
{
|
||||
char *strcpy(char *restrict s1, const char *restrict s2) {
|
||||
while(*s2 != 0) {
|
||||
*s1++ = *s2++;
|
||||
}
|
||||
|
@ -46,25 +36,26 @@ char *strcpy(char *restrict s1, const char *restrict s2)
|
|||
return s1;
|
||||
}
|
||||
|
||||
char *strncpy(char *restrict s1, const char *restrict s2, size_t n)
|
||||
{
|
||||
while(n-->0 && *s2 != 0) {
|
||||
char *strncpy(char *restrict s1, const char *restrict s2, size_t n) {
|
||||
size_t i = 0;
|
||||
for(; i < n && *s2 != 0; ++ i) {
|
||||
*s1++ = *s2++;
|
||||
}
|
||||
while(n-->0) {
|
||||
for(; i < n; ++i) {
|
||||
*s1++ = 0;
|
||||
}
|
||||
return s1;
|
||||
}
|
||||
|
||||
|
||||
char *strncat(char *restrict s1, const char *restrict s2, size_t n)
|
||||
{
|
||||
char *strcat(char *restrict s1, const char *restrict s2) {
|
||||
size_t start = strlen(s1);
|
||||
for(size_t i = 0; i != n && *s2 != 0; ++i) {
|
||||
s1[start+i] = s2[i];
|
||||
}
|
||||
s1[start+n] = 0;
|
||||
return strcpy(s1+start, s2);
|
||||
}
|
||||
|
||||
char *strncat(char *restrict s1, const char *restrict s2, size_t n) {
|
||||
size_t start = strlen(s1);
|
||||
strncpy(s1+start, s2, n);
|
||||
return s1;
|
||||
}
|
||||
|
||||
|
@ -78,6 +69,14 @@ int memcmp(const void *s1, const void *s2, size_t n) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void *memset(void *s, int c, size_t n) {
|
||||
byte *restrict buf = s;
|
||||
while (n--) {
|
||||
*buf++ = c;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2) {
|
||||
int diff;
|
||||
do {
|
||||
|
@ -86,8 +85,7 @@ int strcmp(const char *s1, const char *s2) {
|
|||
return diff;
|
||||
}
|
||||
|
||||
int strncmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
int strncmp(const char *s1, const char *s2, size_t n) {
|
||||
int diff = 0;
|
||||
size_t i = 0;
|
||||
if(n != 0) do {
|
||||
|
@ -96,15 +94,13 @@ int strncmp(const char *s1, const char *s2, size_t n)
|
|||
return diff;
|
||||
}
|
||||
|
||||
// fuck locales
|
||||
int strcoll(const char *s1, const char *s2)
|
||||
{
|
||||
int strcoll(const char *s1, const char *s2) {
|
||||
return strcmp(s1, s2);
|
||||
}
|
||||
|
||||
// fuck bad implementation of strcoll
|
||||
size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n)
|
||||
{
|
||||
// TODO: I don't quite understand the intent nor use behind this function
|
||||
// so I'm just going to ignore locales for now.
|
||||
size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n) {
|
||||
size_t len = strlen(s2);
|
||||
if(s1 != NULL && n != 0) {
|
||||
for(size_t i = 0; i != n; ++i) {
|
||||
|
@ -114,39 +110,47 @@ size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n)
|
|||
return len;
|
||||
}
|
||||
|
||||
void *memchr(const void *ptr, int c, size_t n)
|
||||
{
|
||||
const byte *s = ptr;
|
||||
size_t i = 0;
|
||||
for(; i != n && *s != c; ++i, ++s) {
|
||||
++s;
|
||||
void *memchr(const void *ptr, int c, size_t n) {
|
||||
const char *s = ptr;
|
||||
for(size_t i = 0; i != n; ++i) {
|
||||
if(s[i] == c) {
|
||||
// Casting away const because clang warnings
|
||||
return (void *)(s+i);
|
||||
}
|
||||
if(i == n) return NULL;
|
||||
return (void *)s; // fuck clang
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *strchr(const char *s, int c)
|
||||
{
|
||||
while(*s && *s != c) ++s;
|
||||
if(*s != c) return NULL;
|
||||
return (void *)s; // fuck clang
|
||||
char *strchr(const char *s, int c) {
|
||||
do {
|
||||
if(*s == c) return (char *)s;
|
||||
} while(*s++);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t strcspn(const char *s1, const char *s2)
|
||||
{
|
||||
size_t strspn(const char *s1, const char *s2) {
|
||||
size_t i = 0;
|
||||
while(*s1) {
|
||||
if(strchr(s2, *s1) != NULL) {
|
||||
for(; *s1; ++s1) {
|
||||
if(strchr(s2, *s1) == NULL) {
|
||||
break;
|
||||
}
|
||||
++s1;
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
char *strpbrk(const char *s1, const char *s2)
|
||||
{
|
||||
size_t strcspn(const char *s1, const char *s2) {
|
||||
size_t i = 0;
|
||||
for(; *s1; ++s1) {
|
||||
if(strchr(s2, *s1) != NULL) {
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
char *strpbrk(const char *s1, const char *s2) {
|
||||
while(*s1) {
|
||||
if(strchr(s2, *s1) == NULL) {
|
||||
break;
|
||||
|
@ -156,26 +160,47 @@ char *strpbrk(const char *s1, const char *s2)
|
|||
return (char *)s1;
|
||||
}
|
||||
|
||||
char *strstr(const char *s1, const char *s2)
|
||||
{
|
||||
if(!*s2) return (char *)s1;
|
||||
char *strrchr(const char *s, int c) {
|
||||
char const *last = NULL;
|
||||
for(; *s != 0; ++s) {
|
||||
if(*s == c) last = s;
|
||||
}
|
||||
return (char *)last;
|
||||
}
|
||||
|
||||
char *strstr(const char *s1, const char *s2) {
|
||||
if(*s2 == 0) return (char *)s1;
|
||||
size_t len = strlen(s2);
|
||||
while(*s1 != 0) {
|
||||
bool match = true;
|
||||
for(size_t i = 0; i != len; ++i) {
|
||||
if(!*s1 || s1[i] != s2[i]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++s1;
|
||||
if(match) return (char *)s1;
|
||||
for(; *s1 != 0; ++s1) {
|
||||
if(strncmp(s1, s2, len) == 0) return (char *)s1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *strerror(int errnum)
|
||||
{
|
||||
// TODO: there may be restrict-related UB
|
||||
char *strtok(char *restrict s1, const char *restrict s2) {
|
||||
static char *restrict str;
|
||||
if(s1 != NULL) str = s1;
|
||||
if(str == NULL) return NULL;
|
||||
|
||||
size_t junk_len = strspn(str, s2);
|
||||
char *tok_start = str+junk_len;
|
||||
if(*tok_start == 0) {
|
||||
str = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t tok_len = strcspn(str, s2);
|
||||
|
||||
char *tok_end = tok_start + tok_len;
|
||||
*tok_end = 0;
|
||||
str = tok_end+1;
|
||||
|
||||
return tok_start;
|
||||
}
|
||||
|
||||
|
||||
char *strerror(int errnum) {
|
||||
switch(errnum) {
|
||||
case 0: return "No errors";
|
||||
case EDOM: return "Value is out of domain of the function";
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
|
||||
#define _con(a,b) a ## b
|
||||
|
||||
#define _countof(arr) (sizeof (arr) / sizeof ((arr)[0]))
|
||||
|
|
|
@ -13,3 +13,9 @@
|
|||
|| defined(_os_linux))
|
||||
#error "Unsupported OS"
|
||||
#endif
|
||||
|
||||
// OS-dependent IO Functions
|
||||
void _os_file_write(void* ctx, size_t n, const char str[]);
|
||||
_Noreturn void _os_exit(int code);
|
||||
void _os_init_eh();
|
||||
typedef struct FILE FILE;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "_compiler.h"
|
||||
#include "_macros.h"
|
||||
|
||||
extern void _assert_error(
|
||||
char *cond,
|
||||
|
|
29
inc/signal.h
29
inc/signal.h
|
@ -3,19 +3,24 @@
|
|||
|
||||
typedef int sig_atomic_t;
|
||||
|
||||
// TODO: implement this
|
||||
#define SIG_DFL 0
|
||||
#define SIG_ERR 1
|
||||
#define SIG_IGN 2
|
||||
// TODO: idk about SIG_ERR, for now this
|
||||
#define SIG_ERR ((void(*)(int))0)
|
||||
#define SIG_DFL _signal_default_handler
|
||||
#define SIG_IGN _signal_ignore_handler
|
||||
|
||||
// not sure why but windows picked these, we can change it later
|
||||
#define SIGINT 2
|
||||
#define SIGILL 4
|
||||
#define SIGFPE 8
|
||||
#define SIGSEGV 11
|
||||
#define SIGTERM 15
|
||||
#define SIGBREAK 21
|
||||
#define SIGABRT 22
|
||||
// Note(bumbread): from the impl standpoint the numbers are arbitrary
|
||||
#define _SIG_MIN 0
|
||||
#define SIGINT 1
|
||||
#define SIGILL 2
|
||||
#define SIGFPE 3
|
||||
#define SIGSEGV 4
|
||||
#define SIGTERM 5
|
||||
#define SIGABRT 6
|
||||
// These guys are impl defined
|
||||
#define SIGBREAK 7
|
||||
#define SIGALIGN 8
|
||||
#define SIGSTEP 9
|
||||
#define _SIG_MAX 9
|
||||
|
||||
void (*signal(int sig, void (*func)(int)))(int);
|
||||
int raise(int sig);
|
||||
|
|
14
inc/stdio.h
14
inc/stdio.h
|
@ -6,6 +6,10 @@
|
|||
typedef struct FILE FILE;
|
||||
typedef int64_t fpos_t;
|
||||
|
||||
#if !defined(NULL)
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_LIB_EXT1__)
|
||||
#define __STDC_LIB_EXT1__
|
||||
typedef int errno_t;
|
||||
|
@ -29,9 +33,9 @@ typedef int64_t fpos_t;
|
|||
#define FOPEN_MAX 20
|
||||
|
||||
#ifdef _os_win
|
||||
#define FILENAME_MAX 260
|
||||
#define FILENAME_MAX 260
|
||||
#else
|
||||
#define FILENAME_MAX 4096
|
||||
#define FILENAME_MAX 4096
|
||||
#endif
|
||||
|
||||
#define L_tmpnam FILENAME_MAX
|
||||
|
@ -40,7 +44,11 @@ typedef int64_t fpos_t;
|
|||
#define SEEK_END 2
|
||||
#define SEEK_SET 0
|
||||
|
||||
#define TMP_MAX INT_MAX
|
||||
#ifdef _os_win
|
||||
#define TMP_MAX SHORT_MAX
|
||||
#else
|
||||
#define TMP_MAX INT_MAX
|
||||
#endif
|
||||
|
||||
extern FILE *stdout, *stderr, *stdin;
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#define EXIT_SUCCESS 0
|
||||
#define EXIT_FAILURE 1
|
||||
|
||||
// typedef struct div_t {
|
||||
// int quot;
|
||||
// int rem;
|
||||
|
@ -55,11 +58,11 @@ void free(void *ptr);
|
|||
void *malloc(size_t size);
|
||||
void *realloc(void *ptr, size_t size);
|
||||
|
||||
// _Noreturn void abort(void);
|
||||
_Noreturn void abort(void);
|
||||
// int atexit(void (*func)(void));
|
||||
// int at_quick_exit(void (*func)(void));
|
||||
// _Noreturn void exit(int status);
|
||||
// _Noreturn void _Exit(int status);
|
||||
_Noreturn void exit(int status);
|
||||
_Noreturn void _Exit(int status);
|
||||
// char *getenv(const char *name);
|
||||
// _Noreturn void quick_exit(int status);
|
||||
// int system(const char *string);
|
||||
|
|
31
inc/string.h
31
inc/string.h
|
@ -1,6 +1,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
// Technically all we should have here is typedef for size_t.
|
||||
// but I can't get that without macro shittery so
|
||||
// for now I'm just doing this, which is not quite correct
|
||||
#include <stddef.h>
|
||||
|
||||
#if !defined(NULL)
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
@ -19,17 +24,17 @@
|
|||
|
||||
// int _wcsicmp(const wchar_t *string1, const wchar_t *string2);
|
||||
|
||||
void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
|
||||
void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
|
||||
void *memmove(void *s1, const void *s2, size_t n);
|
||||
char *strcpy(char * restrict s1, const char * restrict s2);
|
||||
char *strncpy(char * restrict s1, const char * restrict s2, size_t n);
|
||||
char *strcat(char * restrict s1, const char * restrict s2);
|
||||
char *strncat(char * restrict s1, const char * restrict s2, size_t n);
|
||||
char *strcpy(char *restrict s1, const char *restrict s2);
|
||||
char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
|
||||
char *strcat(char *restrict s1, const char *restrict s2);
|
||||
char *strncat(char *restrict s1, const char *restrict s2, size_t n);
|
||||
int memcmp(const void *s1, const void *s2, size_t n);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
int strcoll(const char *s1, const char *s2);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
size_t strxfrm(char * restrict s1, const char * restrict s2, size_t n);
|
||||
size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n);
|
||||
void *memchr(const void *s, int c, size_t n);
|
||||
char *strchr(const char *s, int c);
|
||||
size_t strcspn(const char *s1, const char *s2);
|
||||
|
@ -37,19 +42,19 @@ char *strpbrk(const char *s1, const char *s2);
|
|||
char *strrchr(const char *s, int c);
|
||||
size_t strspn(const char *s1, const char *s2);
|
||||
char *strstr(const char *s1, const char *s2);
|
||||
char *strtok(char * restrict s1, const char * restrict s2);
|
||||
char *strtok(char *restrict s1, const char *restrict s2);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
char *strerror(int errnum);
|
||||
size_t strlen(const char *s);
|
||||
|
||||
#if __STDC_WANT_LIB_EXT1__ == 1
|
||||
errno_t memcpy_s(void * restrict s1, rsize_t s1max, const void * restrict s2, rsize_t n);
|
||||
errno_t memcpy_s(void *restrict s1, rsize_t s1max, const void *restrict s2, rsize_t n);
|
||||
errno_t memmove_s(void *s1, rsize_t s1max, const void *s2, rsize_t n);
|
||||
errno_t strcpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2);
|
||||
errno_t strncpy_s(char * restrict s1, rsize_t s1max,const char * restrict s2, rsize_t n);
|
||||
errno_t strcat_s(char * restrict s1, rsize_t s1max, const char * restrict s2);
|
||||
errno_t strncat_s(char * restrict s1, rsize_t s1max, const char * restrict s2, rsize_t n);
|
||||
char *strtok_s(char * restrict s1, rsize_t * restrict s1max, const char * restrict s2, char ** restrict ptr);
|
||||
errno_t strcpy_s(char *restrict s1, rsize_t s1max, const char *restrict s2);
|
||||
errno_t strncpy_s(char *restrict s1, rsize_t s1max,const char *restrict s2, rsize_t n);
|
||||
errno_t strcat_s(char *restrict s1, rsize_t s1max, const char *restrict s2);
|
||||
errno_t strncat_s(char *restrict s1, rsize_t s1max, const char *restrict s2, rsize_t n);
|
||||
char *strtok_s(char *restrict s1, rsize_t *restrict s1max, const char *restrict s2, char **restrict ptr);
|
||||
errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n);
|
||||
errno_t strerror_s(char *s, rsize_t maxsize, errno_t errnum);
|
||||
size_t strerrorlen_s(errno_t errnum);
|
||||
|
|
25
test/test.c
25
test/test.c
|
@ -4,10 +4,31 @@
|
|||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
int test() {
|
||||
static int a = 2;
|
||||
a += 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
uint64_t mynumber = 4;
|
||||
printf("Hello, guys %"PRIu64"\n", mynumber);
|
||||
test();
|
||||
char input[] = "A bird came down the walk";
|
||||
printf("Parsing the input string '%s'\n", input);
|
||||
char *token = strtok(input, " ");
|
||||
while(token) {
|
||||
printf("%s\n", token);
|
||||
token = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
printf("Contents of the input string now: '");
|
||||
for(size_t n = 0; n < sizeof input; ++n)
|
||||
input[n] ? printf("%c", input[n]) : printf("\\0");
|
||||
printf("'");
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue