Bläddra i källkod

added print

banana-cakes
FelixBrendel 6 år sedan
förälder
incheckning
fcc64d84a2
4 ändrade filer med 491 tillägg och 42 borttagningar
  1. +27
    -23
      build.bat
  2. +30
    -2
      hashmap.hpp
  3. +398
    -0
      print.hpp
  4. +36
    -17
      test.cpp

+ 27
- 23
build.bat Visa fil

@@ -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
echo.
echo clang:
clang %SRC% -o %BINDIR_WIN%\clang_%EXE_WIN%
%BINDIR_WIN%\clang_%EXE_WIN%

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.
echo g++:
g++ %SRC% -o %BINDIR_WIN%\g++_%EXE_WIN%
%BINDIR_WIN%\g++_%EXE_WIN%

popd
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
hashmap.hpp Visa fil

@@ -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) {


+ 398
- 0
print.hpp Visa fil

@@ -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);
}

+ 36
- 17
test.cpp Visa fil

@@ -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");
// };

h << []{
printf("Hallo1");
};
h << [] {
printf("Hallo2");
};

h << [] {
printf("Hallo3");
};
h();
u32 arr[] = {1,2,3,4,1,1,3};
f32 f_arr[] = {1.1,2.1,3.2};

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);


return 0;
}

Laddar…
Avbryt
Spara