mirror of https://github.com/flysand7/ciabatta.git
Added printf variants
This commit is contained in:
parent
04555ac1db
commit
e964f2375d
|
@ -4,6 +4,7 @@ setlocal enabledelayedexpansion
|
||||||
set PLATFORM=win32
|
set PLATFORM=win32
|
||||||
set CIABATTA_OPTIONS=-Iinc -g -gcodeview -nodefaultlibs -D_CRT_SECURE_NO_WARNINGS
|
set CIABATTA_OPTIONS=-Iinc -g -gcodeview -nodefaultlibs -D_CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
|
del ciabatta.lib
|
||||||
for /R code %%F in (*.c) do (
|
for /R code %%F in (*.c) do (
|
||||||
echo %%F
|
echo %%F
|
||||||
clang -c -o build\%%~nF.obj %%F %CIABATTA_OPTIONS%
|
clang -c -o build\%%~nF.obj %%F %CIABATTA_OPTIONS%
|
||||||
|
@ -15,3 +16,5 @@ for /R platform\%PLATFORM% %%F in (*.c) do (
|
||||||
llvm-ar rc ciabatta.lib build\*.obj
|
llvm-ar rc ciabatta.lib build\*.obj
|
||||||
|
|
||||||
clang test\test.c ciabatta.lib -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS%
|
clang test\test.c ciabatta.lib -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS%
|
||||||
|
del build\*.obj
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
// NOTE: this file doesn't exist in a vacuum, it's a template for generating
|
||||||
|
// the formatted print, you should define FMT_CHAR_TYPE before including it
|
||||||
|
inline static int FMT_FUNC_NAME (void *ctx, OutputFunc out, const FMT_CHAR_TYPE *fmt, va_list args) {
|
||||||
|
size_t full_length = 0;
|
||||||
|
|
||||||
|
while (*fmt) {
|
||||||
|
// skip any normal non percent text
|
||||||
|
const FMT_CHAR_TYPE *start = fmt;
|
||||||
|
while (*fmt && *fmt != '%') fmt++;
|
||||||
|
|
||||||
|
// print all those non percent text
|
||||||
|
out(ctx, fmt - start, start);
|
||||||
|
full_length += (fmt - start);
|
||||||
|
|
||||||
|
// null terminated
|
||||||
|
if (*fmt == '\0') break;
|
||||||
|
fmt += 1;
|
||||||
|
|
||||||
|
if (*fmt == '%') {
|
||||||
|
out(ctx, 1, "%");
|
||||||
|
fmt++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int precision = 0;
|
||||||
|
if (*fmt == '.') {
|
||||||
|
// custom precision
|
||||||
|
fmt++;
|
||||||
|
|
||||||
|
if (isdigit(*fmt)) {
|
||||||
|
// just a small atoi
|
||||||
|
while (isdigit(*fmt)) {
|
||||||
|
precision *= 10u;
|
||||||
|
precision += (*fmt - '0');
|
||||||
|
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
} else if (*fmt == '*') {
|
||||||
|
int p = va_arg(args, int);
|
||||||
|
|
||||||
|
precision = p >= 0 ? ((unsigned int)p) : 0;
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// integer length specifiers
|
||||||
|
enum {
|
||||||
|
CHAR,
|
||||||
|
SHORT,
|
||||||
|
INT,
|
||||||
|
LONG,
|
||||||
|
LLONG
|
||||||
|
} int_length = INT;
|
||||||
|
|
||||||
|
if (*fmt == 'l') {
|
||||||
|
fmt++;
|
||||||
|
|
||||||
|
if (*fmt == 'l') {
|
||||||
|
int_length = LLONG;
|
||||||
|
fmt++;
|
||||||
|
} else {
|
||||||
|
int_length = LONG;
|
||||||
|
}
|
||||||
|
} else if (*fmt == 'h') {
|
||||||
|
fmt++;
|
||||||
|
|
||||||
|
if (*fmt == 'h') {
|
||||||
|
int_length = CHAR;
|
||||||
|
fmt++;
|
||||||
|
} else {
|
||||||
|
int_length = SHORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_CHAR_TYPE ch = *fmt++;
|
||||||
|
switch (ch) {
|
||||||
|
case 's': {
|
||||||
|
const FMT_CHAR_TYPE *str = va_arg(args, FMT_CHAR_TYPE*);
|
||||||
|
size_t len = FMT_STRLEN_S(str, precision ? precision : SIZE_MAX);
|
||||||
|
|
||||||
|
out(ctx, len, str);
|
||||||
|
full_length += len;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
case 'o':
|
||||||
|
case 'i':
|
||||||
|
case 'u':
|
||||||
|
case 'd':
|
||||||
|
case 'x':
|
||||||
|
case 'X': {
|
||||||
|
int base = 10;
|
||||||
|
switch (ch) {
|
||||||
|
case 'X': case 'x': base = 16; break;
|
||||||
|
case 'o': base = 8; break;
|
||||||
|
case 'b': base = 2; break;
|
||||||
|
default: base = 10; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* characters = "0123456789abcdef";
|
||||||
|
if (ch == 'X') characters = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
uintmax_t i;
|
||||||
|
if (ch == 'd' || ch == 'i') {
|
||||||
|
intmax_t num = 0;
|
||||||
|
switch (int_length) {
|
||||||
|
case CHAR: num = (char) va_arg(args, int); break;
|
||||||
|
case SHORT: num = (short) va_arg(args, int); break;
|
||||||
|
case INT: num = va_arg(args, int); break;
|
||||||
|
case LONG: num = va_arg(args, long); break;
|
||||||
|
case LLONG: num = va_arg(args, long long); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num < 0) {
|
||||||
|
out(ctx, 1, "-");
|
||||||
|
i = -num;
|
||||||
|
full_length += 1;
|
||||||
|
} else {
|
||||||
|
i = num;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (int_length) {
|
||||||
|
case CHAR: i = (char) va_arg(args, int); break;
|
||||||
|
case SHORT: i = (short) va_arg(args, int); break;
|
||||||
|
case INT: i = va_arg(args, int); break;
|
||||||
|
case LONG: i = va_arg(args, long); break;
|
||||||
|
case LLONG: i = va_arg(args, long long); break;
|
||||||
|
default: i = 0; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
out(ctx, 1, "0");
|
||||||
|
full_length += 1;
|
||||||
|
} else {
|
||||||
|
FMT_CHAR_TYPE buffer[20];
|
||||||
|
size_t len = sizeof(buffer);
|
||||||
|
|
||||||
|
// we build the number in reverse
|
||||||
|
while (i != 0) {
|
||||||
|
buffer[--len] = characters[i % base];
|
||||||
|
i /= base;
|
||||||
|
}
|
||||||
|
|
||||||
|
out(ctx, sizeof(buffer) - (len * sizeof(FMT_CHAR_TYPE)), buffer + len);
|
||||||
|
full_length += (sizeof(buffer) - len);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return full_length;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
// Even if the user doesn't enable LIB_EXT1 we still have it existing
|
||||||
|
size_t strnlen_s(const char *s, size_t maxsize);
|
||||||
|
|
||||||
|
typedef void(*OutputFunc)(void* ctx, size_t n, const char str[]);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
// Instantiate formatted print functions
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
// TODO: instantiate wide char variants of print
|
||||||
|
#define FMT_FUNC_NAME fmt_print_char
|
||||||
|
#define FMT_CHAR_TYPE char
|
||||||
|
#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;
|
||||||
|
} StrPrintCtx;
|
||||||
|
|
||||||
|
FILE *stdout, *stderr, *stdin;
|
||||||
|
|
||||||
|
#define CALL_PRINTF(fmt_func, ctx, out, fmt) \
|
||||||
|
va_list args; \
|
||||||
|
va_start(args, fmt); \
|
||||||
|
int result = fmt_func(ctx, out, fmt, args); \
|
||||||
|
va_end(args)
|
||||||
|
|
||||||
|
static void string_write(void *ctx, size_t n, const char *restrict str) {
|
||||||
|
StrPrintCtx *c = ctx;
|
||||||
|
memcpy(c->string + c->used, str, n);
|
||||||
|
c->used += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fprintf(FILE *file, const char *restrict fmt, ...) {
|
||||||
|
CALL_PRINTF(fmt_print_char, file, file_write, fmt);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int printf(const char *restrict fmt, ...) {
|
||||||
|
CALL_PRINTF(fmt_print_char, stdout, file_write, fmt);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...) {
|
||||||
|
StrPrintCtx ctx = { 0, n, s };
|
||||||
|
CALL_PRINTF(fmt_print_char, &ctx, string_write, fmt);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sprintf(char *restrict s, const char *restrict fmt, ...) {
|
||||||
|
StrPrintCtx ctx = { 0, SIZE_MAX, s };
|
||||||
|
CALL_PRINTF(fmt_print_char, &ctx, string_write, fmt);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vfprintf(FILE *file, const char *restrict fmt, va_list args) {
|
||||||
|
return fmt_print_char(file, file_write, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
int vprintf(const char *restrict fmt, va_list args) {
|
||||||
|
return fmt_print_char(stdout, file_write, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list args) {
|
||||||
|
StrPrintCtx ctx = { 0, n, s };
|
||||||
|
return fmt_print_char(&ctx, string_write, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
int vsprintf(char *restrict s, const char *restrict fmt, va_list args) {
|
||||||
|
StrPrintCtx ctx = { 0, SIZE_MAX, s };
|
||||||
|
return fmt_print_char(&ctx, string_write, fmt, args);
|
||||||
|
}
|
|
@ -49,6 +49,8 @@ size_t strlen(const char *s) {
|
||||||
|
|
||||||
// __STDC_WANT_LIB_EXT1__
|
// __STDC_WANT_LIB_EXT1__
|
||||||
size_t strnlen_s(const char *s, size_t maxsize) {
|
size_t strnlen_s(const char *s, size_t maxsize) {
|
||||||
|
if (s == NULL) return 0;
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (s[i] && i < maxsize) {
|
while (s[i] && i < maxsize) {
|
||||||
i++;
|
i++;
|
||||||
|
|
19
inc/stdio.h
19
inc/stdio.h
|
@ -14,9 +14,9 @@ typedef int64_t fpos_t;
|
||||||
#define FOPEN_MAX 20
|
#define FOPEN_MAX 20
|
||||||
|
|
||||||
#ifdef _os_win
|
#ifdef _os_win
|
||||||
#define FILENAME_MAX 260
|
#define FILENAME_MAX 260
|
||||||
#else
|
#else
|
||||||
#define FILENAME_MAX 4096
|
#define FILENAME_MAX 4096
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define L_tmpnam FILENAME_MAX
|
#define L_tmpnam FILENAME_MAX
|
||||||
|
@ -27,10 +27,7 @@ typedef int64_t fpos_t;
|
||||||
|
|
||||||
#define TMP_MAX INT_MAX
|
#define TMP_MAX INT_MAX
|
||||||
|
|
||||||
// TODO: complete these, they don't need to be macros btw, could be external globals
|
extern FILE *stdout, *stderr, *stdin;
|
||||||
#define stderr ((FILE*)NULL)
|
|
||||||
#define stdin ((FILE*)NULL)
|
|
||||||
#define stdout ((FILE*)NULL)
|
|
||||||
|
|
||||||
int remove(const char *filename);
|
int remove(const char *filename);
|
||||||
int rename(const char *oldname, const char *newname);
|
int rename(const char *oldname, const char *newname);
|
||||||
|
@ -79,9 +76,9 @@ int ferror(FILE *stream);
|
||||||
void perror(const char *s);
|
void perror(const char *s);
|
||||||
|
|
||||||
#ifdef __STDC_WANT_LIB_EXT1__
|
#ifdef __STDC_WANT_LIB_EXT1__
|
||||||
#define L_tmpnam_s L_tmpnam
|
#define L_tmpnam_s L_tmpnam
|
||||||
#define TMP_MAX_S TMP_MAX
|
#define TMP_MAX_S TMP_MAX
|
||||||
|
|
||||||
errno_t tmpfile_s(FILE * restrict * restrict streamptr);
|
errno_t tmpfile_s(FILE * restrict * restrict streamptr);
|
||||||
errno_t tmpnam_s(char *s, rsize_t maxsize);
|
errno_t tmpnam_s(char *s, rsize_t maxsize);
|
||||||
#endif
|
#endif
|
||||||
|
|
60
inc/wchar.h
60
inc/wchar.h
|
@ -8,7 +8,7 @@ typedef wchar_t wint_t;
|
||||||
#define WCHAR_MAX 0xffff
|
#define WCHAR_MAX 0xffff
|
||||||
|
|
||||||
#ifndef WEOF
|
#ifndef WEOF
|
||||||
#define WEOF 0
|
#define WEOF 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int fwprintf(FILE * restrict stream, const wchar_t * restrict format, ...);
|
int fwprintf(FILE * restrict stream, const wchar_t * restrict format, ...);
|
||||||
|
@ -26,8 +26,7 @@ int wscanf(const wchar_t * restrict format, ...);
|
||||||
wint_t fgetwc(FILE *stream);
|
wint_t fgetwc(FILE *stream);
|
||||||
wchar_t *fgetws(wchar_t * restrict s, int n, FILE * restrict stream);
|
wchar_t *fgetws(wchar_t * restrict s, int n, FILE * restrict stream);
|
||||||
wint_t fputwc(wchar_t c, FILE *stream);
|
wint_t fputwc(wchar_t c, FILE *stream);
|
||||||
int fputws(const wchar_t * restrict s,
|
int fputws(const wchar_t * restrict s, FILE * restrict stream);
|
||||||
FILE * restrict stream);
|
|
||||||
int fwide(FILE *stream, int mode);
|
int fwide(FILE *stream, int mode);
|
||||||
wint_t getwc(FILE *stream);
|
wint_t getwc(FILE *stream);
|
||||||
wint_t getwchar(void);
|
wint_t getwchar(void);
|
||||||
|
@ -73,32 +72,29 @@ size_t mbsrtowcs(wchar_t * restrict dst, const char ** restrict src, size_t len,
|
||||||
size_t wcsrtombs(char * restrict dst, const wchar_t ** restrict src, size_t len, mbstate_t * restrict ps);
|
size_t wcsrtombs(char * restrict dst, const wchar_t ** restrict src, size_t len, mbstate_t * restrict ps);
|
||||||
|
|
||||||
#ifdef __STDC_WANT_LIB_EXT1__
|
#ifdef __STDC_WANT_LIB_EXT1__
|
||||||
int fwprintf_s(FILE * restrict stream, const wchar_t * restrict format, ...);
|
int fwprintf_s(FILE * restrict stream, const wchar_t * restrict format, ...);
|
||||||
int fwscanf_s(FILE * restrict stream, const wchar_t * restrict format, ...);
|
int fwscanf_s(FILE * restrict stream, const wchar_t * restrict format, ...);
|
||||||
int snwprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, ...);
|
int snwprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, ...);
|
||||||
int swprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, ...);
|
int swprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, ...);
|
||||||
int swscanf_s(const wchar_t * restrict s, const wchar_t * restrict format, ...);
|
int swscanf_s(const wchar_t * restrict s, const wchar_t * restrict format, ...);
|
||||||
int vfwprintf_s(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
|
int vfwprintf_s(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
|
||||||
int vfwscanf_s(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
|
int vfwscanf_s(FILE * restrict stream, const wchar_t * restrict format, va_list arg);
|
||||||
int vsnwprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, va_list arg);
|
int vsnwprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, va_list arg);
|
||||||
int vswprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, va_list arg);
|
int vswprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, va_list arg);
|
||||||
int vswscanf_s(const wchar_t * restrict s, const wchar_t * restrict format, va_list arg);
|
int vswscanf_s(const wchar_t * restrict s, const wchar_t * restrict format, va_list arg);
|
||||||
int vwprintf_s(const wchar_t * restrict format, va_list arg);
|
int vwprintf_s(const wchar_t * restrict format, va_list arg);
|
||||||
int vwscanf_s(const wchar_t * restrict format, va_list arg);
|
int vwscanf_s(const wchar_t * restrict format, va_list arg);
|
||||||
int wprintf_s(const wchar_t * restrict format, ...);
|
int wprintf_s(const wchar_t * restrict format, ...);
|
||||||
int wscanf_s(const wchar_t * restrict format, ...);
|
int wscanf_s(const wchar_t * restrict format, ...);
|
||||||
errno_t wcscpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2);
|
errno_t wcscpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2);
|
||||||
errno_t wcsncpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n);
|
errno_t wcsncpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n);
|
||||||
errno_t wmemcpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n);
|
errno_t wmemcpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n);
|
||||||
errno_t wmemmove_s(wchar_t *s1, rsize_t s1max, const wchar_t *s2, rsize_t n);
|
errno_t wmemmove_s(wchar_t *s1, rsize_t s1max, const wchar_t *s2, rsize_t n);
|
||||||
errno_t wcscat_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2);
|
errno_t wcscat_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2);
|
||||||
errno_t wcsncat_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n);
|
errno_t wcsncat_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n);
|
||||||
wchar_t *wcstok_s(wchar_t * restrict s1, rsize_t * restrict s1max,
|
wchar_t *wcstok_s(wchar_t * restrict s1, rsize_t * restrict s1max, const wchar_t * restrict s2, wchar_t ** restrict ptr);
|
||||||
const wchar_t * restrict s2, wchar_t ** restrict ptr);
|
size_t wcsnlen_s(const wchar_t *s, size_t maxsize);
|
||||||
size_t wcsnlen_s(const wchar_t *s, size_t maxsize);
|
errno_t wcrtomb_s(size_t * restrict retval, char * restrict s, rsize_t smax, wchar_t wc, mbstate_t * restrict ps);
|
||||||
errno_t wcrtomb_s(size_t * restrict retval,
|
errno_t mbsrtowcs_s(size_t * restrict retval, wchar_t * restrict dst, rsize_t dstmax, const char ** restrict src, rsize_t len, mbstate_t * restrict ps);
|
||||||
char * restrict s, rsize_t smax,
|
errno_t wcsrtombs_s(size_t * restrict retval, char * restrict dst, rsize_t dstmax, const wchar_t ** restrict src, rsize_t len, mbstate_t * restrict ps);
|
||||||
wchar_t wc, mbstate_t * restrict ps);
|
#endif
|
||||||
errno_t mbsrtowcs_s(size_t * restrict retval, wchar_t * restrict dst, rsize_t dstmax, const char ** restrict src, rsize_t len, mbstate_t * restrict ps);
|
|
||||||
errno_t wcsrtombs_s(size_t * restrict retval, char * restrict dst, rsize_t dstmax, const wchar_t ** restrict src, rsize_t len, mbstate_t * restrict ps);
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "win32.h"
|
#include "win32.h"
|
||||||
|
|
||||||
|
@ -58,6 +59,12 @@ void mainCRTStartup() {
|
||||||
convert_wide_chars_to_ansi(args[i], args_wide[i], wide_len);
|
convert_wide_chars_to_ansi(args[i], args_wide[i], wide_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize terminal
|
||||||
|
stdout = (FILE*) GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
stderr = (FILE*) GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
stdin = (FILE*) GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
|
||||||
|
// Initialize heap
|
||||||
_os_heap heap_data = {
|
_os_heap heap_data = {
|
||||||
.handle = heap,
|
.handle = heap,
|
||||||
};
|
};
|
||||||
|
|
10
test/test.c
10
test/test.c
|
@ -1,10 +1,14 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
/*for (int i = 0; i < argv; i++) {
|
for (int i = 0; i < argc; i++) {
|
||||||
printf("[%d] = %s\n", argv[i]);
|
printf("[%d] = %s\n", i, argv[i]);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
printf("%d\n", 583875381);
|
||||||
|
printf("%.*s", (int)3, "Hello");
|
||||||
|
|
||||||
for (char c = 'a'; c != 'z'; ++c) {
|
for (char c = 'a'; c != 'z'; ++c) {
|
||||||
assert(isupper(toupper(c)));
|
assert(isupper(toupper(c)));
|
||||||
|
|
Loading…
Reference in New Issue