From 6576a91d11139cd87662a3b3f6e886ddb424d175 Mon Sep 17 00:00:00 2001 From: Matt Mascarenhas Date: Fri, 13 Jan 2023 20:31:44 +0000 Subject: [PATCH] cinera: Support message deduplication This commit adds support for deduplication of messages emitted by PrintEdit(). It's a first pass, only supporting single-line messages and ones no larger than 512 bytes. It also fixes StringContains() to skip strings shorter than the search substring, and emits a more sensible error on empty "output" value. --- cinera/cinera.c | 1021 ++++++++++++++++++++++------------------ cinera/cinera_config.c | 320 +++++++------ 2 files changed, 723 insertions(+), 618 deletions(-) diff --git a/cinera/cinera.c b/cinera/cinera.c index 6ebefc2..ee17ed4 100644 --- a/cinera/cinera.c +++ b/cinera/cinera.c @@ -23,7 +23,7 @@ typedef struct version CINERA_APP_VERSION = { .Major = 0, .Minor = 10, - .Patch = 21 + .Patch = 22 }; #define __USE_XOPEN2K8 // NOTE(matt): O_NOFOLLOW @@ -92,10 +92,23 @@ typedef uint64_t bool; // //// +typedef struct +{ + char DesiredMessage[512]; // TODO(matt): memory_book or other growable buffer + char LastMessage[512]; // TODO(matt): memory_book or other growable buffer + uint64_t RepetitionCount; + bool LastMessageMayBeDeduplicated; +} message_control; + +message_control MESSAGE_CONTROL = { .RepetitionCount = 1 }; + +#define Print(...) fprintf(__VA_ARGS__); MESSAGE_CONTROL.LastMessageMayBeDeduplicated = FALSE +#define WriteToFile(...) fprintf(__VA_ARGS__) + bool PROFILING = 0; clock_t TIMING_START; -#define START_TIMING_BLOCK(...) if(PROFILING) { printf(__VA_ARGS__); TIMING_START = clock(); } -#define END_TIMING_BLOCK() if(PROFILING) { printf("\e[1;34m%ld\e[0m\n", clock() - TIMING_START);} +#define START_TIMING_BLOCK(...) if(PROFILING) { Print(stdout, __VA_ARGS__); TIMING_START = clock(); } +#define END_TIMING_BLOCK() if(PROFILING) { Print(stdout, "\e[1;34m%ld\e[0m\n", clock() - TIMING_START);} #define Kilobytes(Bytes) Bytes << 10 #define Megabytes(Bytes) Bytes << 20 @@ -128,8 +141,8 @@ clock_t TIMING_START; #define INDENT_WIDTH 4 #define ArrayCount(A) sizeof(A)/sizeof(*(A)) -#define Assert(Expression) do { if(!(Expression)){ fprintf(stderr, "l.%d: \e[1;31mAssertion failure\e[0m\n", __LINE__); __asm__("int3"); } } while(0) -#define BreakHere() fprintf(stderr, "[%i] BreakHere\n", __LINE__) +#define Assert(Expression) do { if(!(Expression)){ Print(stderr, "l.%d: \e[1;31mAssertion failure\e[0m\n", __LINE__); __asm__("int3"); } } while(0) +#define BreakHere() Print(stderr, "[%i] BreakHere\n", __LINE__) #define FOURCC(String) ((uint32_t)(String[0] << 0) | (uint32_t)(String[1] << 8) | (uint32_t)(String[2] << 16) | (uint32_t)(String[3] << 24)) #define Free(M) free(M); M = 0; @@ -193,7 +206,7 @@ GetUsage(void) // #if DEBUG_MEMORY_LEAKAGE_LOOPED #define MEM_LOOP_PRE_FREE(String) \ - fprintf(stderr, "Testing %s freeing\n", String);\ + Print(stderr, "Testing %s freeing\n", String);\ int MemLoopInitial = GetUsage();\ int MemLoopOld = MemLoopInitial;\ int MemLoopNew;\ @@ -202,14 +215,14 @@ GetUsage(void) #define MEM_LOOP_PRE_WORK() \ MemLoopNew = GetUsage();\ - if(1 /*MemLoopNew > MemLoopOld*/) { fprintf(stderr, "iter %2i: %i (%s%i)\n", i, MemLoopNew, MemLoopNew > MemLoopOld ? "+" : "-", MemLoopNew - MemLoopOld); sleep(1); }\ + if(1 /*MemLoopNew > MemLoopOld*/) { Print(stderr, "iter %2i: %i (%s%i)\n", i, MemLoopNew, MemLoopNew > MemLoopOld ? "+" : "-", MemLoopNew - MemLoopOld); sleep(1); }\ #define MEM_LOOP_POST(String) \ MemLoopOld = MemLoopNew;\ }\ - fprintf(stderr, "Done (%s): ", String);\ + Print(stderr, "Done (%s): ", String);\ Colourise(MemLoopNew > MemLoopInitial ? CS_RED : CS_GREEN);\ - fprintf(stderr, "%s%i\n", MemLoopNew > MemLoopInitial ? "+" : "-", MemLoopNew - MemLoopInitial);\ + Print(stderr, "%s%i\n", MemLoopNew > MemLoopInitial ? "+" : "-", MemLoopNew - MemLoopInitial);\ Colourise(CS_END);\ sleep(4); #else @@ -227,11 +240,11 @@ int DebugMemoryIndentLevel = 0; #define MEM_TEST_TOP() int MemTestInitialValue = GetUsage(); int MemTestRunningValue = MemTestInitialValue;\ /*\ Colourise(CS_BLACK_BOLD);\ - fprintf(stderr, "[%5i]", __LINE__);\ + Print(stderr, "[%5i]", __LINE__);\ Colourise(CS_GREEN);\ - fprintf(stderr, " ");\ + Print(stderr, " ");\ Indent(DebugMemoryIndentLevel);\ - fprintf(stderr, "%s() starts at %i kb\n", __func__, MemTestInitialValue);\ + Print(stderr, "%s() starts at %i kb\n", __func__, MemTestInitialValue);\ Colourise(CS_END);\ */\ ++DebugMemoryIndentLevel; @@ -239,11 +252,11 @@ int DebugMemoryIndentLevel = 0; #define MEM_TEST_MID() if(GetUsage() > MemTestRunningValue)\ {\ Colourise(CS_BLACK_BOLD);\ - fprintf(stderr, "[%5i]", __LINE__);\ + Print(stderr, "[%5i]", __LINE__);\ Colourise(CS_YELLOW);\ - fprintf(stderr, " ");\ + Print(stderr, " ");\ Indent(DebugMemoryIndentLevel - 1);\ - fprintf(stderr, "%s() is now at %i kb (+%i)\n", __func__, GetUsage(), GetUsage() - MemTestInitialValue);\ + Print(stderr, "%s() is now at %i kb (+%i)\n", __func__, GetUsage(), GetUsage() - MemTestInitialValue);\ Colourise(CS_END);\ MemTestRunningValue = GetUsage();\ WaitForInput();\ @@ -253,11 +266,11 @@ int DebugMemoryIndentLevel = 0; if(MemTestRunningValue > MemTestInitialValue)\ {\ Colourise(CS_BLACK_BOLD);\ - fprintf(stderr, "[%5i]", __LINE__);\ + Print(stderr, "[%5i]", __LINE__);\ Colourise(CS_RED);\ - fprintf(stderr, " ");\ + Print(stderr, " ");\ Indent(DebugMemoryIndentLevel);\ - fprintf(stderr, "%s() ends at %i kb (+%i)\n", __func__, MemTestRunningValue, MemTestRunningValue - MemTestInitialValue);\ + Print(stderr, "%s() ends at %i kb (+%i)\n", __func__, MemTestRunningValue, MemTestRunningValue - MemTestInitialValue);\ Colourise(CS_END);\ WaitForInput();\ } @@ -472,12 +485,83 @@ typedef struct bool Locking; } file; +char *ColourStrings[] = +{ + "\e[0m", + "\e[0;30m", "\e[0;31m", "\e[0;32m", "\e[0;33m", "\e[0;34m", "\e[0;35m", "\e[0;36m", "\e[0;37m", + "\e[1;30m", "\e[1;31m", "\e[1;32m", "\e[1;33m", "\e[1;34m", "\e[1;35m", "\e[1;36m", "\e[1;37m", +}; + +typedef enum +{ + CS_END, + CS_BLACK, CS_RED, CS_GREEN, CS_YELLOW, CS_BLUE, CS_MAGENTA, CS_CYAN, CS_WHITE, + CS_BLACK_BOLD, CS_RED_BOLD, CS_GREEN_BOLD, CS_YELLOW_BOLD, CS_BLUE_BOLD, CS_MAGENTA_BOLD, CS_CYAN_BOLD, CS_WHITE_BOLD, +} colour_code; + +#define CS_SUCCESS CS_GREEN_BOLD +#define CS_ADDITION CS_GREEN_BOLD +#define CS_REINSERTION CS_YELLOW_BOLD +#define CS_FAILURE CS_RED_BOLD +#define CS_ERROR CS_RED_BOLD +#define CS_WARNING CS_YELLOW +#define CS_PRIVATE CS_BLUE +#define CS_ONGOING CS_MAGENTA +#define CS_COMMENT CS_BLACK_BOLD +#define CS_DELETION CS_BLACK_BOLD + +void +Colourise(colour_code C) +{ + Print(stderr, "%s", ColourStrings[C]); +} + +uint64_t +StringLength(char *String) +{ + uint64_t i = 0; + if(String) + { + while(String[i]) + { + ++i; + } + } + return i; +} + typedef struct { char *Base; uint64_t Length; } string; +// NOTE(matt): For use with 0-terminated strings +string +Wrap0(char *String) +{ + string Result = {}; + Result.Base = String; + Result.Length = StringLength(String); + return Result; +} + +// NOTE(matt): For use with implicitly 0-terminated strings, i.e. fixed-size char arrays that may either be full of data, +// or filled after their data with 0s +#define Wrap0i(S) Wrap0i_(S, sizeof(S)) +string +Wrap0i_(char *S, uint64_t MaxSize) +{ + string Result = {}; + Result.Base = S; + Result.Length = MaxSize; + while(Result.Length > 0 && Result.Base[Result.Length - 1] == '\0') + { + --Result.Length; + } + return Result; +} + int CopyBytes(char *Dest, char *Src, int Count) { @@ -494,6 +578,16 @@ CopyStringToBarePtr(char *Dest, string Src) return CopyBytes(Dest, Src.Base, Src.Length); } +int +CopyStringCToBarePtr(colour_code Colour, char *Dest, string Src) +{ + int Length = 0; + Length += CopyStringToBarePtr(Dest + Length, Wrap0(ColourStrings[Colour])); + Length += CopyStringToBarePtr(Dest + Length, Src); + Length += CopyStringToBarePtr(Dest + Length, Wrap0(ColourStrings[CS_END])); + return Length; +} + typedef struct { char *Base; @@ -767,7 +861,7 @@ EraseCurrentStringFromBook(memory_book *M) void PrintPage(memory_page *P) { - fprintf(stderr, "%.*s\n\n", (int)(P->Ptr - P->Base), P->Base); + Print(stderr, "%.*s\n\n", (int)(P->Ptr - P->Base), P->Base); } void @@ -790,20 +884,6 @@ StringToInt(string S) return Result; } -uint64_t -StringLength(char *String) -{ - uint64_t i = 0; - if(String) - { - while(String[i]) - { - ++i; - } - } - return i; -} - int64_t StringsDiffer(string A, string B) { @@ -965,13 +1045,16 @@ bool StringContains(string S, string Substring) { bool Result = FALSE; - string Test = S; - for(int64_t i = 0; i <= S.Length - Substring.Length; ++i, ++Test.Base, --Test.Length) + if(S.Length >= Substring.Length) { - if(StringsMatchSized(Test, Substring.Length, Substring)) + string Test = S; + for(int64_t i = 0; i <= S.Length - Substring.Length; ++i, ++Test.Base, --Test.Length) { - Result = TRUE; - break; + if(StringsMatchSized(Test, Substring.Length, Substring)) + { + Result = TRUE; + break; + } } } return Result; @@ -1042,32 +1125,6 @@ ExtensionMatches(string Path, extension_id Extension) // NOTE(matt): Extension i return Result; } -// NOTE(matt): For use with 0-terminated strings -string -Wrap0(char *String) -{ - string Result = {}; - Result.Base = String; - Result.Length = StringLength(String); - return Result; -} - -// NOTE(matt): For use with implicitly 0-terminated strings, i.e. fixed-size char arrays that may either be full of data, -// or filled after their data with 0s -#define Wrap0i(S) Wrap0i_(S, sizeof(S)) -string -Wrap0i_(char *S, uint64_t MaxSize) -{ - string Result = {}; - Result.Base = S; - Result.Length = MaxSize; - while(Result.Length > 0 && Result.Base[Result.Length - 1] == '\0') - { - --Result.Length; - } - return Result; -} - void ExtendString0(char **Dest, string Src) { @@ -1179,47 +1236,16 @@ ReadFileIntoMemory0(FILE *F) return Result; } -char *ColourStrings[] = -{ - "\e[0m", - "\e[0;30m", "\e[0;31m", "\e[0;32m", "\e[0;33m", "\e[0;34m", "\e[0;35m", "\e[0;36m", "\e[0;37m", - "\e[1;30m", "\e[1;31m", "\e[1;32m", "\e[1;33m", "\e[1;34m", "\e[1;35m", "\e[1;36m", "\e[1;37m", -}; - -typedef enum -{ - CS_END, - CS_BLACK, CS_RED, CS_GREEN, CS_YELLOW, CS_BLUE, CS_MAGENTA, CS_CYAN, CS_WHITE, - CS_BLACK_BOLD, CS_RED_BOLD, CS_GREEN_BOLD, CS_YELLOW_BOLD, CS_BLUE_BOLD, CS_MAGENTA_BOLD, CS_CYAN_BOLD, CS_WHITE_BOLD, -} colour_code; - -#define CS_SUCCESS CS_GREEN_BOLD -#define CS_ADDITION CS_GREEN_BOLD -#define CS_REINSERTION CS_YELLOW_BOLD -#define CS_FAILURE CS_RED_BOLD -#define CS_ERROR CS_RED_BOLD -#define CS_WARNING CS_YELLOW -#define CS_PRIVATE CS_BLUE -#define CS_ONGOING CS_MAGENTA -#define CS_COMMENT CS_BLACK_BOLD -#define CS_DELETION CS_BLACK_BOLD - -void -Colourise(colour_code C) -{ - fprintf(stderr, "%s", ColourStrings[C]); -} - int PrintString(string S) { - return fprintf(stderr, "%.*s", (int)S.Length, S.Base); + return Print(stderr, "%.*s", (int)S.Length, S.Base); } void PrintStringN(string S) { - fprintf(stderr, "\n%.*s", (int)S.Length, S.Base); + Print(stderr, "\n%.*s", (int)S.Length, S.Base); } void @@ -1227,7 +1253,7 @@ PrintStringI(string S, uint64_t Indentation) { for(int i = 0; i < Indentation; ++i) { - fprintf(stderr, " "); + Print(stderr, " "); } PrintString(S); } @@ -1244,18 +1270,18 @@ PrintStringC(colour_code Colour, string String) void PrintStringCN(colour_code Colour, string String, bool PrependNewline, bool AppendNewline) { - if(PrependNewline) { fprintf(stderr, "\n"); } + if(PrependNewline) { Print(stderr, "\n"); } Colourise(Colour); PrintString(String); Colourise(CS_END); - if(AppendNewline) { fprintf(stderr, "\n"); } + if(AppendNewline) { Print(stderr, "\n"); } } void PrintC(colour_code Colour, char *String) { Colourise(Colour); - fprintf(stderr, "%s", String); + Print(stderr, "%s", String); Colourise(CS_END); } @@ -1264,14 +1290,14 @@ void PrintFunctionName(char *N) { PrintC(CS_MAGENTA, N); - fprintf(stderr, "\n"); + Print(stderr, "\n"); } void PrintLinedFunctionName(int LineNumber, char *N) { Colourise(CS_BLACK_BOLD); - fprintf(stderr, "[%i] ", LineNumber); + Print(stderr, "[%i] ", LineNumber); Colourise(CS_END); PrintFunctionName(N); } @@ -1668,14 +1694,14 @@ Indent(uint64_t Indent) { for(int i = 0; i < INDENT_WIDTH * Indent; ++i) { - fprintf(stderr, " "); + Print(stderr, " "); } } void IndentedCarriageReturn(int IndentationLevel) { - fprintf(stderr, "\n"); + Print(stderr, "\n"); Indent(IndentationLevel); } @@ -1684,14 +1710,14 @@ AlignText(int Alignment) { for(int i = 0; i < Alignment; ++i) { - fprintf(stderr, " "); + Print(stderr, " "); } } void NewParagraph(int IndentationLevel) { - fprintf(stderr, "\n"); + Print(stderr, "\n"); IndentedCarriageReturn(IndentationLevel); } @@ -1701,7 +1727,7 @@ NewSection(char *Title, int *IndentationLevel) IndentedCarriageReturn(*IndentationLevel); if(Title) { - fprintf(stderr, "%s:", Title); + Print(stderr, "%s:", Title); } ++*IndentationLevel; IndentedCarriageReturn(*IndentationLevel); @@ -1724,7 +1750,7 @@ GetTerminalColumns(void) void ClearTerminal(void) { - fprintf(stderr, "\033[2J"); + Print(stderr, "\033[2J"); } void @@ -1771,10 +1797,10 @@ TypesetString(int CurrentColumn, string String) while(CharactersToWrite > 0) { - fprintf(stderr, "\n"); + Print(stderr, "\n"); for(int i = 0; i < CurrentColumn; ++i) { - fprintf(stderr, " "); + Print(stderr, " "); } string Pen = { .Base = String.Base + String.Length - CharactersToWrite, @@ -1922,7 +1948,7 @@ typedef enum void ErrorFilenameAndLineNumber(string *Filename, uint64_t LineNumber, severity Severity, error_domain Domain) { - fprintf(stderr, "\n" + Print(stderr, "\n" "┌─ "); switch(Severity) @@ -1931,26 +1957,26 @@ ErrorFilenameAndLineNumber(string *Filename, uint64_t LineNumber, severity Sever case S_WARNING: Colourise(CS_WARNING); break; } - fprintf(stderr, "%s %s", ErrorDomainStrings[Domain], SeverityStrings[Severity]); + Print(stderr, "%s %s", ErrorDomainStrings[Domain], SeverityStrings[Severity]); Colourise(CS_END); if(Filename) { if(LineNumber > 0) { - fprintf(stderr, " on line "); + Print(stderr, " on line "); Colourise(CS_BLUE_BOLD); - fprintf(stderr, "%lu", LineNumber); + Print(stderr, "%lu", LineNumber); Colourise(CS_END); - fprintf(stderr, " of "); + Print(stderr, " of "); } else { - fprintf(stderr, " with "); + Print(stderr, " with "); } PrintStringC(CS_CYAN, *Filename); } - fprintf(stderr, "\n" + Print(stderr, "\n" "└─╼ "); } @@ -1960,13 +1986,13 @@ void ConfigError(string *Filename, uint64_t LineNumber, severity Severity, char *Message, string *Received) { ErrorFilenameAndLineNumber(Filename, LineNumber, Severity, ED_CONFIG); - fprintf(stderr, + Print(stderr, "%s", Message); if(Received) { PrintStringC(CS_MAGENTA_BOLD, *Received); } - fprintf(stderr, "\n"); + Print(stderr, "\n"); } void @@ -1974,7 +2000,7 @@ ConfigErrorField(string *Filename, uint64_t LineNumber, severity Severity, confi string *Received, char *Message) { ErrorFilenameAndLineNumber(Filename, LineNumber, Severity, ED_CONFIG); - fprintf(stderr, + Print(stderr, "%s%s%s value %s%.*s%s %s\n", ColourStrings[CS_YELLOW_BOLD], ConfigIdentifiers[FieldID].String, ColourStrings[CS_END], ColourStrings[CS_MAGENTA_BOLD], (int)Received->Length, Received->Base, ColourStrings[CS_END], @@ -1985,7 +2011,7 @@ void ConfigErrorUnset(config_identifier_id FieldID) { ErrorFilenameAndLineNumber(0, 0, S_ERROR, ED_CONFIG); - fprintf(stderr, + Print(stderr, "Unset %s\n", ConfigIdentifiers[FieldID].String); } @@ -1995,7 +2021,7 @@ ConfigErrorUnsetFieldOf(string *Filename, uint64_t LineNumber, config_identifier_id ScopeKey, string ScopeID) { ErrorFilenameAndLineNumber(Filename, LineNumber, S_ERROR, ED_CONFIG); - fprintf(stderr, + Print(stderr, "Unset %s%s%s of %s%s%s: %s%.*s%s\n", ColourStrings[CS_YELLOW_BOLD], ConfigIdentifiers[UnsetFieldID].String, ColourStrings[CS_END], ColourStrings[CS_YELLOW_BOLD], ConfigIdentifiers[ScopeKey].String, ColourStrings[CS_END], @@ -2006,37 +2032,37 @@ void ConfigErrorSizing(string *Filename, uint64_t LineNumber, config_identifier_id FieldID, string *Received, uint64_t MaxSize) { ErrorFilenameAndLineNumber(Filename, LineNumber, S_ERROR, ED_CONFIG); - fprintf(stderr, "%s value is too long (%lu/%lu characters): ", ConfigIdentifiers[FieldID].String, Received->Length, MaxSize); + Print(stderr, "%s value is too long (%lu/%lu characters): ", ConfigIdentifiers[FieldID].String, Received->Length, MaxSize); PrintStringC(CS_MAGENTA_BOLD, *Received); - fprintf(stderr, "\n"); + Print(stderr, "\n"); } void ConfigErrorLockedConfigLocation(string *Filename, uint64_t LineNumber, string *Received) { ErrorFilenameAndLineNumber(Filename, LineNumber, Filename ? S_WARNING : S_ERROR, ED_CONFIG); - fprintf(stderr, "%s file %s%.*s%s is in use by another Cinera instance\n", Filename ? "Included" : "Config", ColourStrings[CS_MAGENTA_BOLD], (int)Received->Length, Received->Base, ColourStrings[CS_END]); + Print(stderr, "%s file %s%.*s%s is in use by another Cinera instance\n", Filename ? "Included" : "Config", ColourStrings[CS_MAGENTA_BOLD], (int)Received->Length, Received->Base, ColourStrings[CS_END]); } void ConfigErrorUnopenableConfigLocation(string *Filename, uint64_t LineNumber, string *Received) { ErrorFilenameAndLineNumber(Filename, LineNumber, Filename ? S_WARNING : S_ERROR, ED_CONFIG); - fprintf(stderr, "%s file %s%.*s%s could not be opened: %s\n", Filename ? "Included" : "Config", ColourStrings[CS_MAGENTA_BOLD], (int)Received->Length, Received->Base, ColourStrings[CS_END], strerror(errno)); + Print(stderr, "%s file %s%.*s%s could not be opened: %s\n", Filename ? "Included" : "Config", ColourStrings[CS_MAGENTA_BOLD], (int)Received->Length, Received->Base, ColourStrings[CS_END], strerror(errno)); } void ConfigErrorLockedDBLocation(string *Filename, uint64_t LineNumber, string *Received) { ErrorFilenameAndLineNumber(Filename, LineNumber, S_ERROR, ED_CONFIG); - fprintf(stderr, "File at db_location %s%.*s%s is in use by another Cinera instance\n", ColourStrings[CS_MAGENTA_BOLD], (int)Received->Length, Received->Base, ColourStrings[CS_END]); + Print(stderr, "File at db_location %s%.*s%s is in use by another Cinera instance\n", ColourStrings[CS_MAGENTA_BOLD], (int)Received->Length, Received->Base, ColourStrings[CS_END]); } void ConfigErrorInt(string *Filename, uint64_t LineNumber, severity Severity, char *Message, uint64_t Number) { ErrorFilenameAndLineNumber(Filename, LineNumber, Severity, ED_CONFIG); - fprintf(stderr, + Print(stderr, "%s%s%lu%s\n", Message, ColourStrings[CS_BLUE_BOLD], Number, ColourStrings[CS_END]); } @@ -2046,7 +2072,7 @@ ConfigErrorExpectation(tokens *T, token_type GreaterExpectation, token_type Less token *This = GetPlaceInBook(&T->Token, T->CurrentIndex); string Filepath = Wrap0(T->File.Path); ErrorFilenameAndLineNumber(&Filepath, This->LineNumber, S_ERROR, ED_CONFIG); - fprintf(stderr, + Print(stderr, "Syntax error: Received "); if(This->Content.Base) { @@ -2054,19 +2080,19 @@ ConfigErrorExpectation(tokens *T, token_type GreaterExpectation, token_type Less } else { - fprintf(stderr, "%s%ld%s", ColourStrings[CS_BLUE_BOLD], This->int64_t, ColourStrings[CS_END]); + Print(stderr, "%s%ld%s", ColourStrings[CS_BLUE_BOLD], This->int64_t, ColourStrings[CS_END]); } - fprintf(stderr, + Print(stderr, " but Expected "); PrintStringC(CS_GREEN, Wrap0(TokenStrings[GreaterExpectation])); if(LesserExpectation) { - fprintf(stderr, + Print(stderr, " or "); PrintStringC(CS_GREEN, Wrap0(TokenStrings[LesserExpectation])); } - fprintf(stderr, + Print(stderr, "\n"); } @@ -2075,13 +2101,13 @@ IndexingError(string Filename, uint64_t LineNumber, severity Severity, char *Mes { ErrorFilenameAndLineNumber(&Filename, LineNumber, Severity, ED_INDEXING); // TODO(matt): Typeset the Message? - fprintf(stderr, + Print(stderr, "%s", Message); if(Received) { PrintStringC(CS_MAGENTA_BOLD, *Received); } - fprintf(stderr, "\n"); + Print(stderr, "\n"); } void @@ -2090,11 +2116,11 @@ PrintTimecode(FILE *Dest, v3 Timecode) Colourise(CS_BLUE_BOLD); if(Timecode.Hours) { - fprintf(Dest, "%i:%02i:%02i", Timecode.Hours, Timecode.Minutes, Timecode.Seconds); + Print(Dest, "%i:%02i:%02i", Timecode.Hours, Timecode.Minutes, Timecode.Seconds); } else { - fprintf(Dest, "%i:%02i", Timecode.Minutes, Timecode.Seconds); + Print(Dest, "%i:%02i", Timecode.Minutes, Timecode.Seconds); } Colourise(CS_END); } @@ -2104,49 +2130,49 @@ IndexingChronologyError(string *Filename, uint64_t LineNumber, v3 ThisTimecode, { severity Severity = S_ERROR; ErrorFilenameAndLineNumber(Filename, LineNumber, Severity, ED_INDEXING); - fprintf(stderr, + Print(stderr, "Timecode "); PrintTimecode(stderr, ThisTimecode); - fprintf(stderr, " is chronologically earlier than previous timecode ("); + Print(stderr, " is chronologically earlier than previous timecode ("); PrintTimecode(stderr, PrevTimecode); - fprintf(stderr, ")\n"); + Print(stderr, ")\n"); } void IndexingQuoteError(string *Filename, uint64_t LineNumber, string Author, uint64_t QuoteID) { ErrorFilenameAndLineNumber(Filename, LineNumber, S_ERROR, ED_INDEXING); - fprintf(stderr, "Quote not found: "); + Print(stderr, "Quote not found: "); Colourise(CS_MAGENTA_BOLD); - fprintf(stderr, "#"); + Print(stderr, "#"); PrintString(Author); - fprintf(stderr, " %ld", QuoteID); + Print(stderr, " %ld", QuoteID); Colourise(CS_END); - fprintf(stderr, "\n"); + Print(stderr, "\n"); } void IndexingErrorSizing(string *Filename, uint64_t LineNumber, char *Key, string Received, uint64_t MaxSize) { ErrorFilenameAndLineNumber(Filename, LineNumber, S_ERROR, ED_INDEXING); - fprintf(stderr, "%s value is too long (%lu/%lu characters): ", Key, Received.Length, MaxSize); + Print(stderr, "%s value is too long (%lu/%lu characters): ", Key, Received.Length, MaxSize); PrintStringC(CS_MAGENTA_BOLD, Received); - fprintf(stderr, "\n"); + Print(stderr, "\n"); } void IndexingErrorClash(string *Filename, uint64_t LineNumber, severity Severity, char *Key, string Received, string ExistingEntryBaseFilename) { ErrorFilenameAndLineNumber(Filename, LineNumber, Severity, ED_INDEXING); - fprintf(stderr, "%s value %s%.*s%s clashes with that of existing entry: ", Key, ColourStrings[CS_MAGENTA_BOLD], (int)Received.Length, Received.Base, ColourStrings[CS_END]); + Print(stderr, "%s value %s%.*s%s clashes with that of existing entry: ", Key, ColourStrings[CS_MAGENTA_BOLD], (int)Received.Length, Received.Base, ColourStrings[CS_END]); PrintStringC(CS_MAGENTA, ExistingEntryBaseFilename); - fprintf(stderr, "\n"); + Print(stderr, "\n"); } void PrintValidLanguageCodeChars(void) { - fprintf(stderr, + Print(stderr, " Valid characters:\n" " a to z\n" " A to Z\n" @@ -2158,33 +2184,40 @@ void IndexingErrorInvalidLanguageCode(string *Filename, uint64_t LineNumber, char *Key, string Received) { ErrorFilenameAndLineNumber(Filename, LineNumber, S_ERROR, ED_INDEXING); - fprintf(stderr, "%s value %s%.*s%s contains invalid character(s)\n", + Print(stderr, "%s value %s%.*s%s contains invalid character(s)\n", Key, ColourStrings[CS_MAGENTA_BOLD], (int)Received.Length, Received.Base, ColourStrings[CS_END]); } +void +IndexingErrorEmptyField(string *Filename, uint64_t LineNumber, char *Key) +{ + ErrorFilenameAndLineNumber(Filename, LineNumber, S_ERROR, ED_INDEXING); + Print(stderr, "%s field cannot be empty\n", Key); +} + void IndexingErrorInvalidSubstring(string *Filename, uint64_t LineNumber, char *Key, string Received, string InvalidSubstring) { ErrorFilenameAndLineNumber(Filename, LineNumber, S_ERROR, ED_INDEXING); - fprintf(stderr, "%s value %s%.*s%s contains invalid substring: ", Key, ColourStrings[CS_MAGENTA_BOLD], (int)Received.Length, Received.Base, ColourStrings[CS_END]); + Print(stderr, "%s value %s%.*s%s contains invalid substring: ", Key, ColourStrings[CS_MAGENTA_BOLD], (int)Received.Length, Received.Base, ColourStrings[CS_END]); PrintStringC(CS_MAGENTA, InvalidSubstring); - fprintf(stderr, "\n"); + Print(stderr, "\n"); } void IndexingErrorCustomSizing(string *Filename, uint64_t LineNumber, int CustomIndex, string Received) { ErrorFilenameAndLineNumber(Filename, LineNumber, S_ERROR, ED_INDEXING); - fprintf(stderr, "custom%d value is too long (%lu/%i characters): ", CustomIndex, Received.Length, CustomIndex < 12 ? MAX_CUSTOM_SNIPPET_SHORT_LENGTH : MAX_CUSTOM_SNIPPET_LONG_LENGTH); + Print(stderr, "custom%d value is too long (%lu/%i characters): ", CustomIndex, Received.Length, CustomIndex < 12 ? MAX_CUSTOM_SNIPPET_SHORT_LENGTH : MAX_CUSTOM_SNIPPET_LONG_LENGTH); PrintStringC(CS_MAGENTA_BOLD, Received); - fprintf(stderr, "\n"); + Print(stderr, "\n"); if(Received.Length < MAX_CUSTOM_SNIPPET_LONG_LENGTH) { - fprintf(stderr, "Consider using custom12 to custom15, which can hold %d characters\n", MAX_CUSTOM_SNIPPET_LONG_LENGTH); + Print(stderr, "Consider using custom12 to custom15, which can hold %d characters\n", MAX_CUSTOM_SNIPPET_LONG_LENGTH); } else { - fprintf(stderr, "Consider using a bespoke template for longer amounts of localised information\n"); + Print(stderr, "Consider using a bespoke template for longer amounts of localised information\n"); } } @@ -2193,13 +2226,13 @@ SystemError(string *Filename, uint64_t LineNumber, severity Severity, char *Mess { ErrorFilenameAndLineNumber(Filename, LineNumber, Severity, ED_SYSTEM); // TODO(matt): Typeset the Message? - fprintf(stderr, + Print(stderr, "%s", Message); if(Received) { PrintStringC(CS_MAGENTA_BOLD, *Received); } - fprintf(stderr, "\n"); + Print(stderr, "\n"); } typedef enum @@ -2237,10 +2270,10 @@ GetLogLevelFromString(string *Filename, token *T) } ConfigError(Filename, T->LineNumber, S_ERROR, "Unknown log level: ", &T->Content); - fprintf(stderr, " Valid log levels:\n"); + Print(stderr, " Valid log levels:\n"); for(int i = 0; i < LOG_COUNT; ++i) { - fprintf(stderr, " %s\n", LogLevelStrings[i]); + Print(stderr, " %s\n", LogLevelStrings[i]); } return LOG_COUNT; @@ -2298,10 +2331,10 @@ GetGenreFromString(string *Filename, token *T) } ConfigError(Filename, T->LineNumber, S_ERROR, "Unknown genre: ", &T->Content); - fprintf(stderr, " Valid genres:\n"); + Print(stderr, " Valid genres:\n"); for(int i = 0; i < GENRE_COUNT; ++i) { - fprintf(stderr, " %s\n", GenreStrings[i]); + Print(stderr, " %s\n", GenreStrings[i]); } return GENRE_COUNT; @@ -2331,10 +2364,10 @@ GetNumberingSchemeFromString(string *Filename, token *T) } ConfigError(Filename, T->LineNumber, S_ERROR, "Unknown numbering scheme: ", &T->Content); - fprintf(stderr, " Valid numbering schemes:\n"); + Print(stderr, " Valid numbering schemes:\n"); for(int i = 0; i < NS_COUNT; ++i) { - fprintf(stderr, " %s\n", NumberingSchemeStrings[i]); + Print(stderr, " %s\n", NumberingSchemeStrings[i]); } return NS_COUNT; @@ -2364,10 +2397,10 @@ GetNumberingMethodFromString(string *Filename, token *T) } ConfigError(Filename, T->LineNumber, S_ERROR, "Unknown numbering method: ", &T->Content); - fprintf(stderr, " Valid numbering methods:\n"); + Print(stderr, " Valid numbering methods:\n"); for(int i = 0; i < NM_COUNT; ++i) { - fprintf(stderr, " %s\n", NumberingMethodStrings[i]); + Print(stderr, " %s\n", NumberingMethodStrings[i]); } return NM_COUNT; @@ -2413,7 +2446,7 @@ GetBoolFromString(string *Filename, token *T) else { ConfigError(Filename, T->LineNumber, S_ERROR, "Unknown boolean: ", &T->Content); - fprintf(stderr, " Valid booleans:\n"); + Print(stderr, " Valid booleans:\n"); PrintC(CS_GREEN, " true\n"); PrintC(CS_GREEN, " True\n"); PrintC(CS_GREEN, " TRUE\n"); @@ -2559,11 +2592,11 @@ ParseArtVariantsString(string *Filename, token *ArtVariantsString) if(!Valid) { - fprintf(stderr, " Valid variant_types:\n"); + Print(stderr, " Valid variant_types:\n"); int FirstValidVariant = 1; for(int i = FirstValidVariant; i < CAV_COUNT; ++i) { - fprintf(stderr, " %s\n", ConfigArtVariants[i].String); + Print(stderr, " %s\n", ConfigArtVariants[i].String); } Result = -1; } @@ -2595,11 +2628,11 @@ GetIconTypeFromString(string *Filename, token *T) } ConfigError(Filename, T->LineNumber, S_ERROR, "Unknown icon_type: ", &T->Content); - fprintf(stderr, " Valid icon_types:\n"); + Print(stderr, " Valid icon_types:\n"); int FirstValidIconType = 1; for(int i = FirstValidIconType; i < IT_COUNT; ++i) { - fprintf(stderr, " %s\n", IconTypeStrings[i]); + Print(stderr, " %s\n", IconTypeStrings[i]); } return NS_COUNT; @@ -2631,11 +2664,11 @@ GetVODPlatformFromString(string *Filename, token *T) } ConfigError(Filename, T->LineNumber, S_ERROR, "Unknown vod_platform: ", &T->Content); - fprintf(stderr, " Valid vod_platforms:\n"); + Print(stderr, " Valid vod_platforms:\n"); int FirstValidVODPlatform = 1; for(int i = FirstValidVODPlatform; i < VP_COUNT; ++i) { - fprintf(stderr, " %s\n", VODPlatformStrings[i]); + Print(stderr, " %s\n", VODPlatformStrings[i]); } return VP_COUNT; @@ -3295,14 +3328,14 @@ void PrintFour(FILE *Dest, uint32_t Four) { Colourise(CS_YELLOW); - fprintf(Dest, "%c%c%c%c", Four, Four >> 8, Four >> 16, Four >> 24); + Print(Dest, "%c%c%c%c", Four, Four >> 8, Four >> 16, Four >> 24); Colourise(CS_END); } void PrintDBStructureDataType(FILE *Dest, db_structure_datatype DataType) { - fprintf(Dest, "%s%.*s%s (%s%u%s byte%s)", + Print(Dest, "%s%.*s%s (%s%u%s byte%s)", ColourStrings[CS_MAGENTA], (int)DataType.Name.Length, DataType.Name.Base, ColourStrings[CS_END], ColourStrings[CS_BLUE_BOLD], DataType.SizeOf, ColourStrings[CS_END], DataType.SizeOf == 1 ? "" : "s"); @@ -3314,7 +3347,7 @@ TypesetDBStructureField(FILE *Dest, int IndentLevel, db_structure_field Field) if(Field.SizeOf) { IndentedCarriageReturn(IndentLevel); - fprintf(Dest, "%s%.*s%s: %s%u%s byte%s wide @ %s%u%s-byte offset", + Print(Dest, "%s%.*s%s: %s%u%s byte%s wide @ %s%u%s-byte offset", ColourStrings[CS_GREEN], (int)Field.Name.Length, Field.Name.Base, ColourStrings[CS_END], ColourStrings[CS_BLUE_BOLD], Field.SizeOf, ColourStrings[CS_END], Field.SizeOf == 1 ? "" : "s", @@ -3326,7 +3359,7 @@ void PrintDBBlockIDandSize(FILE *Dest, int IndentLevel, uint32_t ID, uint32_t SizeOf) { PrintFour(Dest, ID); - fprintf(Dest, " (%s%u%s bytes)", ColourStrings[CS_BLUE_BOLD], SizeOf, ColourStrings[CS_END]); + Print(Dest, " (%s%u%s bytes)", ColourStrings[CS_BLUE_BOLD], SizeOf, ColourStrings[CS_END]); } void @@ -3393,11 +3426,11 @@ PrintDBStructureItemLineage(FILE *Dest, db_structure_item *Item) for(int i = Lineage.ItemCount - 2; i >= 0; --i) { Cursor = GetPlaceInBook(&Lineage, i); - fprintf(Dest, "%s", Cursor->StructuralItemType == DBS_INDEXER_FIELD ? "." : "/"); + Print(Dest, "%s", Cursor->StructuralItemType == DBS_INDEXER_FIELD ? "." : "/"); PrintString(*Cursor->Name); if(Cursor->IndexerType == IDX_COMPOUND) { - fprintf(Dest, " [compound]"); + Print(Dest, " [compound]"); } } @@ -3411,18 +3444,18 @@ TypesetIndexers(FILE *Dest, int IndentLevel, memory_book *IndexedIntoBy) { IndentedCarriageReturn(IndentLevel); Colourise(CS_YELLOW_BOLD); - fprintf(Dest, "╿ is indexed into by:"); + Print(Dest, "╿ is indexed into by:"); for(int i = 0; i < IndexedIntoBy->ItemCount - 1; ++i) { IndentedCarriageReturn(IndentLevel); db_structure_item *This = GetPlaceInBook(IndexedIntoBy, i); - fprintf(Dest, "├── "); + Print(Dest, "├── "); PrintDBStructureItemLineage(Dest, This); } IndentedCarriageReturn(IndentLevel); db_structure_item *This = GetPlaceInBook(IndexedIntoBy, IndexedIntoBy->ItemCount - 1); - fprintf(Dest, "└── "); + Print(Dest, "└── "); PrintDBStructureItemLineage(Dest, This); Colourise(CS_END); } @@ -3451,7 +3484,7 @@ PrintDBStructureBlock(FILE *Dest, int IndentLevel, db_structure_block *Block) { IndentedCarriageReturn(IndentLevel); PrintFour(Dest, Block->ID); - fprintf(Dest, " (%s%u%s bytes)", ColourStrings[CS_BLUE_BOLD], Block->SizeOf, ColourStrings[CS_END]); + Print(Dest, " (%s%u%s bytes)", ColourStrings[CS_BLUE_BOLD], Block->SizeOf, ColourStrings[CS_END]); ++IndentLevel; TypesetDBStructureField(Dest, IndentLevel, Block->Count); @@ -3475,7 +3508,7 @@ void PrintDBStructure(FILE *Dest, int IndentLevel, db_structure *S) { IndentedCarriageReturn(IndentLevel); - fprintf(Dest, "Version %s%u%s", ColourStrings[CS_MAGENTA_BOLD], S->Version, ColourStrings[CS_END]); + Print(Dest, "Version %s%u%s", ColourStrings[CS_MAGENTA_BOLD], S->Version, ColourStrings[CS_END]); PrintDBStructureHeader(Dest, IndentLevel, &S->Header); ++IndentLevel; @@ -3496,7 +3529,7 @@ PrintDBStructures(FILE *Dest) db_structure *S = GetPlaceInBook(&DBStructures.Structure, i); PrintDBStructure(Dest, IndentLevel, S); } - fprintf(Dest, "\n"); + Print(Dest, "\n"); } typedef struct @@ -3940,7 +3973,7 @@ WaitForInput() { if(!Config || !Config->SuppressingPrompts) { - fprintf(stderr, "Press Enter to continue...\n"); + Print(stderr, "Press Enter to continue...\n"); getchar(); } } @@ -3951,7 +3984,7 @@ SeekConfirmation(char *Message, bool Default) bool Result = Default; if(!Config || !Config->SuppressingPrompts) { - fprintf(stderr, "%s (%s)\n", Message, Default == TRUE ? "Y/n" : "y/N"); + Print(stderr, "%s (%s)\n", Message, Default == TRUE ? "Y/n" : "y/N"); switch(getchar()) { case 'n': @@ -4025,7 +4058,7 @@ LogUsage(buffer *Buffer) } } - fprintf(LogFile, "%s,%ld,%d\n", + WriteToFile(LogFile, "%s,%ld,%d\n", Buffer->ID, Buffer->Ptr - Buffer->Location, Buffer->Size); @@ -4059,7 +4092,7 @@ LogError(int LogLevel, char *Format, ...) vfprintf(LogFile, Format, Args); va_end(Args); // TODO(matt): Include the LogLevel "string" and the current wall time - fprintf(LogFile, "\n"); + WriteToFile(LogFile, "\n"); fclose(LogFile); Free(LogPath); } @@ -4127,7 +4160,7 @@ ClaimBuffer(buffer *Buffer, buffer_id ID, int Size) Buffer->Ptr = Buffer->Location; #if DEBUG float PercentageUsed = (float)(MemoryArena.Ptr - MemoryArena.Location) / MemoryArena.Size * 100; - printf(" ClaimBuffer(%s): %ld\n" + Print(stdout, " ClaimBuffer(%s): %ld\n" " Total ClaimedMemory: %ld (%.2f%%, leaving %ld free)\n\n", BufferIDStrings[Buffer->ID], Buffer->Size, MemoryArena.Ptr - MemoryArena.Location, PercentageUsed, MemoryArena.Size - (MemoryArena.Ptr - MemoryArena.Location)); #endif return RC_SUCCESS; @@ -4140,7 +4173,7 @@ DeclaimBuffer(buffer *Buffer) { float PercentageUsed = (float)(Buffer->Ptr - Buffer->Location) / Buffer->Size * 100; #if DEBUG - printf("DeclaimBuffer(%s)\n" + Print(stdout, "DeclaimBuffer(%s)\n" " Used: %li / %ld (%.2f%%)\n" "\n" " Total ClaimedMemory: %ld\n\n", @@ -4155,7 +4188,7 @@ DeclaimBuffer(buffer *Buffer) { // TODO(matt): Implement either dynamically growing buffers, or phoning home to admin@miblo.net LogError(LOG_ERROR, "%s used %.2f%% of its allotted memory\n", BufferIDStrings[Buffer->ID], PercentageUsed); - fprintf(stderr, "%sWarning%s: %s used %.2f%% of its allotted memory\n", + Print(stderr, "%sWarning%s: %s used %.2f%% of its allotted memory\n", ColourStrings[CS_ERROR], ColourStrings[CS_END], BufferIDStrings[Buffer->ID], PercentageUsed); } @@ -4163,7 +4196,7 @@ DeclaimBuffer(buffer *Buffer) { // TODO(matt): Implement either dynamically growing buffers, or phoning home to admin@miblo.net LogError(LOG_ERROR, "%s used %.2f%% of its allotted memory\n", BufferIDStrings[Buffer->ID], PercentageUsed); - fprintf(stderr, "%sWarning%s: %s used %.2f%% of its allotted memory\n", + Print(stderr, "%sWarning%s: %s used %.2f%% of its allotted memory\n", ColourStrings[CS_WARNING], ColourStrings[CS_END], BufferIDStrings[Buffer->ID], PercentageUsed); } @@ -4180,7 +4213,7 @@ RewindBuffer(buffer *Buffer) { #if DEBUG float PercentageUsed = (float)(Buffer->Ptr - Buffer->Location) / Buffer->Size * 100; - printf("Rewinding %s\n" + Print(stdout, "Rewinding %s\n" " Used: %ld / %ld (%.2f%%)\n\n", BufferIDStrings[Buffer->ID], Buffer->Ptr - Buffer->Location, @@ -4245,7 +4278,7 @@ CopyString_(int LineNumber, char Dest[], int DestSize, char *Format, ...) Length = vsnprintf(Dest, DestSize, Format, Args); if(Length >= DestSize) { - printf("CopyString() call on line %d has been passed a buffer too small (%d bytes) to contain null-terminated %d(+1)-character string\n", LineNumber, DestSize, Length); + Print(stdout, "CopyString() call on line %d has been passed a buffer too small (%d bytes) to contain null-terminated %d(+1)-character string\n", LineNumber, DestSize, Length); __asm__("int3"); } va_end(Args); @@ -4264,7 +4297,7 @@ ClearCopyString_(int LineNumber, char Dest[], int DestSize, char *Format, ...) Length = vsnprintf(Dest, DestSize, Format, Args); if(Length >= DestSize) { - printf("CopyString() call on line %d has been passed a buffer too small (%d bytes) to contain null-terminated %d(+1)-character string\n", LineNumber, DestSize, Length); + Print(stdout, "CopyString() call on line %d has been passed a buffer too small (%d bytes) to contain null-terminated %d(+1)-character string\n", LineNumber, DestSize, Length); __asm__("int3"); } va_end(Args); @@ -4277,7 +4310,7 @@ CopyStringNoFormat_(int LineNumber, char *Dest, int DestSize, string String) { if(String.Length + 1 > DestSize) { - printf("CopyStringNoFormat() call on line %d has been passed a buffer too small (%d bytes) to contain null-terminated %ld(+1)-character string:\n" + Print(stdout, "CopyStringNoFormat() call on line %d has been passed a buffer too small (%d bytes) to contain null-terminated %ld(+1)-character string:\n" "%.*s\n", LineNumber, DestSize, String.Length, (int)String.Length, String.Base); __asm__("int3"); } @@ -4292,7 +4325,7 @@ ClearCopyStringNoFormatOrTerminate_(int LineNumber, char *Dest, int DestSize, st { if(String.Length > DestSize) { - printf("ClearCopyStringNoFormatOrTerminate() call on line %d has been passed a buffer too small (%d bytes) to contain %ld-character string:\n" + Print(stdout, "ClearCopyStringNoFormatOrTerminate() call on line %d has been passed a buffer too small (%d bytes) to contain %ld-character string:\n" "%.*s\n", LineNumber, DestSize, String.Length, (int)String.Length, String.Base); __asm__("int3"); } @@ -4313,7 +4346,7 @@ CopyStringNoFormatT_(int LineNumber, char *Dest, int DestSize, char *String, cha } if(BytesToWrite >= DestSize) { - printf("CopyStringNoFormatT() call on line %d has been passed a buffer too small (%d bytes) to contain %c-terminated %d(+1)-character string:\n" + Print(stdout, "CopyStringNoFormatT() call on line %d has been passed a buffer too small (%d bytes) to contain %c-terminated %d(+1)-character string:\n" "%.*s\n", LineNumber, DestSize, Terminator == 0 ? '0' : Terminator, BytesToWrite, BytesToWrite, String); __asm__("int3"); } @@ -4333,7 +4366,7 @@ CopyStringToBuffer_(int LineNumber, buffer *Dest, char *Format, ...) va_end(Args); if(Length + (Dest->Ptr - Dest->Location) >= Dest->Size) { - fprintf(stderr, "CopyStringToBuffer(%s) call on line %d cannot accommodate null-terminated %d(+1)-character string:\n" + Print(stderr, "CopyStringToBuffer(%s) call on line %d cannot accommodate null-terminated %d(+1)-character string:\n" "%s\n", BufferIDStrings[Dest->ID], LineNumber, Length, Format); __asm__("int3"); } @@ -4368,9 +4401,9 @@ CopyTimecodeToBuffer_(int LineNumber, buffer *Dest, v3 Timecode) { if(DigitsInTimecode(Timecode) + (Dest->Ptr - Dest->Location) >= Dest->Size) { - fprintf(stderr, "CopyTimecodeToBuffer(%s) call on line %d cannot accommodate timecode:\n", BufferIDStrings[Dest->ID], LineNumber); + Print(stderr, "CopyTimecodeToBuffer(%s) call on line %d cannot accommodate timecode:\n", BufferIDStrings[Dest->ID], LineNumber); PrintTimecode(stderr, Timecode); - fprintf(stderr, "\n"); + Print(stderr, "\n"); __asm__("int3"); } else @@ -4392,7 +4425,7 @@ CopyStringToBufferNoFormat_(int LineNumber, buffer *Dest, string String) { if(String.Length + 1 > Dest->Size - (Dest->Ptr - Dest->Location)) { - fprintf(stderr, "CopyStringToBufferNoFormat(%s) call on line %d cannot accommodate %ld-character string:\n" + Print(stderr, "CopyStringToBufferNoFormat(%s) call on line %d cannot accommodate %ld-character string:\n" "%.*s\n", BufferIDStrings[Dest->ID], LineNumber, String.Length, (int)String.Length, String.Base); __asm__("int3"); } @@ -4406,7 +4439,7 @@ CopyStringToBufferNoTerminate_(int LineNumber, buffer *Dest, string Src) { if((Dest->Ptr - Dest->Location + Src.Length) > Dest->Size) { - fprintf(stderr, "CopyStringToBufferNoTerminate(%s) call on line %d cannot accommodate %ld-character string:\n" + Print(stderr, "CopyStringToBufferNoTerminate(%s) call on line %d cannot accommodate %ld-character string:\n" "%.*s\n", BufferIDStrings[Dest->ID], LineNumber, Src.Length, (int)Src.Length, Src.Base); __asm__("int3"); } @@ -4419,7 +4452,7 @@ CopyStringToBufferNoFormatL_(int LineNumber, buffer *Dest, int Length, char *Str { if(Dest->Ptr - Dest->Location + Length + 1 >= Dest->Size) { - fprintf(stderr, "CopyStringToBufferNoFormat(%s) call on line %d cannot accommodate %ld(+1)-character string:\n" + Print(stderr, "CopyStringToBufferNoFormat(%s) call on line %d cannot accommodate %ld(+1)-character string:\n" "%s\n", BufferIDStrings[Dest->ID], LineNumber, StringLength(String), String); __asm__("int3"); } @@ -4445,7 +4478,7 @@ CopyStringToBufferHTMLSafe_(int LineNumber, buffer *Dest, string String) if((Dest->Ptr - Dest->Location) + Length >= Dest->Size) { - fprintf(stderr, "CopyStringToBufferHTMLSafe(%s) call on line %d cannot accommodate %d(+1)-character HTML-sanitised string:\n" + Print(stderr, "CopyStringToBufferHTMLSafe(%s) call on line %d cannot accommodate %d(+1)-character HTML-sanitised string:\n" "%.*s\n", BufferIDStrings[Dest->ID], LineNumber, Length, (int)String.Length, String.Base); __asm__("int3"); } @@ -4495,7 +4528,7 @@ CopyStringToBufferHTMLSafeBreakingOnSlash_(int LineNumber, buffer *Dest, string } if(Dest->Ptr - Dest->Location >= Dest->Size) { - fprintf(stderr, "CopyStringToBufferHTMLSafeBreakingOnSlash(%s) call on line %d cannot accommodate %d(+1)-character HTML-sanitised string:\n" + Print(stderr, "CopyStringToBufferHTMLSafeBreakingOnSlash(%s) call on line %d cannot accommodate %d(+1)-character HTML-sanitised string:\n" "%.*s\n", BufferIDStrings[Dest->ID], LineNumber, Length, (int)String.Length, String.Base); __asm__("int3"); } @@ -4530,7 +4563,7 @@ CopyStringToBufferHTMLPercentEncoded_(int LineNumber, buffer *Dest, string Strin if((Dest->Ptr - Dest->Location) + Length >= Dest->Size) { - fprintf(stderr, "CopyStringToBufferHTMLPercentEncodedL(%s) call on line %d cannot accommodate %d(+1)-character percent-encoded string:\n" + Print(stderr, "CopyStringToBufferHTMLPercentEncodedL(%s) call on line %d cannot accommodate %d(+1)-character percent-encoded string:\n" "%.*s\n", BufferIDStrings[Dest->ID], LineNumber, Length, (int)String.Length, String.Base); __asm__("int3"); } @@ -4564,7 +4597,7 @@ CopyBuffer_(int LineNumber, buffer *Dest, buffer *Src) { if((Dest->Ptr - Dest->Location + Src->Ptr - Src->Location) >= Dest->Size) { - fprintf(stderr, "CopyBuffer(%s) call on line %d cannot accommodate %ld(+1)-character %s\n", BufferIDStrings[Dest->ID], LineNumber, StringLength(Src->Location), BufferIDStrings[Src->ID]); + Print(stderr, "CopyBuffer(%s) call on line %d cannot accommodate %ld(+1)-character %s\n", BufferIDStrings[Dest->ID], LineNumber, StringLength(Src->Location), BufferIDStrings[Src->ID]); __asm__("int3"); } Dest->Ptr += CopyBytes(Dest->Ptr, Src->Location, Src->Ptr - Src->Location); @@ -4620,7 +4653,7 @@ CopyLandmarkedBuffer_(int LineNumber, buffer *Dest, buffer *Src, uint32_t *PrevS { if((Dest->Ptr - Dest->Location + Src->Ptr - Src->Location) >= Dest->Size) { - fprintf(stderr, "CopyLandmarkedBuffer(%s) call on line %d cannot accommodate %ld(+1)-character %s\n", BufferIDStrings[Dest->ID], LineNumber, StringLength(Src->Location), BufferIDStrings[Src->ID]); + Print(stderr, "CopyLandmarkedBuffer(%s) call on line %d cannot accommodate %ld(+1)-character %s\n", BufferIDStrings[Dest->ID], LineNumber, StringLength(Src->Location), BufferIDStrings[Src->ID]); __asm__("int3"); } @@ -4638,7 +4671,7 @@ CopyBufferSized_(int LineNumber, buffer *Dest, buffer *Src, uint64_t Size) // NOTE(matt): Similar to CopyBuffer(), just without null-terminating if((Dest->Ptr - Dest->Location + Size) > Dest->Size) { - fprintf(stderr, "CopyBufferSized(%s) call on line %d cannot accommodate %ld-character %s\n", BufferIDStrings[Dest->ID], LineNumber, Size, BufferIDStrings[Src->ID]); + Print(stderr, "CopyBufferSized(%s) call on line %d cannot accommodate %ld-character %s\n", BufferIDStrings[Dest->ID], LineNumber, Size, BufferIDStrings[Src->ID]); __asm__("int3"); } Dest->Ptr += CopyBytes(Dest->Ptr, Src->Location, Size); @@ -5005,7 +5038,7 @@ InitTemplate(template *Template, string Location, template_type Type) Template->File = InitFile(Type == TEMPLATE_BESPOKE ? &CurrentProject->HMMLDir : &CurrentProject->TemplatesDir, &Location, EXT_NULL, FALSE); } } - fprintf(stderr, "%sPacking%s template: %s\n", ColourStrings[CS_ONGOING], ColourStrings[CS_END], Template->File.Path); + Print(stderr, "%sPacking%s template: %s\n", ColourStrings[CS_ONGOING], ColourStrings[CS_END], Template->File.Path); ReadFileIntoBuffer(&Template->File); ClearTemplateMetadata(Template); Template->Metadata.Tags = InitBook(sizeof(tag_offset), 16); @@ -5290,7 +5323,7 @@ ClearTerminalRow(uint64_t Length) { for(uint64_t i = 0; i < Length; ++i) { - fprintf(stderr, "\b \b"); + Print(stderr, "\b \b"); } } @@ -5444,7 +5477,7 @@ BinarySearchForMetadataLandmark(db_asset *Asset, landmark_range ProjectRange, in void PrintEntryIndex(db_project_index Project, int64_t EntryIndex) { - fprintf(stderr, "%s%2i:%2i%s %s%3li%s", + Print(stderr, "%s%2i:%2i%s %s%3li%s", ColourStrings[CS_MAGENTA], Project.Generation, Project.Index, ColourStrings[CS_END], ColourStrings[CS_BLUE_BOLD], EntryIndex, ColourStrings[CS_END]); } @@ -5455,11 +5488,11 @@ PrintLandmark(db_landmark *L, uint16_t *Index) if(Index) { Colourise(CS_BLACK_BOLD); - fprintf(stderr, "[%4u] ", *Index); + Print(stderr, "[%4u] ", *Index); Colourise(CS_END); } PrintEntryIndex(L->Index.Project, L->Index.Entry); - fprintf(stderr, " %6u", L->Position); + Print(stderr, " %6u", L->Position); } void @@ -5468,11 +5501,11 @@ PrintAsset(db_asset *A, uint16_t *Index) if(Index) { Colourise(CS_BLACK_BOLD); - fprintf(stderr, "[%4u]", *Index); + Print(stderr, "[%4u]", *Index); Colourise(CS_END); } string FilenameL = Wrap0i(A->Filename); - fprintf(stderr, " %s asset: %.*s [%8x]\n", + Print(stderr, " %s asset: %.*s [%8x]\n", AssetTypeNames[A->Type], (int)FilenameL.Length, FilenameL.Base, A->Hash); if(A->Type == ASSET_IMG) @@ -5484,30 +5517,30 @@ PrintAsset(db_asset *A, uint16_t *Index) int SpacesRequired = 1 + 1 + DigitsInInt(Index); for(int i = 0; i < SpacesRequired; ++i) { - fprintf(stderr, " "); + Print(stderr, " "); } } - fprintf(stderr, " Associated: "); + Print(stderr, " Associated: "); if(Associated) { PrintC(CS_GREEN, "true"); } else { PrintC(CS_RED, "false"); } - fprintf(stderr, " • Variants: "); + Print(stderr, " • Variants: "); Colourise(CS_BLUE_BOLD); - fprintf(stderr, "%lu", Variants); + Print(stderr, "%lu", Variants); Colourise(CS_END); - fprintf(stderr, " • Dimensions: "); + Print(stderr, " • Dimensions: "); Colourise(CS_BLUE_BOLD); - fprintf(stderr, "%u", A->Width); - fprintf(stderr, "×"); - fprintf(stderr, "%u", A->Height); + Print(stderr, "%u", A->Width); + Print(stderr, "×"); + Print(stderr, "%u", A->Height); Colourise(CS_END); - fprintf(stderr, "\n"); + Print(stderr, "\n"); } } void PrintAssetAndLandmarks(db_asset *A, uint16_t *Index) { - fprintf(stderr, "\n" + Print(stderr, "\n" "\n"); PrintAsset(A, Index); db_landmark *FirstLandmark = LocateFirstLandmark(A); @@ -5516,7 +5549,7 @@ PrintAssetAndLandmarks(db_asset *A, uint16_t *Index) db_landmark *This = FirstLandmark + i; if((i % 8) == 0) { - fprintf(stderr, "\n"); + Print(stderr, "\n"); } else { @@ -5524,7 +5557,7 @@ PrintAssetAndLandmarks(db_asset *A, uint16_t *Index) } PrintLandmark(This, &i); } - fprintf(stderr, "\n"); + Print(stderr, "\n"); } // TODO(matt): Almost definitely redo this using Locate*() functions... @@ -5619,7 +5652,7 @@ PrintGenerations(project_generations *G, bool IndicateCurrentGeneration) for(uint64_t i = 0; i < G->EntriesInGeneration.ItemCount; ++i) { uint32_t *This = GetPlaceInBook(&G->EntriesInGeneration, i); - fprintf(stderr, "%lu: %u%s\n", i, *This, IndicateCurrentGeneration && i == G->CurrentGeneration ? " [Current Generation]" : ""); + Print(stderr, "%lu: %u%s\n", i, *This, IndicateCurrentGeneration && i == G->CurrentGeneration ? " [Current Generation]" : ""); } } @@ -6015,7 +6048,7 @@ SnipeChecksumIntoHTML(db_asset *Asset, asset_hash Checksum) default: { Colourise(CS_RED); - fprintf(stderr, "SnipeChecksumIntoHTML() does not know about special page with index %i\n", Landmark->Index.Entry); + Print(stderr, "SnipeChecksumIntoHTML() does not know about special page with index %i\n", Landmark->Index.Entry); Colourise(CS_END); Assert(0); } break; @@ -6038,11 +6071,11 @@ SnipeChecksumIntoHTML(db_asset *Asset, asset_hash Checksum) void PrintWatchFile(watch_file *W) { - fprintf(stderr, "%s", WatchTypeStrings[W->Type]); - fprintf(stderr, " • "); + Print(stderr, "%s", WatchTypeStrings[W->Type]); + Print(stderr, " • "); if(W->Extension != EXT_NULL) { - fprintf(stderr, "*"); + Print(stderr, "*"); PrintString(ExtensionStrings[W->Extension]); } else @@ -6052,27 +6085,27 @@ PrintWatchFile(watch_file *W) if(W->Project) { - fprintf(stderr, " • "); + Print(stderr, " • "); PrintLineage(W->Project->Lineage, FALSE); } if(W->Asset) { - fprintf(stderr, " • "); - fprintf(stderr, "%s", AssetTypeNames[W->Asset->Type]); + Print(stderr, " • "); + Print(stderr, "%s", AssetTypeNames[W->Asset->Type]); } } void PrintWatchHandle(watch_handle *W) { - fprintf(stderr, "%4d", W->Descriptor); + Print(stderr, "%4d", W->Descriptor); - fprintf(stderr, " • "); + Print(stderr, " • "); if(StringsDiffer(W->TargetPath, W->WatchedPath)) { PrintStringC(CS_MAGENTA, W->WatchedPath); - fprintf(stderr, "\n "); + Print(stderr, "\n "); PrintStringC(CS_RED_BOLD, W->TargetPath); } else @@ -6083,7 +6116,7 @@ PrintWatchHandle(watch_handle *W) for(int i = 0; i < W->Files.ItemCount; ++i) { watch_file *This = GetPlaceInBook(&W->Files, i); - fprintf(stderr, "\n" + Print(stderr, "\n" " "); PrintWatchFile(This); } @@ -6106,16 +6139,16 @@ PrintWatchHandles_(int LineNumber) .Delimiter = ": ", .Separator = "•", }; - fprintf(stderr, "\n" + Print(stderr, "\n" "%s%s%s [%i] PrintWatchHandles()", T.UpperLeftCorner, T.Horizontal, T.UpperRight, LineNumber); for(int i = 0; i < WatchHandles.Handles.ItemCount; ++i) { watch_handle *This = GetPlaceInBook(&WatchHandles.Handles, i); - fprintf(stderr, "\n"); + Print(stderr, "\n"); PrintWatchHandle(This); } - fprintf(stderr, "\n" + Print(stderr, "\n" "%s%s%s", T.LowerLeftCorner, T.Horizontal, T.UpperRight); } @@ -6576,14 +6609,14 @@ UpdateAssetInDB(asset *Asset) " → ", ColourStrings[CS_BLUE_BOLD], NewChecksum, ColourStrings[CS_END], " of ", AssetFile.Path, " in HTML files"); - fprintf(stderr, "%.*s%.*s", (int)MessageEditType.Length, MessageEditType.Base, (int)Message.Length, Message.Base); + Print(stderr, "%.*s%.*s", (int)MessageEditType.Length, MessageEditType.Base, (int)Message.Length, Message.Base); uint64_t MessageLength = MessageEditType.Length + Message.Length; if(SnipeChecksumIntoHTML(StoredAsset, Asset->Hash) == RC_SUCCESS) { ClearTerminalRow(MessageLength); PrintC(CS_REINSERTION, "Updated"); - fprintf(stderr, "%.*s\n", (int)Message.Length, Message.Base); + Print(stderr, "%.*s\n", (int)Message.Length, Message.Base); } FreeString(&Message); @@ -6623,7 +6656,7 @@ UpdateAssetInDB(asset *Asset) fwrite(&StoredAsset, sizeof(StoredAsset), 1, DB.Metadata.File.Handle); AccumulateFileEditSize(&DB.Metadata, sizeof(StoredAsset)); - fprintf(stderr, "%sAppended%s %s asset: %s [%08x]\n", ColourStrings[CS_ADDITION], ColourStrings[CS_END], AssetTypeNames[StoredAsset.Type], StoredAsset.Filename, StoredAsset.Hash); + Print(stderr, "%sAppended%s %s asset: %s [%08x]\n", ColourStrings[CS_ADDITION], ColourStrings[CS_END], AssetTypeNames[StoredAsset.Type], StoredAsset.Filename, StoredAsset.Hash); fwrite(DB.Metadata.File.Buffer.Location + BytesIntoFile, DB.Metadata.File.Buffer.Size - BytesIntoFile, 1, DB.Metadata.File.Handle); @@ -6800,7 +6833,7 @@ PlaceAsset(string Filename, asset_type Type, uint64_t Variants, bool Associated, else { ResolvePath(&File.Path); - printf("%sNonexistent%s %s asset: %s\n", ColourStrings[CS_WARNING], ColourStrings[CS_END], AssetTypeNames[Type], File.Path); + Print(stdout, "%sNonexistent%s %s asset: %s\n", ColourStrings[CS_WARNING], ColourStrings[CS_END], AssetTypeNames[Type], File.Path); } FreeFile(&File, NA); @@ -6844,7 +6877,7 @@ InitBuiltinAssets(void) asset *This = BuiltinAssets + AssetIndex; if(!(PlaceAsset(Wrap0(This->Filename), This->Type, This->Variants, This->Associated, AssetIndex)) && AssetIndex == ASSET_CSS_TOPICS) { - printf( " %s└───────┴────┴─── Don't worry about this one. We'll generate it if needed%s\n", ColourStrings[CS_COMMENT], ColourStrings[CS_END]); + Print(stdout, " %s└───────┴────┴─── Don't worry about this one. We'll generate it if needed%s\n", ColourStrings[CS_COMMENT], ColourStrings[CS_END]); } } Assets.ItemCount = BUILTIN_ASSETS_COUNT; @@ -7415,12 +7448,12 @@ void ErrorCredentials(string HMMLFilepath, string Actor, role *Role) { ErrorFilenameAndLineNumber(&HMMLFilepath, 0, S_ERROR, ED_INDEXING); - fprintf(stderr, "No credentials for%s%s%.*s%s: %s%.*s%s\n", + Print(stderr, "No credentials for%s%s%.*s%s: %s%.*s%s\n", ColourStrings[CS_YELLOW_BOLD], Role ? " " : "", Role ? (int)Role->Name.Length : 0, Role ? Role->Name.Base : "", ColourStrings[CS_END], ColourStrings[CS_MAGENTA_BOLD], (int)Actor.Length, Actor.Base, ColourStrings[CS_END]); - fprintf(stderr, "Perhaps you'd like to add a new person to your config file, e.g.:\n" + Print(stderr, "Perhaps you'd like to add a new person to your config file, e.g.:\n" " person = \"%.*s\"\n" " {\n" " name = \"Jane Doe\";\n" @@ -7436,17 +7469,17 @@ ErrorRole(string HMMLFilepath, string Role) ErrorFilenameAndLineNumber(&HMMLFilepath, 0, S_ERROR, ED_INDEXING); if(Role.Length == 0) { - fprintf(stderr, "Credit lacks a role\n"); - fprintf(stderr, " A complete credit takes the form:\n" + Print(stderr, "Credit lacks a role\n"); + Print(stderr, " A complete credit takes the form:\n" " credit = creditable_person:their_role\n"); } else { - fprintf(stderr, "No such role: %s%.*s%s\n", + Print(stderr, "No such role: %s%.*s%s\n", ColourStrings[CS_YELLOW_BOLD], (int)Role.Length, Role.Base, ColourStrings[CS_END]); - fprintf(stderr, "Perhaps you'd like to add a new role to your config file, e.g.:\n" + Print(stderr, "Perhaps you'd like to add a new role to your config file, e.g.:\n" " role = \"%.*s\"\n" " {\n" " name = \"Roller\";\n" @@ -7957,7 +7990,7 @@ CURLcode CurlQuotes(buffer *QuoteStaging, char *QuotesURL) { MEM_TEST_TOP(); - fprintf(stderr, "%sFetching%s quotes: %s\n", ColourStrings[CS_ONGOING], ColourStrings[CS_END], QuotesURL); + Print(stderr, "%sFetching%s quotes: %s\n", ColourStrings[CS_ONGOING], ColourStrings[CS_END], QuotesURL); CURLcode Result = CURLE_FAILED_INIT; CURL *curl = curl_easy_init(); @@ -7970,7 +8003,7 @@ CurlQuotes(buffer *QuoteStaging, char *QuotesURL) /* */ MEM_TEST_MID(); if(Result) { - fprintf(stderr, "%s\n", curl_easy_strerror(Result)); + Print(stderr, "%s\n", curl_easy_strerror(Result)); } curl_easy_cleanup(curl); curl = 0; @@ -8094,7 +8127,7 @@ BuildQuote(memory_book *Strings, quote_info *Info, string Speaker, int ID, bool else { // TODO(matt): SystemError(); - fprintf(stderr, "Unable to open quote cache %s: %s\n", QuoteCachePath, strerror(errno)); + Print(stderr, "Unable to open quote cache %s: %s\n", QuoteCachePath, strerror(errno)); } } @@ -8109,9 +8142,9 @@ BuildQuote(memory_book *Strings, quote_info *Info, string Speaker, int ID, bool { #if DEBUG_MEM FILE *MemLog = fopen("/home/matt/cinera_mem", "a+"); - fprintf(MemLog, " Allocated QuoteStaging (%ld)\n", QuoteStaging.Size); + WriteToFile(MemLog, " Allocated QuoteStaging (%ld)\n", QuoteStaging.Size); fclose(MemLog); - printf(" Allocated QuoteStaging (%ld)\n", QuoteStaging.Size); + Print(stdout, " Allocated QuoteStaging (%ld)\n", QuoteStaging.Size); #endif if(!ShouldFetchQuotes) @@ -8210,7 +8243,7 @@ GenerateTopicColours(neighbourhood *N, string Topic) if(!MakeDir(Wrap0(Topics.Path))) { LogError(LOG_ERROR, "Unable to create directory %s: %s", Topics.Path, strerror(errno)); - fprintf(stderr, "Unable to create directory %s: %s\n", Topics.Path, strerror(errno)); + Print(stderr, "Unable to create directory %s: %s\n", Topics.Path, strerror(errno)); Result = RC_ERROR_DIRECTORY; }; } @@ -8245,22 +8278,22 @@ GenerateTopicColours(neighbourhood *N, string Topic) { if(StringsMatch(Topic, Wrap0("nullTopic"))) { - fprintf(Topics.Handle, ".category.%s { border: 1px solid transparent; background: transparent; }\n", + WriteToFile(Topics.Handle, ".category.%s { border: 1px solid transparent; background: transparent; }\n", SanitisedTopic); } else { hsl_colour Colour; StringToColourHash(&Colour, Topic); - fprintf(Topics.Handle, ".category.%s { border: 1px solid hsl(%d, %d%%, %d%%); background: hsl(%d, %d%%, %d%%); }\n", + WriteToFile(Topics.Handle, ".category.%s { border: 1px solid hsl(%d, %d%%, %d%%); background: hsl(%d, %d%%, %d%%); }\n", SanitisedTopic, Colour.Hue, Colour.Saturation, Colour.Lightness, Colour.Hue, Colour.Saturation, Colour.Lightness); } #if DEBUG_MEM MemLog = fopen("/home/matt/cinera_mem", "a+"); - fprintf(MemLog, " Freed Topics (%ld)\n", Topics.Buffer.Size); + WriteToFile(MemLog, " Freed Topics (%ld)\n", Topics.Buffer.Size); fclose(MemLog); - printf(" Freed Topics (%ld)\n", Topics.Buffer.Size); + Print(stdout, " Freed Topics (%ld)\n", Topics.Buffer.Size); #endif CloseFile(&Topics, NA); @@ -8314,21 +8347,21 @@ PrintHelpConfig(void) NewSection("Assigning values", &IndentationLevel); PrintC(CS_YELLOW_BOLD, "identifier"); - fprintf(stderr, " = "); + Print(stderr, " = "); PrintC(CS_GREEN_BOLD, "\"string\""); - fprintf(stderr, ";"); + Print(stderr, ";"); IndentedCarriageReturn(IndentationLevel); PrintC(CS_YELLOW_BOLD, "identifier"); - fprintf(stderr, " = "); + Print(stderr, " = "); PrintC(CS_BLUE_BOLD, "number"); - fprintf(stderr, ";"); + Print(stderr, ";"); IndentedCarriageReturn(IndentationLevel); PrintC(CS_YELLOW_BOLD, "identifier"); - fprintf(stderr, " = "); + Print(stderr, " = "); PrintC(CS_GREEN_BOLD, "\"boolean\""); - fprintf(stderr, ";"); + Print(stderr, ";"); ++IndentationLevel; IndentedCarriageReturn(IndentationLevel); @@ -8337,12 +8370,12 @@ PrintHelpConfig(void) IndentedCarriageReturn(IndentationLevel); PrintC(CS_YELLOW_BOLD, "identifier"); - fprintf(stderr, " = "); + Print(stderr, " = "); PrintC(CS_GREEN_BOLD, "\"scope\""); - fprintf(stderr, " {"); + Print(stderr, " {"); IndentedCarriageReturn(IndentationLevel); - fprintf(stderr, "}\n"); + Print(stderr, "}\n"); EndSection(&IndentationLevel); @@ -8361,7 +8394,7 @@ scope, which is absorbed by a project, only gets resolved as if it had been writ //FreeTypeSpecs(&TypeSpecs); EndSection(&IndentationLevel); - fprintf(stderr, "\n"); + Print(stderr, "\n"); NewSection("Variables", &IndentationLevel); TypesetString(INDENT_WIDTH * IndentationLevel, Wrap0("We write variables the same way as in shell scripts like bash, zsh, etc.")); @@ -8391,14 +8424,14 @@ scope, which is absorbed by a project, only gets resolved as if it had been writ } EndSection(&IndentationLevel); - fprintf(stderr, "\n"); + Print(stderr, "\n"); NewSection("Environment variables", &IndentationLevel); TypesetString(INDENT_WIDTH *IndentationLevel, Wrap0("Run `export` to see all available environment variables")); EndSection(&IndentationLevel); EndSection(&IndentationLevel); // Variables - fprintf(stderr, "\n"); + Print(stderr, "\n"); NewSection("Miscellaneous", &IndentationLevel); TypesetString(INDENT_WIDTH * IndentationLevel, Wrap0("We may use C-style comments, single-line with // and multi-line with /* and */")); NewParagraph(IndentationLevel); @@ -8413,7 +8446,7 @@ enable syntax highlighting:")); EndSection(&IndentationLevel); - fprintf(stderr, "\n"); + Print(stderr, "\n"); #if 1 // numbering_scheme // linear @@ -8436,7 +8469,7 @@ enable syntax highlighting:")); FreeScopeTree(ScopeTree); FreeTypeSpecs(&TypeSpecs); #endif - fprintf(stderr, "\n"); + Print(stderr, "\n"); } #define PrintHelp() PrintHelp_(Args[0], ConfigPath) @@ -8444,7 +8477,7 @@ void PrintHelp_(char *BinaryLocation, char *DefaultConfigPath) { // Options - fprintf(stderr, + Print(stderr, "Usage: %s [option(s)]\n" "\n" "Options:\n" @@ -8467,7 +8500,7 @@ void PrintHelp_Old(char *BinaryLocation) { #if AFE - fprintf(stderr, + Print(stderr, "Usage: %s [option(s)] filename(s)\n" "\n" "Options:\n" @@ -8512,20 +8545,20 @@ PrintHelp_Old(char *BinaryLocation) for(int ProjectIndex = 0; ProjectIndex < ArrayCount(ProjectInfo); ++ProjectIndex) { - fprintf(stderr, " %s:", + Print(stderr, " %s:", ProjectInfo[ProjectIndex].ProjectID); // NOTE(matt): This kind of thing really needs to loop over the dudes once to find the longest one for(int i = 11; i > StringLength(ProjectInfo[ProjectIndex].ProjectID); i -= 4) { - fprintf(stderr, "\t"); + Print(stderr, "\t"); } - fprintf(stderr, "%s\n", + Print(stderr, "%s\n", ProjectInfo[ProjectIndex].Medium); } - fprintf(stderr, + Print(stderr, "%s -s