diff --git a/arena_findings.txt b/arena_findings.txt deleted file mode 100644 index 10dcafd..0000000 --- a/arena_findings.txt +++ /dev/null @@ -1,36 +0,0 @@ -1. Avoid function pointer based overrides, prefer macro based overrides - Macros allow you to define one override per compilation context, but - that one override has better range, than the kinds of overrides you - can do with function pointers. You can always use macros to plug in - a dynamic dispatch system, but you can't use function pointers to - plug in high speed light weight systems. - [ This same idea should for thread contexts ] - -2. It's starting to seem like the header technique is the way to go. - It solves a couple of problems for the library, which won't know - the size of the arena struct when it is written. And there are good - enough bridge techniques for libraries that have non-header arenas, - to get up and running, and fixing the remaining issues or fully - transitioning to header technique shouldn't be too hard. - -3. It seems like it will be better to count on pre-briding at least - the types and default controls (before the header) so that we can - get type checking on various arena and array of arenas parameters. - [ This idea was less fully explored, it may still turn out to be - better to stick with post-bridging ]. - -[ ] Could there be an easy bridge from a malloc/free style allocator - in the codebase to an arena style in the library? - -[ ] Figure out the header technique problem: - Arena min position to implement clear? - Init instead of New, pass in memory for thread context? - -[ ] Test integrating two libraries into the same codebase - -[ ] Thread Context/Get Scratch cooperative mode - -[ ] What if only the slow path ever triggered a function call? - And we put everything in the common path into macros? - -[ ] MD_ArenaPushAlignDefault(arena->pos, arena->align, arena->cap); diff --git a/samples/node_errors/node_errors.c b/samples/node_errors/node_errors.c index 742733e..142b4da 100644 --- a/samples/node_errors/node_errors.c +++ b/samples/node_errors/node_errors.c @@ -1,5 +1,7 @@ // Sample code to demonstrate errors being reported for certain nodes. +#define MD_ENABLE_PRINT_HELPERS 1 + #include "md.h" #include "md.c" diff --git a/source/md.c b/source/md.c index 8d393f7..416f4c4 100644 --- a/source/md.c +++ b/source/md.c @@ -21,6 +21,41 @@ #endif +#if MD_DEFAULT_FILE_LOAD + +#include + +#if !defined(MD_IMPL_LoadEntireFile) +# define MD_IMPL_LoadEntireFile MD_CRT_LoadEntireFile +#endif + +MD_FUNCTION_IMPL MD_String8 +MD_CRT_LoadEntireFile(MD_Arena *arena, MD_String8 filename){ + MD_ArenaTemp scratch = MD_GetScratch(&arena, 1); + MD_String8 file_contents = MD_ZERO_STRUCT; + MD_String8 filename_copy = MD_S8Copy(scratch.arena, filename); + FILE *file = fopen((char*)filename_copy.str, "rb"); + if(file != 0) + { + fseek(file, 0, SEEK_END); + MD_u64 file_size = ftell(file); + fseek(file, 0, SEEK_SET); + file_contents.str = MD_PushArray(arena, MD_u8, file_size+1); + if(file_contents.str) + { + file_contents.size = file_size; + fread(file_contents.str, 1, file_size, file); + file_contents.str[file_contents.size] = 0; + } + fclose(file); + } + MD_ReleaseScratch(scratch); + return file_contents; +} + +#endif + + //~///////////////////////////////////////////////////////////////////////////// /////////////////////////// Win32 Implementation /////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -449,7 +484,6 @@ MD_GetScratchDefault(MD_Arena **conflicts, MD_u64 count){ //////////////////////// MD Library Implementation ///////////////////////////// //////////////////////////////////////////////////////////////////////////////// -#define MD_FUNCTION_IMPL MD_FUNCTION #define MD_UNTERMINATED_TOKEN_LEN_CAP 20 #define STB_SPRINTF_IMPLEMENTATION @@ -771,10 +805,9 @@ MD_S8FmtV(MD_Arena *arena, char *fmt, va_list args) MD_FUNCTION_IMPL MD_String8 MD_S8Fmt(MD_Arena *arena, char *fmt, ...) { - MD_String8 result = MD_ZERO_STRUCT; va_list args; va_start(args, fmt); - result = MD_S8FmtV(arena, fmt, args); + MD_String8 result = MD_S8FmtV(arena, fmt, args); va_end(args); return result; } @@ -790,6 +823,16 @@ MD_S8ListPush(MD_Arena *arena, MD_String8List *list, MD_String8 string) list->total_size += string.size; } +MD_FUNCTION_IMPL void +MD_S8ListPushFmt(MD_Arena *arena, MD_String8List *list, char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + MD_String8 string = MD_S8FmtV(arena, fmt, args); + va_end(args); + MD_S8ListPush(arena, list, string); +} + MD_FUNCTION_IMPL void MD_S8ListConcat(MD_String8List *list, MD_String8List *to_push) { @@ -2229,7 +2272,7 @@ MD_ParseNodeSet(MD_Arena *arena, MD_String8 string, MD_u64 offset, MD_Node *pare // NOTE(rjf): @error We didn't get a closer for the set MD_String8 error_str = MD_S8Fmt(arena, "Unbalanced \"%c\"", set_opener); MD_Message *error = MD_MakeTokenError(arena, string, initial_token, - MD_MessageKind_CatastrophicError, error_str); + MD_MessageKind_FatalError, error_str); MD_MessageListPush(&result.errors, error); } @@ -2381,7 +2424,7 @@ MD_ParseOneNode(MD_Arena *arena, MD_String8 string, MD_u64 offset) // NOTE(rjf): @error Unexpected set closing symbol MD_String8 error_str = MD_S8Fmt(arena, "Unbalanced \"%c\"", c); MD_Message *error = MD_MakeTokenError(arena, string, unnamed_set_opener, - MD_MessageKind_CatastrophicError, error_str); + MD_MessageKind_FatalError, error_str); MD_MessageListPush(&result.errors, error); off += unnamed_set_opener.raw_string.size; } @@ -2546,7 +2589,7 @@ MD_ParseWholeFile(MD_Arena *arena, MD_String8 filename) { // NOTE(rjf): @error File failing to load MD_String8 error_str = MD_S8Fmt(arena, "Could not read file \"%.*s\"", MD_S8VArg(filename)); - MD_Message *error = MD_MakeNodeError(arena, parse.node, MD_MessageKind_CatastrophicError, + MD_Message *error = MD_MakeNodeError(arena, parse.node, MD_MessageKind_FatalError, error_str); MD_MessageListPush(&parse.errors, error); } @@ -2803,53 +2846,64 @@ MD_NodeFromReference(MD_Node *node) //~ Error/Warning Helpers -MD_FUNCTION_IMPL void -MD_PrintMessage(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, MD_String8 str) -{ - const char *kind_name = ""; +MD_FUNCTION MD_String8 +MD_StringFromMessageKind(MD_MessageKind kind){ + MD_String8 result = MD_ZERO_STRUCT; switch (kind){ default: break; - case MD_MessageKind_Note: kind_name = "note: "; break; - case MD_MessageKind_Warning: kind_name = "warning: "; break; - case MD_MessageKind_Error: kind_name = "error: "; break; - case MD_MessageKind_CatastrophicError: kind_name = "fatal error: "; break; + case MD_MessageKind_Note: result = MD_S8Lit("note"); break; + case MD_MessageKind_Warning: result = MD_S8Lit("warning"); break; + case MD_MessageKind_Error: result = MD_S8Lit("error"); break; + case MD_MessageKind_FatalError: result = MD_S8Lit("fatal error"); break; } - fprintf(out, "%.*s:%i:%i: %s%.*s\n", - MD_S8VArg(loc.filename), loc.line, loc.column, - kind_name, MD_S8VArg(str)); + return(result); } -MD_FUNCTION_IMPL void -MD_PrintMessageFmt(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, char *fmt, ...) -{ +MD_FUNCTION MD_String8 +MD_FormatMessage(MD_Arena *arena, MD_CodeLoc loc, MD_MessageKind kind, MD_String8 string){ + MD_String8 kind_string = MD_StringFromMessageKind(kind); + MD_String8 result = MD_S8Fmt(arena, "" MD_FmtCodeLoc " %.*s: %.*s\n", + MD_CodeLocVArg(loc), MD_S8VArg(kind_string), MD_S8VArg(string)); + return(result); +} + +#if MD_ENABLE_PRINT_HELPERS + +MD_FUNCTION void +MD_PrintMessage(FILE *file, MD_CodeLoc code_loc, MD_MessageKind kind, MD_String8 string){ + MD_ArenaTemp scratch = MD_GetScratch(0, 0); + MD_String8 message = MD_FormatMessage(scratch.arena, code_loc, kind, string); + fwrite(message.str, message.size, 1, file); + MD_ReleaseScratch(scratch); +} + +MD_FUNCTION void +MD_PrintMessageFmt(FILE *file, MD_CodeLoc code_loc, MD_MessageKind kind, char *fmt, ...){ + MD_ArenaTemp scratch = MD_GetScratch(0, 0); va_list args; va_start(args, fmt); - MD_ArenaTemp scratch = MD_GetScratch(0, 0); MD_String8 string = MD_S8FmtV(scratch.arena, fmt, args); - MD_PrintMessage(out, loc, kind, string); - MD_ReleaseScratch(scratch); va_end(args); + MD_String8 message = MD_FormatMessage(scratch.arena, code_loc, kind, string); + fwrite(message.str, message.size, 1, file); + MD_ReleaseScratch(scratch); } -MD_FUNCTION_IMPL void -MD_PrintNodeMessage(FILE *out, MD_Node *node, MD_MessageKind kind, MD_String8 str) -{ - MD_CodeLoc loc = MD_CodeLocFromNode(node); - MD_PrintMessage(out, loc, kind, str); -} - -MD_FUNCTION_IMPL void -MD_PrintNodeMessageFmt(FILE *out, MD_Node *node, MD_MessageKind kind, char *fmt, ...) -{ +MD_FUNCTION void +MD_PrintNodeMessageFmt(FILE *file, MD_Node *node, MD_MessageKind kind, char *fmt, ...){ + MD_ArenaTemp scratch = MD_GetScratch(0, 0); va_list args; va_start(args, fmt); - MD_ArenaTemp scratch = MD_GetScratch(0, 0); MD_String8 string = MD_S8FmtV(scratch.arena, fmt, args); - MD_PrintNodeMessage(out, node, kind, string); - MD_ReleaseScratch(scratch); va_end(args); + MD_CodeLoc code_loc = MD_CodeLocFromNode(node); + MD_String8 message = MD_FormatMessage(scratch.arena, code_loc, kind, string); + fwrite(message.str, message.size, 1, file); + MD_ReleaseScratch(scratch); } +#endif + //~ Tree Comparison/Verification MD_FUNCTION_IMPL MD_b32 @@ -3467,23 +3521,11 @@ MD_CmdLineI64FromString(MD_CmdLine cmdln, MD_String8 name) MD_FUNCTION_IMPL MD_String8 MD_LoadEntireFile(MD_Arena *arena, MD_String8 filename) { - MD_String8 file_contents = MD_ZERO_STRUCT; - MD_String8 filename_copy = MD_S8Copy(arena, filename); - FILE *file = fopen((char*)filename_copy.str, "rb"); - if(file) - { - fseek(file, 0, SEEK_END); - MD_u64 file_size = ftell(file); - fseek(file, 0, SEEK_SET); - file_contents.str = MD_PushArray(arena, MD_u8, file_size+1); - if(file_contents.str) - { - file_contents.size = file_size; - fread(file_contents.str, 1, file_size, file); - } - fclose(file); - } - return file_contents; + MD_String8 result = MD_ZERO_STRUCT; +#if defined(MD_IMPL_LoadEntireFile) + result = MD_IMPL_LoadEntireFile(arena, filename); +#endif + return(result); } MD_FUNCTION_IMPL MD_b32 diff --git a/source/md.h b/source/md.h index 8c91b4b..a064a41 100644 --- a/source/md.h +++ b/source/md.h @@ -20,6 +20,9 @@ ** #define MD_IMPL_FileIterNext (MD_Arena*, MD_FileIter*) -> MD_FileInfo ** #define MD_IMPL_FileIterEnd (MD_FileIter*) -> void ** +** "file load" ** OPTIONAL +** #define MD_IMPL_LoadEntireFile (MD_Arena*, MD_String8 filename) -> MD_String8 +** ** "low level memory" ** OPTIONAL (required for default arena) ** #define MD_IMPL_Reserve (MD_u64) -> void* ** #define MD_IMPL_Commit (void*, MD_u64) -> void @@ -56,6 +59,9 @@ #if !defined(MD_DEFAULT_MEMSET) # define MD_DEFAULT_MEMSET 1 #endif +#if !defined(MD_DEFAULT_FILE_LOAD) +# define MD_DEFAULT_FILE_LOAD 1 +#endif #if !defined(MD_DEFAULT_FILE_ITER) # define MD_DEFAULT_FILE_ITER 1 #endif @@ -69,6 +75,10 @@ # define MD_DEFAULT_SCRATCH 1 #endif +#if !defined(MD_ENABLE_PRINT_HELPERS) +# define MD_ENABLE_PRINT_HELPERS 0 +#endif + // NOTE(rjf): Compiler cracking from the 4th dimension @@ -297,11 +307,14 @@ //~ Common defines -#define MD_FUNCTION +#if !defined(MD_FUNCTION) +# define MD_FUNCTION +#endif +#define MD_FUNCTION_IMPL MD_FUNCTION + #define MD_GLOBAL static #include -#include #include #define STB_SPRINTF_DECORATE(name) md_stbsp_##name #include "md_stb_sprintf.h" @@ -624,7 +637,7 @@ typedef enum MD_MessageKind MD_MessageKind_Note, MD_MessageKind_Warning, MD_MessageKind_Error, - MD_MessageKind_CatastrophicError, + MD_MessageKind_FatalError, } MD_MessageKind; @@ -865,6 +878,9 @@ MD_FUNCTION MD_String8 MD_S8Fmt(MD_Arena *arena, char *fmt, ...); MD_FUNCTION void MD_S8ListPush(MD_Arena *arena, MD_String8List *list, MD_String8 string); +MD_FUNCTION void MD_S8ListPushFmt(MD_Arena *arena, MD_String8List *list, + char *fmt, ...); + MD_FUNCTION void MD_S8ListConcat(MD_String8List *list, MD_String8List *to_push); MD_FUNCTION MD_String8List MD_S8Split(MD_Arena *arena, MD_String8 string, int split_count, MD_String8 *splits); @@ -994,10 +1010,23 @@ it##_r = it##_r->next, it = MD_NodeFromReference(it##_r) //~ Error/Warning Helpers -MD_FUNCTION void MD_PrintMessage(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, MD_String8 str); -MD_FUNCTION void MD_PrintMessageFmt(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, char *fmt, ...); -MD_FUNCTION void MD_PrintNodeMessage(FILE *out, MD_Node *node, MD_MessageKind kind, MD_String8 str); -MD_FUNCTION void MD_PrintNodeMessageFmt(FILE *out, MD_Node *node, MD_MessageKind kind, char *fmt, ...); +MD_FUNCTION MD_String8 MD_StringFromMessageKind(MD_MessageKind kind); + +#define MD_FmtCodeLoc "%.*s:%i:%i:" +#define MD_CodeLocVArg(loc) MD_S8VArg((loc).filename), (loc).line, (loc).column + +MD_FUNCTION MD_String8 MD_FormatMessage(MD_Arena *arena, MD_CodeLoc loc, MD_MessageKind kind, + MD_String8 string); + +#if MD_ENABLE_PRINT_HELPERS +#include +MD_FUNCTION void MD_PrintMessage(FILE *file, MD_CodeLoc loc, MD_MessageKind kind, + MD_String8 string); +MD_FUNCTION void MD_PrintMessageFmt(FILE *file, MD_CodeLoc code_loc, MD_MessageKind kind, + char *fmt, ...); +MD_FUNCTION void MD_PrintNodeMessageFmt(FILE *file, MD_Node *node, MD_MessageKind kind, + char *fmt, ...); +#endif //~ Tree Comparison/Verification diff --git a/source/md_c_helpers.h b/source/md_c_helpers.h index 2e0a39d..0c8197b 100644 --- a/source/md_c_helpers.h +++ b/source/md_c_helpers.h @@ -103,6 +103,9 @@ MD_FUNCTION MD_b32 MD_C_ExprDeepMatch(MD_C_Expr *a, MD_C_Expr *b, MD_Matc //~ C Language Generation +// TODO(allen): cleanup these printers +#include + MD_FUNCTION void MD_C_Generate_String(FILE *file, MD_Node *node); MD_FUNCTION void MD_C_Generate_Struct(FILE *file, MD_Node *node); diff --git a/tests/cpp_build_test.cpp b/tests/cpp_build_test.cpp index 78c3583..7ba5033 100644 --- a/tests/cpp_build_test.cpp +++ b/tests/cpp_build_test.cpp @@ -1,6 +1,8 @@ #include "md.h" #include "md.c" +#include + static MD_Arena *arena = 0; int main(void)