added print
This commit is contained in:
@@ -1,29 +1,33 @@
|
||||
@echo off
|
||||
pushd %~dp0
|
||||
|
||||
set exeName=main.exe
|
||||
set binDir=bin
|
||||
set EXE_RAW=test
|
||||
set BINDIR_RAW=bin
|
||||
set SRC=test.cpp
|
||||
|
||||
mkdir %bindir%
|
||||
pushd %bindir%
|
||||
set EXE_WIN=%EXE_RAW%.exe
|
||||
set EXE_LINUX=%EXE_RAW%
|
||||
set BINDIR_WIN=.\%BINDIR_RAW%
|
||||
set BINDIR_LINUX=./%BINDIR_RAW%
|
||||
|
||||
cl^
|
||||
../test.cpp^
|
||||
/Fe%exeName% /MP /openmp /W3 /std:c++latest^
|
||||
/nologo /EHsc /Z7^
|
||||
/link /incremental
|
||||
|
||||
if %errorlevel% == 0 (
|
||||
echo.
|
||||
if not exist ..\%binDir% mkdir ..\%binDir%
|
||||
move %exeName% ..\%binDir%\ > NUL
|
||||
echo ---------- Output start ----------
|
||||
%exeName%
|
||||
echo ---------- Output end ----------
|
||||
popd
|
||||
) else (
|
||||
echo.
|
||||
echo Fucki'n 'ell
|
||||
)
|
||||
echo clang:
|
||||
clang %SRC% -o %BINDIR_WIN%\clang_%EXE_WIN%
|
||||
%BINDIR_WIN%\clang_%EXE_WIN%
|
||||
|
||||
popd
|
||||
echo.
|
||||
echo g++:
|
||||
g++ %SRC% -o %BINDIR_WIN%\g++_%EXE_WIN%
|
||||
%BINDIR_WIN%\g++_%EXE_WIN%
|
||||
|
||||
echo.
|
||||
echo cl:
|
||||
cl %SRC% /nologo /Zi /Fd: %BINDIR_WIN%\cl_%EXE_WIN%.pdb /Fo: %BINDIR_WIN%\ /Fe: %BINDIR_WIN%\cl_%EXE_WIN% /wd4090
|
||||
%BINDIR_WIN%\cl_%EXE_WIN%
|
||||
|
||||
echo.
|
||||
echo bash_clang:
|
||||
bash -c "clang -std=c++11 %SRC% -o %BINDIR_LINUX%/bash_clang_%EXE_LINUX% && %BINDIR_LINUX%/bash_clang_%EXE_LINUX%"
|
||||
|
||||
echo.
|
||||
echo bash_g++:
|
||||
bash -c "g++ -std=c++11 %SRC% -o %BINDIR_LINUX%/bash_g++_%EXE_LINUX% && %BINDIR_LINUX%/bash_g++_%EXE_LINUX%"
|
||||
|
||||
+30
-2
@@ -6,6 +6,29 @@
|
||||
#include "types.hpp"
|
||||
#include "arraylist.hpp"
|
||||
|
||||
|
||||
u32 hm_hash(char* str) {
|
||||
u32 value = str[0] << 7;
|
||||
s32 i = 0;
|
||||
while (str[i]) {
|
||||
value = (10000003 * value) ^ str[i++];
|
||||
}
|
||||
return value ^ i;
|
||||
}
|
||||
|
||||
u32 hm_hash(void* ptr) {
|
||||
return ((u64)ptr * 2654435761) % 4294967296;
|
||||
}
|
||||
|
||||
inline bool hm_objects_match(char* a, char* b) {
|
||||
return strcmp(a, b) == 0;
|
||||
}
|
||||
|
||||
inline bool hm_objects_match(void* a, void* b) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
|
||||
#define for_hash_map(hm) \
|
||||
if (decltype((hm).data[0].original) key = 0); else \
|
||||
if (decltype((hm).data[0].object) value = 0); else \
|
||||
@@ -103,14 +126,19 @@ struct Hash_Map {
|
||||
return ret;
|
||||
}
|
||||
|
||||
value_type get_object(key_type key) {
|
||||
s32 index = get_index_of_living_cell_if_it_exists(key, hm_hash((key_type)key));
|
||||
value_type get_object(key_type key, u64 hash_val) {
|
||||
s32 index = get_index_of_living_cell_if_it_exists(key, hash_val);
|
||||
if (index != -1) {
|
||||
return data[index].object;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
value_type get_object(key_type key) {
|
||||
return get_object(key, hm_hash((key_type)key));
|
||||
}
|
||||
|
||||
|
||||
void delete_object(key_type key) {
|
||||
s32 index = get_index_of_living_cell_if_it_exists(key, hm_hash((key_type)key));
|
||||
if (index != -1) {
|
||||
|
||||
@@ -0,0 +1,398 @@
|
||||
#pragma once
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hashmap.hpp"
|
||||
|
||||
#define str_eq(s1, s2) (strcmp(s1, s2) == 0)
|
||||
|
||||
typedef const char* static_string;
|
||||
typedef int (*printer_function_32b)(FILE*, u32);
|
||||
typedef int (*printer_function_64b)(FILE*, u64);
|
||||
typedef int (*printer_function_flt)(FILE*, double);
|
||||
typedef int (*printer_function_ptr)(FILE*, void*);
|
||||
typedef int (*printer_function_void)(FILE*);
|
||||
|
||||
enum struct Printer_Function_Type {
|
||||
unknown,
|
||||
_32b,
|
||||
_64b,
|
||||
_flt,
|
||||
_ptr,
|
||||
_void
|
||||
};
|
||||
|
||||
Hash_Map<char*, printer_function_32b> printer_map = {0};
|
||||
Hash_Map<char*, int> type_map = {0};
|
||||
|
||||
#define register_printer(spec, fun, type) \
|
||||
register_printer_32(spec, (printer_function_32b)fun, type)
|
||||
|
||||
void register_printer_32(const char* spec, printer_function_32b fun, Printer_Function_Type type) {
|
||||
printer_map.set_object((char*)spec, fun);
|
||||
type_map.set_object((char*)spec, (int)type);
|
||||
}
|
||||
|
||||
int maybe_special_print(FILE* file, static_string format, int* pos, va_list* arg_list) {
|
||||
if(format[*pos] != '{')
|
||||
return 0;
|
||||
|
||||
int end_pos = (*pos)+1;
|
||||
while (format[end_pos] != '}' &&
|
||||
format[end_pos] != ',' &&
|
||||
format[end_pos] != '[' &&
|
||||
format[end_pos] != 0)
|
||||
++end_pos;
|
||||
|
||||
if (format[end_pos] == 0)
|
||||
return 0;
|
||||
|
||||
char* spec = (char*)malloc(end_pos - (*pos));
|
||||
strncpy(spec, format+(*pos)+1, end_pos - (*pos));
|
||||
spec[end_pos - (*pos)-1] = '\0';
|
||||
|
||||
u64 spec_hash = hm_hash(spec);
|
||||
Printer_Function_Type type = (Printer_Function_Type)type_map.get_object(spec, spec_hash);
|
||||
|
||||
|
||||
union {
|
||||
printer_function_32b printer_32b;
|
||||
printer_function_64b printer_64b;
|
||||
printer_function_ptr printer_ptr;
|
||||
printer_function_flt printer_flt;
|
||||
printer_function_void printer_void;
|
||||
} printer;
|
||||
|
||||
// just grab it, it will have the correct type
|
||||
printer.printer_32b = printer_map.get_object(spec, spec_hash);
|
||||
|
||||
free(spec);
|
||||
|
||||
if (type == Printer_Function_Type::unknown) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (format[end_pos] == ',') {
|
||||
int element_count;
|
||||
|
||||
++end_pos;
|
||||
sscanf(format+end_pos, "%d", &element_count);
|
||||
|
||||
while (format[end_pos] != '}' &&
|
||||
format[end_pos] != 0)
|
||||
++end_pos;
|
||||
if (format[end_pos] == 0)
|
||||
return 0;
|
||||
|
||||
// both brackets already included:
|
||||
int written_length = 2;
|
||||
|
||||
fputs("[", file);
|
||||
for (int i = 0; i < element_count - 1; ++i) {
|
||||
if (type == Printer_Function_Type::_32b) written_length += printer.printer_32b(file, va_arg(*arg_list, u32));
|
||||
else if (type == Printer_Function_Type::_64b) written_length += printer.printer_64b(file, va_arg(*arg_list, u64));
|
||||
else if (type == Printer_Function_Type::_flt) written_length += printer.printer_flt(file, va_arg(*arg_list, double));
|
||||
else if (type == Printer_Function_Type::_ptr) written_length += printer.printer_ptr(file, va_arg(*arg_list, void*));
|
||||
else written_length += printer.printer_void(file);
|
||||
written_length += 2;
|
||||
fputs(", ", file);
|
||||
}
|
||||
if (element_count > 0) {
|
||||
if (type == Printer_Function_Type::_32b) written_length += printer.printer_32b(file, va_arg(*arg_list, u32));
|
||||
else if (type == Printer_Function_Type::_64b) written_length += printer.printer_64b(file, va_arg(*arg_list, u64));
|
||||
else if (type == Printer_Function_Type::_flt) written_length += printer.printer_flt(file, va_arg(*arg_list, double));
|
||||
else if (type == Printer_Function_Type::_ptr) written_length += printer.printer_ptr(file, va_arg(*arg_list, void*));
|
||||
else written_length += printer.printer_void(file);
|
||||
}
|
||||
fputs("]", file);
|
||||
|
||||
*pos = end_pos;
|
||||
return written_length;
|
||||
} else if (format[end_pos] == '[') {
|
||||
end_pos++;
|
||||
u32 element_count;
|
||||
union {
|
||||
u32* arr_32b;
|
||||
u64* arr_64b;
|
||||
f32* arr_flt;
|
||||
void** arr_ptr;
|
||||
} arr;
|
||||
|
||||
if (type == Printer_Function_Type::_32b) arr.arr_32b = va_arg(*arg_list, u32*);
|
||||
else if (type == Printer_Function_Type::_64b) arr.arr_64b = va_arg(*arg_list, u64*);
|
||||
else if (type == Printer_Function_Type::_flt) arr.arr_flt = va_arg(*arg_list, f32*);
|
||||
else arr.arr_ptr = va_arg(*arg_list, void**);
|
||||
|
||||
if (format[end_pos] == '*') {
|
||||
element_count = va_arg(*arg_list, u32);
|
||||
} else {
|
||||
sscanf(format+end_pos, "%d", &element_count);
|
||||
}
|
||||
|
||||
// skip to next ']'
|
||||
while (format[end_pos] != ']' &&
|
||||
format[end_pos] != 0)
|
||||
++end_pos;
|
||||
if (format[end_pos] == 0)
|
||||
return 0;
|
||||
|
||||
// skip to next '}'
|
||||
while (format[end_pos] != '}' &&
|
||||
format[end_pos] != 0)
|
||||
++end_pos;
|
||||
if (format[end_pos] == 0)
|
||||
return 0;
|
||||
|
||||
// both brackets already included:
|
||||
int written_length = 2;
|
||||
|
||||
fputs("[", file);
|
||||
for (u32 i = 0; i < element_count - 1; ++i) {
|
||||
if (type == Printer_Function_Type::_32b) written_length += printer.printer_32b(file, arr.arr_32b[i]);
|
||||
else if (type == Printer_Function_Type::_64b) written_length += printer.printer_64b(file, arr.arr_64b[i]);
|
||||
else if (type == Printer_Function_Type::_flt) written_length += printer.printer_flt(file, arr.arr_flt[i]);
|
||||
else if (type == Printer_Function_Type::_ptr) written_length += printer.printer_ptr(file, arr.arr_ptr[i]);
|
||||
else written_length += printer.printer_void(file);
|
||||
written_length += 2;
|
||||
fputs(", ", file);
|
||||
}
|
||||
if (element_count > 0) {
|
||||
if (type == Printer_Function_Type::_32b) written_length += printer.printer_32b(file, arr.arr_32b[element_count - 1]);
|
||||
else if (type == Printer_Function_Type::_64b) written_length += printer.printer_64b(file, arr.arr_64b[element_count - 1]);
|
||||
else if (type == Printer_Function_Type::_flt) written_length += printer.printer_flt(file, arr.arr_flt[element_count - 1]);
|
||||
else if (type == Printer_Function_Type::_ptr) written_length += printer.printer_ptr(file, arr.arr_ptr[element_count - 1]);
|
||||
else written_length += printer.printer_void(file);
|
||||
}
|
||||
fputs("]", file);
|
||||
|
||||
*pos = end_pos;
|
||||
return written_length;
|
||||
} else {
|
||||
*pos = end_pos;
|
||||
if (type == Printer_Function_Type::_32b) return printer.printer_32b(file, va_arg(*arg_list, u32));
|
||||
else if (type == Printer_Function_Type::_64b) return printer.printer_64b(file, va_arg(*arg_list, u64));
|
||||
else if (type == Printer_Function_Type::_flt) return printer.printer_flt(file, va_arg(*arg_list, double));
|
||||
else if (type == Printer_Function_Type::_ptr) return printer.printer_ptr(file, va_arg(*arg_list, void*));
|
||||
else return printer.printer_void(file);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int maybe_fprintf(FILE* file, static_string format, int* pos, va_list* arg_list) {
|
||||
// %[flags][width][.precision][length]specifier
|
||||
// flags ::= [+- #0]
|
||||
// width ::= [<number>+ \*]
|
||||
// precision ::= \.[<number>+ \*]
|
||||
// length ::= [h l L]
|
||||
// specifier ::= [c d i e E f g G o s u x X p n %]
|
||||
int end_pos = *pos;
|
||||
int writen_len = 0;
|
||||
int used_arg_values = 1;
|
||||
|
||||
// overstep flags:
|
||||
while(format[end_pos] == '+' ||
|
||||
format[end_pos] == '-' ||
|
||||
format[end_pos] == ' ' ||
|
||||
format[end_pos] == '#' ||
|
||||
format[end_pos] == '0')
|
||||
++end_pos;
|
||||
|
||||
// overstep width
|
||||
if (format[end_pos] == '*') {
|
||||
++used_arg_values;
|
||||
++end_pos;
|
||||
}
|
||||
else {
|
||||
while(format[end_pos] >= '0' && format[end_pos] <= '9')
|
||||
++end_pos;
|
||||
}
|
||||
|
||||
// overstep precision
|
||||
if (format[end_pos] == '.') {
|
||||
++end_pos;
|
||||
if (format[end_pos] == '*') {
|
||||
++used_arg_values;
|
||||
++end_pos;
|
||||
}
|
||||
else {
|
||||
while(format[end_pos] >= '0' && format[end_pos] <= '9')
|
||||
++end_pos;
|
||||
}
|
||||
}
|
||||
|
||||
// overstep length:
|
||||
while(format[end_pos] == 'h' ||
|
||||
format[end_pos] == 'l' ||
|
||||
format[end_pos] == 'L')
|
||||
++end_pos;
|
||||
|
||||
// check for actual built_in specifier
|
||||
if(format[end_pos] == 'c' ||
|
||||
format[end_pos] == 'd' ||
|
||||
format[end_pos] == 'i' ||
|
||||
format[end_pos] == 'e' ||
|
||||
format[end_pos] == 'E' ||
|
||||
format[end_pos] == 'f' ||
|
||||
format[end_pos] == 'g' ||
|
||||
format[end_pos] == 'G' ||
|
||||
format[end_pos] == 'o' ||
|
||||
format[end_pos] == 's' ||
|
||||
format[end_pos] == 'u' ||
|
||||
format[end_pos] == 'x' ||
|
||||
format[end_pos] == 'X' ||
|
||||
format[end_pos] == 'p' ||
|
||||
format[end_pos] == 'n' ||
|
||||
format[end_pos] == '%')
|
||||
{
|
||||
writen_len = end_pos - *pos + 2;
|
||||
char* temp = (char*)malloc((writen_len+1)* sizeof(char));
|
||||
temp[0] = '%';
|
||||
temp[1] = 0;
|
||||
strncpy(temp+1, format+*pos, writen_len);
|
||||
temp[writen_len] = 0;
|
||||
|
||||
// printf("\ntest:: len(%s) = %d\n", temp, writen_len+1);
|
||||
|
||||
writen_len = vfprintf(file, temp, *arg_list);
|
||||
|
||||
// NOTE(Felix): For WSL Linux we have to manually overstep the
|
||||
// used args
|
||||
for (int i = 0; i < used_arg_values; ++i) {
|
||||
va_arg(*arg_list, void*);
|
||||
}
|
||||
|
||||
free(temp);
|
||||
*pos = end_pos;
|
||||
}
|
||||
|
||||
return writen_len;
|
||||
}
|
||||
|
||||
|
||||
int vafprint(FILE* file, static_string format, va_list* arg_list) {
|
||||
int printed_chars = 0;
|
||||
|
||||
char c;
|
||||
int pos = -1;
|
||||
while ((c = format[++pos])) {
|
||||
if (c != '%') {
|
||||
putc(c, file);
|
||||
++printed_chars;
|
||||
} else {
|
||||
c = format[++pos];
|
||||
int move = maybe_special_print(file, format, &pos, arg_list);
|
||||
if (move == 0) {
|
||||
move = maybe_fprintf(file, format, &pos, arg_list);
|
||||
if (move == 0) {
|
||||
putchar('%');
|
||||
putchar(c);
|
||||
move = 1;
|
||||
}
|
||||
}
|
||||
printed_chars += move;
|
||||
}
|
||||
}
|
||||
|
||||
return printed_chars;
|
||||
}
|
||||
|
||||
int print_to_string(char** out, static_string format, ...) {
|
||||
va_list arg_list;
|
||||
va_start(arg_list, format);
|
||||
|
||||
FILE* t_file = tmpfile();
|
||||
if (!t_file) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int num_printed_chars = vafprint(t_file, format, &arg_list);
|
||||
va_end(arg_list);
|
||||
|
||||
|
||||
*out = (char*)malloc(sizeof(char) * (num_printed_chars+1));
|
||||
|
||||
rewind(t_file);
|
||||
size_t newLen = fread(*out, sizeof(char), num_printed_chars, t_file);
|
||||
(*out)[num_printed_chars] = '\0';
|
||||
|
||||
fclose(t_file);
|
||||
|
||||
return num_printed_chars;
|
||||
}
|
||||
|
||||
int print_to_file(FILE* file, static_string format, ...) {
|
||||
va_list arg_list;
|
||||
va_start(arg_list, format);
|
||||
|
||||
int num_printed_chars = vafprint(file, format, &arg_list);
|
||||
|
||||
va_end(arg_list);
|
||||
|
||||
return num_printed_chars;
|
||||
}
|
||||
|
||||
int print(static_string format, ...) {
|
||||
va_list arg_list;
|
||||
va_start(arg_list, format);
|
||||
|
||||
int num_printed_chars = vafprint(stdout, format, &arg_list);
|
||||
|
||||
va_end(arg_list);
|
||||
|
||||
return num_printed_chars;
|
||||
}
|
||||
|
||||
int print_bool(FILE* f, u32 val) {
|
||||
return print_to_file(f, val ? "true" : "false");
|
||||
}
|
||||
|
||||
int print_u32(FILE* f, u32 num) {
|
||||
return print_to_file(f, "%u", num);
|
||||
}
|
||||
|
||||
int print_u64(FILE* f, u64 num) {
|
||||
return print_to_file(f, "%llu", num);
|
||||
}
|
||||
|
||||
int print_s32(FILE* f, s32 num) {
|
||||
return print_to_file(f, "%d", num);
|
||||
}
|
||||
|
||||
int print_s64(FILE* f, s64 num) {
|
||||
return print_to_file(f, "%lld", num);
|
||||
}
|
||||
|
||||
int print_flt(FILE* f, double arg) {
|
||||
return print_to_file(f, "%f", arg);
|
||||
}
|
||||
|
||||
int print_str(FILE* f, char* str) {
|
||||
return print_to_file(f, "%s", str);
|
||||
}
|
||||
|
||||
int print_ptr(FILE* f, void* ptr) {
|
||||
if (ptr)
|
||||
return print_to_file(f, "%#0*X", sizeof(void*)*2+2, ptr);
|
||||
return print_to_file(f, "nullptr");
|
||||
}
|
||||
|
||||
void init_printer() {
|
||||
printer_map.alloc();
|
||||
type_map.alloc();
|
||||
|
||||
register_printer("u32", print_u32, Printer_Function_Type::_32b);
|
||||
register_printer("u64", print_u64, Printer_Function_Type::_64b);
|
||||
register_printer("bool", print_bool, Printer_Function_Type::_32b);
|
||||
register_printer("s64", print_s64, Printer_Function_Type::_64b);
|
||||
register_printer("s32", print_s32, Printer_Function_Type::_32b);
|
||||
register_printer("f32", print_flt, Printer_Function_Type::_flt);
|
||||
register_printer("f64", print_flt, Printer_Function_Type::_flt);
|
||||
register_printer("str", print_str, Printer_Function_Type::_ptr);
|
||||
register_printer("ptr", print_ptr, Printer_Function_Type::_ptr);
|
||||
}
|
||||
@@ -1,27 +1,46 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "./types.hpp"
|
||||
#include "./hooks.hpp"
|
||||
|
||||
Hook h;
|
||||
|
||||
#include "./print.hpp"
|
||||
|
||||
|
||||
int print_dots(FILE* f) {
|
||||
return print_to_file(f, "...");
|
||||
}
|
||||
|
||||
s32 main(s32 argc, char* argv[]) {
|
||||
printf("Hello world");
|
||||
// system_shutdown_hook << [] {
|
||||
// printf("Goodbye world\n");
|
||||
// };
|
||||
u32 arr[] = {1,2,3,4,1,1,3};
|
||||
f32 f_arr[] = {1.1,2.1,3.2};
|
||||
|
||||
h << []{
|
||||
printf("Hallo1");
|
||||
};
|
||||
h << [] {
|
||||
printf("Hallo2");
|
||||
};
|
||||
init_printer();
|
||||
register_printer("dots", print_dots, Printer_Function_Type::_void);
|
||||
|
||||
u32 u1 = -1;
|
||||
u64 u2 = -1;
|
||||
|
||||
char* str;
|
||||
print_to_string(&str, " - %{dots[5]} %{ptr} <> %{ptr,2}\n", &u1, &arr, nullptr);
|
||||
print("---> %{str}", str);
|
||||
|
||||
// print(" - %{dots[3]}\n");
|
||||
// print(" - %{u32} %{u64}\n", u1, u2);
|
||||
// print(" - %{u32} %{u32} %{u32}\n", 2, 5, 7);
|
||||
// print(" - %{f32} %{f32} %{f32}\n", 2.0, 5.0, 7.0);
|
||||
// print(" - %{u32} %{bool} %{str}\n", 2, true, "hello");
|
||||
// print(" - %{f32[3]}\n", f_arr);
|
||||
// print(" - %{f32,3}\n", 44.9, 55.1, 66.2);
|
||||
// print(" - %{u32[5]}\n", arr);
|
||||
// print(" - %{u32[*]}\n", arr, 4);
|
||||
// print(" - %{u32,5}\n", 1,2,3,4,1,2);
|
||||
// print(" - %{unknown%d}\n", 1);
|
||||
// print(" - %{s32,3}\n", -1,200,-300);
|
||||
// print(" - %{ptr} <> %{ptr,2}\n", &u1, &arr, nullptr);
|
||||
|
||||
h << [] {
|
||||
printf("Hallo3");
|
||||
};
|
||||
h();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user