diff --git a/.gitignore b/.gitignore index dcbd8c0..e38f598 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ build *.exp *.o *.4coder +*.rdbg diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000..d3ac370 --- /dev/null +++ b/build.cmd @@ -0,0 +1,11 @@ +@echo off +setlocal enabledelayedexpansion + +set CIABATTA_OPTIONS=-Iinc -g -gcodeview -nodefaultlibs -D_CRT_SECURE_NO_WARNINGS + +for /R %%F in (*.c) do ( + clang -c -o build\%%~nF.obj %%F %CIABATTA_OPTIONS% +) +llvm-ar rc ciabatta.lib build\*.obj + +clang test\test.c ciabatta.lib -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS% diff --git a/code/assert.c b/code/assert.c index cd95f43..323f943 100644 --- a/code/assert.c +++ b/code/assert.c @@ -1,55 +1,45 @@ - #include #include +#include #include <_platform.h> // TODO: use abort() to break #if defined(_compiler_msvc) - #include - #define brk __debugbreak +#include +#define brk __debugbreak #else - #define brk __builtin_trap +#define brk __builtin_trap #endif #if defined(_os_win) - #define WIN32_LEAN_AND_MEAN - #include +#define WIN32_LEAN_AND_MEAN +#include - // TODO: make it work via printf +// TODO: make it work via printf +static void _assert_win32_prints(HANDLE conout, char const *str) { + DWORD written = 0; + WriteConsole(conout, str, strlen(str), &written, NULL); +} - static int _assert_strlen(char const *str) - { - int len = 0; - while(*str++!=0) ++len; - return len; +extern void _assert_error(char *cond, char const *func, char const *file, char const *line) { + HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE); + if(conout != INVALID_HANDLE_VALUE) { + _assert_win32_prints(conout, "Assertion Failed: "); + _assert_win32_prints(conout, cond); + _assert_win32_prints(conout, "\n\tFile: "); + _assert_win32_prints(conout, file); + _assert_win32_prints(conout, "\n\tFunc: "); + _assert_win32_prints(conout, func); + _assert_win32_prints(conout, "\n\tLine: "); + _assert_win32_prints(conout, line); } - - static void _assert_win32_prints(HANDLE conout, char const *str) - { - DWORD written = 0; - WriteConsole(conout, str, _assert_strlen(str), &written, NULL); - } - - extern void _assert_error(char *cond, char const *func, char const *file, char const *line) - { - HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE); - if(conout != INVALID_HANDLE_VALUE) { - _assert_win32_prints(conout, "Assertion Failed: "); - _assert_win32_prints(conout, cond); - _assert_win32_prints(conout, "\n\tFile: "); - _assert_win32_prints(conout, file); - _assert_win32_prints(conout, "\n\tFunc: "); - _assert_win32_prints(conout, func); - _assert_win32_prints(conout, "\n\tLine: "); - _assert_win32_prints(conout, line); - } - else { - // TODO: - MessageBoxA(NULL, - "Assertion Failed Somewhere, good luck finding it!\n", - "Error", - MB_OK); - } - brk(); + else { + // TODO: + MessageBoxA(NULL, + "Assertion Failed Somewhere, good luck finding it!\n", + "Error", + MB_OK); } + brk(); +} #endif \ No newline at end of file diff --git a/code/ctype.c b/code/ctype.c index 0f58474..e07fd09 100644 --- a/code/ctype.c +++ b/code/ctype.c @@ -64,7 +64,7 @@ int tolower(int c) { if(isupper(c)) { return c-'A'+'a'; } - return c; + return c; } int toupper(int c) { diff --git a/code/entry_windows.c b/code/entry_windows.c index 7de915f..acc11f2 100644 --- a/code/entry_windows.c +++ b/code/entry_windows.c @@ -1,11 +1,65 @@ - #include <_platform.h> #include +#include -extern int main(); +#define WIN32_LEAN_AND_MEAN +#include -int mainCRTStartup() -{ - setlocale(LC_ALL, "C"); - return main(); +extern int main(int argc, char** argv); + +// Some shell32.lib related crap +DECLSPEC_IMPORT LPWSTR GetCommandLineW(); +DECLSPEC_IMPORT LPWSTR* CommandLineToArgvW(LPCWSTR lpCmdLine, int* pNumArgs); + +static size_t count_wide_chars(const wchar_t* str) { + size_t len = 0; + while (str[len] != 0) len++; + return len; +} + +static bool convert_wide_chars_to_ansi(char* out, const wchar_t* str, size_t len) { + for (size_t i = 0; i < len; i++) { + wchar_t ch = *str++; + if (ch <= 0 && ch > 0x7F) { + *out++ = 0; + return false; + } + + *out++ = ch; + } + + *out++ = 0; + return true; +} + +void mainCRTStartup() { + HANDLE heap = GetProcessHeap(); + if (heap == NULL) { + ExitProcess(-42069); + } + + int arg_count; + LPWSTR* args_wide = CommandLineToArgvW(GetCommandLineW(), &arg_count); + if (!args_wide) { + ExitProcess(-69420); + } + + char** args = HeapAlloc(heap, 0, arg_count * sizeof(char*)); + if (arg_count == 0) { + arg_count = 1; + args[0] = ""; + } + + // Convert wide chars into ANSI + for (int i = 0; i < arg_count; i++) { + size_t wide_len = count_wide_chars(args_wide[i]) + 1; + args[i] = HeapAlloc(heap, 0, wide_len); + + convert_wide_chars_to_ansi(args[i], args_wide[i], wide_len); + } + + setlocale(LC_ALL, "C"); + int exit_code = main(arg_count, args); + + ExitProcess(exit_code); } diff --git a/code/string.c b/code/string.c index ca2a99c..9b50811 100644 --- a/code/string.c +++ b/code/string.c @@ -1,57 +1,57 @@ #include void *memcpy(void *restrict s1, const void *restrict s2, size_t n) { - const unsigned char *restrict c2 = s2; - unsigned char *restrict c1 = s1; + const unsigned char *restrict c2 = s2; + unsigned char *restrict c1 = s1; - while (n--) { - *c1++ = *c2++; - } - return s1; + while (n--) { + *c1++ = *c2++; + } + return s1; } int memcmp(const void *s1, const void *s2, size_t n) { - const unsigned char *u1 = s1; - const unsigned char *u2 = s2; + const unsigned char *u1 = s1; + const unsigned char *u2 = s2; for (; n--; u1++, u2++) { - if (*u1 != *u2) return *u1 - *u2; + if (*u1 != *u2) return *u1 - *u2; } return 0; } void *memset(void *s, int c, size_t n) { - unsigned char *restrict buf = s; - while (n--) { - *buf++ = c; - } - return s; + unsigned char *restrict buf = s; + while (n--) { + *buf++ = c; + } + return s; } int strcmp(const char *s1, const char *s2) { - while (*s1 != 0 && *s2 != 0) { - if (*s1 != *s2) break; - } + while (*s1 != 0 && *s2 != 0) { + if (*s1 != *s2) break; + } - if(*s1 > *s2) return 1; - if(*s1 < *s2) return -1; - return 0; + if(*s1 > *s2) return 1; + if(*s1 < *s2) return -1; + return 0; } size_t strlen(const char *s) { - size_t i = 0; - while (s[i]) { - i++; - } - return i; + size_t i = 0; + while (s[i]) { + i++; + } + return i; } // __STDC_WANT_LIB_EXT1__ size_t strnlen_s(const char *s, size_t maxsize) { - size_t i = 0; - while (s[i] && i < maxsize) { - i++; - } - return i; + size_t i = 0; + while (s[i] && i < maxsize) { + i++; + } + return i; } diff --git a/inc/assert.h b/inc/assert.h index c519463..119d665 100644 --- a/inc/assert.h +++ b/inc/assert.h @@ -1,4 +1,3 @@ - #pragma once #include "_macros.h" diff --git a/makefile b/makefile deleted file mode 100644 index d718419..0000000 --- a/makefile +++ /dev/null @@ -1,27 +0,0 @@ - -# TODO: make shell variable-based path -CLFLAGS=/X /GS- /Iinc /Icode $(shell test\inctoarg) - -CC=clang-cl -CFLAGS=$(CLFLAGS) -LDFLAGS=/nologo /nodefaultlib /entry:mainCRTStartup /subsystem:console - -SRC_DIR := code -OBJ_DIR := build -SRC_FILES := $(wildcard $(SRC_DIR)/*.c) -OBJ_FILES := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.obj,$(SRC_FILES)) - -ciabatta.lib: $(OBJ_FILES) - lib $(LDFLAGS) /out:$@ $^ - -$(OBJ_DIR)/%.obj: $(SRC_DIR)/%.c - $(CC) -c -o $@ $< $(CFLAGS) - -clean: - del /F /Q build\* - del /F /Q lib\ciabatta.lib - -inctoarg: - cl test\inctoarg.c - -.PHONY: inctoarg ciabatta.lib diff --git a/test/inctoarg.c b/test/inctoarg.c deleted file mode 100644 index 234dac2..0000000 --- a/test/inctoarg.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include - -int main() { - char *include = getenv("INCLUDE"); - printf(" "); - while (*include != 0) { - printf("-I \""); - while (*include != ';' && *include != 0) { - if (*include == '\\') { - printf("/"); - } else { - printf("%c", *include); - } - *include++; - } - if (*include == ';') { - ++include; - } - printf("\" "); - } -} diff --git a/test/test.c b/test/test.c index 8fe2724..d895fce 100644 --- a/test/test.c +++ b/test/test.c @@ -1,9 +1,13 @@ #include #include -int main(void) { - for (char c = 'a'; c != 'z'; ++c) { - assert(isupper(toupper(c))); +int main(int argc, char** argv) { + /*for (int i = 0; i < argv; i++) { + printf("[%d] = %s\n", argv[i]); + }*/ + + for (char c = 'a'; c != 'z'; ++c) { + assert(isupper(toupper(c))); } return 0; }