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.
This commit is contained in:
Matt Mascarenhas 2023-01-13 20:31:44 +00:00
parent 1280142d45
commit 6576a91d11
2 changed files with 723 additions and 618 deletions

File diff suppressed because it is too large Load Diff

View File

@ -113,20 +113,20 @@ MakeString_(char *Filename, int LineNumber, char *Format, int ArgCount, ...)
int FormatLength = StringLength(Format); int FormatLength = StringLength(Format);
if(FormatLength != ArgCount) if(FormatLength != ArgCount)
{ {
Colourise(CS_FAILURE); fprintf(stderr, "%s:%d MakeString()", Filename, LineNumber); Colourise(CS_END); Colourise(CS_FAILURE); Print(stderr, "%s:%d MakeString()", Filename, LineNumber); Colourise(CS_END);
fprintf(stderr, Print(stderr,
"\n" "\n"
" MakeString() has been passed a format string containing "); " MakeString() has been passed a format string containing ");
Colourise(CS_BLUE_BOLD); fprintf(stderr, "%d specifier%s", FormatLength, FormatLength == 1 ? "" : "s"); Colourise(CS_END); Colourise(CS_BLUE_BOLD); Print(stderr, "%d specifier%s", FormatLength, FormatLength == 1 ? "" : "s"); Colourise(CS_END);
fprintf(stderr, Print(stderr,
",\n" ",\n"
" and "); " and ");
Colourise(CS_BLUE_BOLD); fprintf(stderr, "%d argument%s", ArgCount, ArgCount == 1 ? "" : "s"); Colourise(CS_END); Colourise(CS_BLUE_BOLD); Print(stderr, "%d argument%s", ArgCount, ArgCount == 1 ? "" : "s"); Colourise(CS_END);
fprintf(stderr, ", but these numbers should be equal.\n"); Print(stderr, ", but these numbers should be equal.\n");
__asm__("int3"); __asm__("int3");
} }
@ -161,8 +161,8 @@ MakeString_(char *Filename, int LineNumber, char *Format, int ArgCount, ...)
} break; } break;
default: default:
{ {
Colourise(CS_FAILURE); fprintf(stderr, "%s:%d", Filename, LineNumber); Colourise(CS_END); Colourise(CS_FAILURE); Print(stderr, "%s:%d", Filename, LineNumber); Colourise(CS_END);
fprintf(stderr, "\n" Print(stderr, "\n"
" MakeString() has been passed an unsupported format specifier: %c\n", Format[i]); " MakeString() has been passed an unsupported format specifier: %c\n", Format[i]);
__asm__("int3"); __asm__("int3");
} break; } break;
@ -197,20 +197,20 @@ MakeString0_(char *Filename, int LineNumber, char *Format, int ArgCount, ...)
int FormatLength = StringLength(Format); int FormatLength = StringLength(Format);
if(FormatLength != ArgCount) if(FormatLength != ArgCount)
{ {
Colourise(CS_FAILURE); fprintf(stderr, "%s:%d MakeString0()", Filename, LineNumber); Colourise(CS_END); Colourise(CS_FAILURE); Print(stderr, "%s:%d MakeString0()", Filename, LineNumber); Colourise(CS_END);
fprintf(stderr, Print(stderr,
"\n" "\n"
" MakeString0() has been passed a format string containing "); " MakeString0() has been passed a format string containing ");
Colourise(CS_BLUE_BOLD); fprintf(stderr, "%d specifier%s", FormatLength, FormatLength == 1 ? "" : "s"); Colourise(CS_END); Colourise(CS_BLUE_BOLD); Print(stderr, "%d specifier%s", FormatLength, FormatLength == 1 ? "" : "s"); Colourise(CS_END);
fprintf(stderr, Print(stderr,
",\n" ",\n"
" and "); " and ");
Colourise(CS_BLUE_BOLD); fprintf(stderr, "%d argument%s", ArgCount, ArgCount == 1 ? "" : "s"); Colourise(CS_END); Colourise(CS_BLUE_BOLD); Print(stderr, "%d argument%s", ArgCount, ArgCount == 1 ? "" : "s"); Colourise(CS_END);
fprintf(stderr, ", but these numbers should be equal.\n"); Print(stderr, ", but these numbers should be equal.\n");
__asm__("int3"); __asm__("int3");
} }
@ -264,8 +264,8 @@ MakeString0_(char *Filename, int LineNumber, char *Format, int ArgCount, ...)
} break; } break;
default: default:
{ {
Colourise(CS_FAILURE); fprintf(stderr, "%s:%d", Filename, LineNumber); Colourise(CS_END); Colourise(CS_FAILURE); Print(stderr, "%s:%d", Filename, LineNumber); Colourise(CS_END);
fprintf(stderr, "\n" Print(stderr, "\n"
" MakeString0() has been passed an unsupported format specifier: %c\n", Format[i]); " MakeString0() has been passed an unsupported format specifier: %c\n", Format[i]);
__asm__("int3"); __asm__("int3");
} break; } break;
@ -304,11 +304,11 @@ PushToken(tokens *Set, token *Token)
void void
PrintToken(token *T, uint64_t Index) PrintToken(token *T, uint64_t Index)
{ {
fprintf(stderr, "[%lu, %s] ", Index, TokenTypeStrings[T->Type]); Print(stderr, "[%lu, %s] ", Index, TokenTypeStrings[T->Type]);
if(T->Type == TOKEN_NUMBER) if(T->Type == TOKEN_NUMBER)
{ {
Colourise(CS_BLUE_BOLD); Colourise(CS_BLUE_BOLD);
fprintf(stderr, "%li", T->int64_t); Print(stderr, "%li", T->int64_t);
Colourise(CS_END); Colourise(CS_END);
} }
@ -320,7 +320,7 @@ PrintToken(token *T, uint64_t Index)
{ {
PrintString(T->Content); PrintString(T->Content);
} }
fprintf(stderr, "\n"); Print(stderr, "\n");
} }
void void
@ -1094,7 +1094,7 @@ PrintTypeField(config_type_field *F, config_identifier_id ParentScopeID, int Ind
} }
else{ else{
Colourise(CS_GREEN_BOLD); Colourise(CS_GREEN_BOLD);
fprintf(stderr, "\"%s\"", FieldTypeNames[F->Type]); Print(stderr, "\"%s\"", FieldTypeNames[F->Type]);
Colourise(CS_END); Colourise(CS_END);
} }
PrintC(CS_BLACK_BOLD, ""); PrintC(CS_BLACK_BOLD, "");
@ -1190,7 +1190,7 @@ PrintTypeSpec(config_type_spec *S, int IndentationLevel)
void void
PrintTypeSpecs(memory_book *TypeSpecs, int IndentationLevel) PrintTypeSpecs(memory_book *TypeSpecs, int IndentationLevel)
{ {
fprintf(stderr, "\n"); Print(stderr, "\n");
// TODO(matt): Document the fact that scopes within scopes are fully configurable, even though // TODO(matt): Document the fact that scopes within scopes are fully configurable, even though
// we only print out the "id" of scopes, omitting their containing fields // we only print out the "id" of scopes, omitting their containing fields
for(int i = 0; i < TypeSpecs->ItemCount; ++i) for(int i = 0; i < TypeSpecs->ItemCount; ++i)
@ -1453,28 +1453,28 @@ FreeScopeTree(scope_tree *T)
void void
PrintPair(config_pair *P, char *Delimiter, bool FillSyntax, uint64_t Indentation, bool PrependNewline, bool AppendNewline) PrintPair(config_pair *P, char *Delimiter, bool FillSyntax, uint64_t Indentation, bool PrependNewline, bool AppendNewline)
{ {
if(PrependNewline) { fprintf(stderr, "\n"); } if(PrependNewline) { Print(stderr, "\n"); }
Indent(Indentation); Indent(Indentation);
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[P->Key].String); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[P->Key].String);
fprintf(stderr, "%s", Delimiter); Print(stderr, "%s", Delimiter);
if(P->Type == PT_BOOL) if(P->Type == PT_BOOL)
{ {
if(P->bool == TRUE) if(P->bool == TRUE)
{ {
Colourise(CS_GREEN); Colourise(CS_GREEN);
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
fprintf(stderr, "true"); Print(stderr, "true");
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
} }
else else
{ {
Colourise(CS_RED); Colourise(CS_RED);
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
fprintf(stderr, "false"); Print(stderr, "false");
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
} }
Colourise(CS_END); Colourise(CS_END);
if(FillSyntax) { fprintf(stderr, ";"); } if(FillSyntax) { Print(stderr, ";"); }
} }
else if(P->Type == PT_INT64) else if(P->Type == PT_INT64)
{ {
@ -1483,68 +1483,68 @@ PrintPair(config_pair *P, char *Delimiter, bool FillSyntax, uint64_t Indentation
case IDENT_GENRE: case IDENT_GENRE:
{ {
Colourise(CS_GREEN_BOLD); Colourise(CS_GREEN_BOLD);
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
fprintf(stderr, "%s", GenreStrings[P->int64_t]); Print(stderr, "%s", GenreStrings[P->int64_t]);
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
} break; } break;
case IDENT_LOG_LEVEL: case IDENT_LOG_LEVEL:
{ {
Colourise(CS_GREEN_BOLD); Colourise(CS_GREEN_BOLD);
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
fprintf(stderr, "%s", LogLevelStrings[P->int64_t]); Print(stderr, "%s", LogLevelStrings[P->int64_t]);
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
} break; } break;
case IDENT_NUMBERING_SCHEME: case IDENT_NUMBERING_SCHEME:
{ {
Colourise(CS_GREEN_BOLD); Colourise(CS_GREEN_BOLD);
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
fprintf(stderr, "%s", NumberingSchemeStrings[P->int64_t]); Print(stderr, "%s", NumberingSchemeStrings[P->int64_t]);
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
} break; } break;
default: default:
{ {
Colourise(CS_BLUE_BOLD); Colourise(CS_BLUE_BOLD);
fprintf(stderr, "%li", P->int64_t); Print(stderr, "%li", P->int64_t);
} break; } break;
} }
Colourise(CS_END); Colourise(CS_END);
if(FillSyntax) { fprintf(stderr, ";"); } if(FillSyntax) { Print(stderr, ";"); }
} }
else if(P->Type == PT_STRING) else if(P->Type == PT_STRING)
{ {
if(P->String.Length) if(P->String.Length)
{ {
Colourise(CS_GREEN_BOLD); Colourise(CS_GREEN_BOLD);
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
PrintString(P->String); PrintString(P->String);
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
Colourise(CS_END); Colourise(CS_END);
if(FillSyntax) { fprintf(stderr, ";"); } if(FillSyntax) { Print(stderr, ";"); }
} }
else else
{ {
PrintC(CS_YELLOW, "[unset]"); PrintC(CS_YELLOW, "[unset]");
} }
} }
if(AppendNewline) { fprintf(stderr, "\n"); } if(AppendNewline) { Print(stderr, "\n"); }
} }
void void
PrintScopeID(config_pair *P, char *Delimiter, uint64_t Indentation) PrintScopeID(config_pair *P, char *Delimiter, uint64_t Indentation)
{ {
fprintf(stderr, "\n"); Print(stderr, "\n");
Indent(Indentation); Indent(Indentation);
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[P->Key].String); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[P->Key].String);
fprintf(stderr, "%s", Delimiter); Print(stderr, "%s", Delimiter);
if(P->String.Length) if(P->String.Length)
{ {
Colourise(CS_GREEN_BOLD); Colourise(CS_GREEN_BOLD);
fprintf(stderr, "\""); Print(stderr, "\"");
PrintString(P->String); PrintString(P->String);
fprintf(stderr, "\""); Print(stderr, "\"");
Colourise(CS_END); Colourise(CS_END);
IndentedCarriageReturn(Indentation); IndentedCarriageReturn(Indentation);
fprintf(stderr, "{"); Print(stderr, "{");
} }
else else
{ {
@ -1555,26 +1555,26 @@ PrintScopeID(config_pair *P, char *Delimiter, uint64_t Indentation)
void void
PrintBool(char *Title, bool Bool, char *Delimiter, bool FillSyntax, uint64_t Indentation, bool PrependNewline, bool AppendNewline) PrintBool(char *Title, bool Bool, char *Delimiter, bool FillSyntax, uint64_t Indentation, bool PrependNewline, bool AppendNewline)
{ {
if(PrependNewline) { fprintf(stderr, "\n"); } if(PrependNewline) { Print(stderr, "\n"); }
Indent(Indentation); Indent(Indentation);
PrintC(CS_YELLOW_BOLD, Title); PrintC(CS_YELLOW_BOLD, Title);
fprintf(stderr, "%s", Delimiter); Print(stderr, "%s", Delimiter);
if(Bool == TRUE) if(Bool == TRUE)
{ {
Colourise(CS_GREEN); Colourise(CS_GREEN);
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
fprintf(stderr, "true"); Print(stderr, "true");
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
} }
else else
{ {
Colourise(CS_RED); Colourise(CS_RED);
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
fprintf(stderr, "false"); Print(stderr, "false");
if(FillSyntax) { fprintf(stderr, "\""); } if(FillSyntax) { Print(stderr, "\""); }
} }
Colourise(CS_END); Colourise(CS_END);
if(AppendNewline) { fprintf(stderr, "\n"); } if(AppendNewline) { Print(stderr, "\n"); }
} }
void PrintScopeTree(scope_tree *T, int IndentationLevel); void PrintScopeTree(scope_tree *T, int IndentationLevel);
@ -1602,7 +1602,7 @@ PrintScopeTree(scope_tree *T, int IndentationLevel)
{ {
--IndentationLevel; --IndentationLevel;
IndentedCarriageReturn(IndentationLevel); IndentedCarriageReturn(IndentationLevel);
fprintf(stderr, "}"); Print(stderr, "}");
} }
} }
} }
@ -1982,7 +1982,7 @@ ParseIncludeRules(memory_book *TypeSpecs, config_type_spec *ParentTypeSpec, toke
{ {
token *This = GetPlaceInBook(&T->Token, T->CurrentIndex); token *This = GetPlaceInBook(&T->Token, T->CurrentIndex);
ConfigError(&Filepath, This->LineNumber, S_WARNING, "Invalid identifier in \"include\" scope: ", &This->Content); ConfigError(&Filepath, This->LineNumber, S_WARNING, "Invalid identifier in \"include\" scope: ", &This->Content);
fprintf(stderr, Print(stderr,
" Valid identifiers:\n" " Valid identifiers:\n"
" allow\n" " allow\n"
" deny\n"); " deny\n");
@ -4013,11 +4013,11 @@ PrintAssociationClashes(config_string_associations *A)
config_pair Assoc1 = { .Key = A->ID1, .String = Association->String1, .Type = PT_STRING }; config_pair Assoc1 = { .Key = A->ID1, .String = Association->String1, .Type = PT_STRING };
PrintPair(&Assoc1, ": ", FALSE, IndentLevel, TRUE, FALSE); PrintPair(&Assoc1, ": ", FALSE, IndentLevel, TRUE, FALSE);
} }
fprintf(stderr, "\n"); Print(stderr, "\n");
for(int j = 0; j < Association->Projects.ItemCount; ++j) for(int j = 0; j < Association->Projects.ItemCount; ++j)
{ {
project **P = GetPlaceInBook(&Association->Projects, j); project **P = GetPlaceInBook(&Association->Projects, j);
fprintf(stderr, " "); Print(stderr, " ");
if(*P) if(*P)
{ {
PrintStringC(CS_CYAN, (*P)->Lineage); PrintStringC(CS_CYAN, (*P)->Lineage);
@ -4032,7 +4032,7 @@ PrintAssociationClashes(config_string_associations *A)
} }
PrintStringC(CS_RED, Wrap0("]")); PrintStringC(CS_RED, Wrap0("]"));
} }
fprintf(stderr, "\n"); Print(stderr, "\n");
} }
} }
} }
@ -4056,11 +4056,11 @@ PrintVariants(uint64_t V, colour_code ColourCode, string Margin)
int Length = StringLength(String); int Length = StringLength(String);
if(RunningAvailableColumns - Length >= 0) if(RunningAvailableColumns - Length >= 0)
{ {
fprintf(stderr, "%s", NeedsSpacing ? " " : ""); Print(stderr, "%s", NeedsSpacing ? " " : "");
} }
else else
{ {
fprintf(stderr, "\n"); Print(stderr, "\n");
PrintString(Margin); PrintString(Margin);
NeedsSpacing = FALSE; NeedsSpacing = FALSE;
RunningAvailableColumns = AvailableColumnsForValue; RunningAvailableColumns = AvailableColumnsForValue;
@ -4091,7 +4091,7 @@ PrintVariantInconsistencies(memory_book *VariantStrings)
string Margin = Wrap0(" "); string Margin = Wrap0(" ");
variant V = *(variant *)GetPlaceInBook(&ThisVariantsString->Variants, j); variant V = *(variant *)GetPlaceInBook(&ThisVariantsString->Variants, j);
PrintVariants(V, j % 2 ? CS_CYAN_BOLD : CS_YELLOW_BOLD, Margin); PrintVariants(V, j % 2 ? CS_CYAN_BOLD : CS_YELLOW_BOLD, Margin);
fprintf(stderr, "\n"); Print(stderr, "\n");
} }
} }
} }
@ -4133,9 +4133,9 @@ PrintLogLevel(char *Title, log_level Level, char *Delimiter, uint64_t Indentatio
{ {
Indent(Indentation); Indent(Indentation);
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_LOG_LEVEL].String); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_LOG_LEVEL].String);
fprintf(stderr, "%s", Delimiter); Print(stderr, "%s", Delimiter);
PrintC(CS_GREEN_BOLD, LogLevelStrings[Level]); PrintC(CS_GREEN_BOLD, LogLevelStrings[Level]);
if(AppendNewline) { fprintf(stderr, "\n"); } if(AppendNewline) { Print(stderr, "\n"); }
} }
typedef struct typedef struct
@ -4157,14 +4157,14 @@ PrintVerticals(typography *T, int Count)
{ {
for(int i = 0; i < Count; ++i) for(int i = 0; i < Count; ++i)
{ {
fprintf(stderr, "%s", T->Vertical); Print(stderr, "%s", T->Vertical);
} }
} }
void void
CarriageReturn(typography *T, int VerticalsRequired) CarriageReturn(typography *T, int VerticalsRequired)
{ {
fprintf(stderr, "\n"); Print(stderr, "\n");
PrintVerticals(T, VerticalsRequired); PrintVerticals(T, VerticalsRequired);
} }
@ -4176,12 +4176,12 @@ TypesetIconType(typography *T, uint8_t Generation, icon_type Type, bool PrependN
// TODO(matt): Implement me, please! // TODO(matt): Implement me, please!
//CarriageReturn(T, Generation); //CarriageReturn(T, Generation);
//fprintf(stderr, "%s", T.Margin); //Print(stderr, "%s", T.Margin);
#if 0 #if 0
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_ICON_TYPE].String); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_ICON_TYPE].String);
fprintf(stderr, "%s", T.Delimiter); Print(stderr, "%s", T.Delimiter);
PrintC(CS_GREEN_BOLD, IconTypeStrings[Type]); PrintC(CS_GREEN_BOLD, IconTypeStrings[Type]);
fprintf(stderr, "\n"); Print(stderr, "\n");
#endif #endif
@ -4195,10 +4195,10 @@ TypesetIconType(typography *T, uint8_t Generation, icon_type Type, bool PrependN
++Result; ++Result;
} }
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
config_identifier_id Key = IDENT_ICON_TYPE; config_identifier_id Key = IDENT_ICON_TYPE;
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[Key].String); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[Key].String);
fprintf(stderr, "%s", T->Delimiter); Print(stderr, "%s", T->Delimiter);
if(Type == IT_DEFAULT_UNSET) if(Type == IT_DEFAULT_UNSET)
{ {
PrintC(CS_YELLOW, "[unset]"); PrintC(CS_YELLOW, "[unset]");
@ -4229,17 +4229,17 @@ TypesetVariants(typography *T, uint8_t Generation, config_identifier_id Key, uin
if(RowsRequired) if(RowsRequired)
{ {
fprintf(stderr, "%s%s ", *RowsRequired == 1 ? T->LowerLeft : T->Vertical, T->Margin); Print(stderr, "%s%s ", *RowsRequired == 1 ? T->LowerLeft : T->Vertical, T->Margin);
} }
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
int CharactersInKeyPlusDelimiter = StringLength(ConfigIdentifiers[Key].String) + StringLength(T->Delimiter); int CharactersInKeyPlusDelimiter = StringLength(ConfigIdentifiers[Key].String) + StringLength(T->Delimiter);
int AvailableColumnsForValue = AvailableColumns - CharactersInKeyPlusDelimiter; int AvailableColumnsForValue = AvailableColumns - CharactersInKeyPlusDelimiter;
int RunningAvailableColumns = AvailableColumnsForValue; int RunningAvailableColumns = AvailableColumnsForValue;
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[Key].String); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[Key].String);
fprintf(stderr, "%s", T->Delimiter); Print(stderr, "%s", T->Delimiter);
bool NeedsSpacing = FALSE; bool NeedsSpacing = FALSE;
if(Value) if(Value)
@ -4252,7 +4252,7 @@ TypesetVariants(typography *T, uint8_t Generation, config_identifier_id Key, uin
int Length = StringLength(String); int Length = StringLength(String);
if(RunningAvailableColumns - Length >= 0) if(RunningAvailableColumns - Length >= 0)
{ {
fprintf(stderr, "%s", NeedsSpacing ? " " : ""); Print(stderr, "%s", NeedsSpacing ? " " : "");
} }
else else
{ {
@ -4260,12 +4260,12 @@ TypesetVariants(typography *T, uint8_t Generation, config_identifier_id Key, uin
if(RowsRequired) if(RowsRequired)
{ {
--*RowsRequired; --*RowsRequired;
fprintf(stderr, "%s%s ", *RowsRequired == 1 ? T->LowerLeft : T->Vertical, T->Margin); Print(stderr, "%s%s ", *RowsRequired == 1 ? T->LowerLeft : T->Vertical, T->Margin);
} }
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
for(int i = 0; i < CharactersInKeyPlusDelimiter; ++i) for(int i = 0; i < CharactersInKeyPlusDelimiter; ++i)
{ {
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
} }
NeedsSpacing = FALSE; NeedsSpacing = FALSE;
RunningAvailableColumns = AvailableColumnsForValue; RunningAvailableColumns = AvailableColumnsForValue;
@ -4295,9 +4295,9 @@ PrintMedium(typography *T, medium *M, char *Delimiter, uint64_t Indentation, boo
{ {
PrintC(CS_BLACK_BOLD, " [hidden]"); PrintC(CS_BLACK_BOLD, " [hidden]");
} }
fprintf(stderr, "%s", Delimiter); Print(stderr, "%s", Delimiter);
PrintStringC(CS_MAGENTA, M->Name); PrintStringC(CS_MAGENTA, M->Name);
fprintf(stderr, " ("); Print(stderr, " (");
if(M->Icon.Length > 0) if(M->Icon.Length > 0)
{ {
PrintStringI(M->Icon, Indentation); PrintStringI(M->Icon, Indentation);
@ -4312,10 +4312,10 @@ PrintMedium(typography *T, medium *M, char *Delimiter, uint64_t Indentation, boo
} }
TypesetIconType(T, Indentation, M->IconType, FALSE, AppendNewline); TypesetIconType(T, Indentation, M->IconType, FALSE, AppendNewline);
TypesetVariants(T, Indentation, IDENT_ICON_VARIANTS, M->IconVariants, 0, 0, FALSE, AppendNewline); TypesetVariants(T, Indentation, IDENT_ICON_VARIANTS, M->IconVariants, 0, 0, FALSE, AppendNewline);
fprintf(stderr, ")"); Print(stderr, ")");
if(AppendNewline) if(AppendNewline)
{ {
fprintf(stderr, "\n"); Print(stderr, "\n");
} }
} }
@ -4324,13 +4324,13 @@ PrintSupport(support *S, typography *Typography, int IndentationLevel, uint8_t *
{ {
bool ShouldFillSyntax = FALSE; bool ShouldFillSyntax = FALSE;
config_pair ID = { .Key = IDENT_SUPPORT, .String = S->ID, .Type = PT_STRING }; config_pair ID = { .Key = IDENT_SUPPORT, .String = S->ID, .Type = PT_STRING };
fprintf(stderr, "%s%s", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin); Print(stderr, "%s%s", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin);
PrintPair(&ID, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); PrintPair(&ID, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--*RowsRequired; --*RowsRequired;
if(S->URL.Length > 0) if(S->URL.Length > 0)
{ {
config_pair URL = { .Key = IDENT_URL, .String = S->URL, .Type = PT_STRING }; config_pair URL = { .Key = IDENT_URL, .String = S->URL, .Type = PT_STRING };
fprintf(stderr, "%s%s ", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin); Print(stderr, "%s%s ", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin);
PrintPair(&URL, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); PrintPair(&URL, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--*RowsRequired; --*RowsRequired;
} }
@ -4338,28 +4338,28 @@ PrintSupport(support *S, typography *Typography, int IndentationLevel, uint8_t *
if(S->Icon.Length > 0) if(S->Icon.Length > 0)
{ {
config_pair Icon = { .Key = IDENT_ICON, .String = S->Icon, .Type = PT_STRING }; config_pair Icon = { .Key = IDENT_ICON, .String = S->Icon, .Type = PT_STRING };
fprintf(stderr, "%s%s ", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin); Print(stderr, "%s%s ", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin);
PrintPair(&Icon, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); PrintPair(&Icon, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--*RowsRequired; --*RowsRequired;
} }
if(S->IconNormal.Length > 0) if(S->IconNormal.Length > 0)
{ {
config_pair IconNormal = { .Key = IDENT_ICON_NORMAL, .String = S->IconNormal, .Type = PT_STRING }; config_pair IconNormal = { .Key = IDENT_ICON_NORMAL, .String = S->IconNormal, .Type = PT_STRING };
fprintf(stderr, "%s%s ", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin); Print(stderr, "%s%s ", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin);
PrintPair(&IconNormal, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); PrintPair(&IconNormal, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--*RowsRequired; --*RowsRequired;
} }
if(S->IconFocused.Length > 0) if(S->IconFocused.Length > 0)
{ {
config_pair IconFocused = { .Key = IDENT_ICON_FOCUSED, .String = S->IconFocused, .Type = PT_STRING }; config_pair IconFocused = { .Key = IDENT_ICON_FOCUSED, .String = S->IconFocused, .Type = PT_STRING };
fprintf(stderr, "%s%s ", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin); Print(stderr, "%s%s ", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin);
PrintPair(&IconFocused, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); PrintPair(&IconFocused, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--*RowsRequired; --*RowsRequired;
} }
#if 1 #if 1
// TODO(matt): FIX ME // TODO(matt): FIX ME
fprintf(stderr, "%s%s ", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin); Print(stderr, "%s%s ", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin);
*RowsRequired -= TypesetIconType(Typography, IndentationLevel, S->IconType, FALSE, TRUE); *RowsRequired -= TypesetIconType(Typography, IndentationLevel, S->IconType, FALSE, TRUE);
uint8_t StartingColumn = 4; uint8_t StartingColumn = 4;
uint64_t AvailableColumns = GetTerminalColumns() - StartingColumn; uint64_t AvailableColumns = GetTerminalColumns() - StartingColumn;
@ -4424,11 +4424,11 @@ void
PrintPerson(person *P, typography *Typography) PrintPerson(person *P, typography *Typography)
{ {
bool HaveInfo = P->Name.Length > 0 || P->Homepage.Length > 0 || P->Support.ItemCount > 0; bool HaveInfo = P->Name.Length > 0 || P->Homepage.Length > 0 || P->Support.ItemCount > 0;
fprintf(stderr, "\n" Print(stderr, "\n"
"%s%s%s%s%s ", HaveInfo ? Typography->UpperLeftCorner : Typography->UpperLeft, "%s%s%s%s%s ", HaveInfo ? Typography->UpperLeftCorner : Typography->UpperLeft,
Typography->Horizontal, Typography->Horizontal, Typography->Horizontal, Typography->UpperRight); Typography->Horizontal, Typography->Horizontal, Typography->Horizontal, Typography->UpperRight);
PrintStringC(CS_GREEN_BOLD, P->ID); PrintStringC(CS_GREEN_BOLD, P->ID);
fprintf(stderr, "\n"); Print(stderr, "\n");
uint8_t RowsRequired = GetRowsRequiredForPersonInfo(Typography, P); uint8_t RowsRequired = GetRowsRequiredForPersonInfo(Typography, P);
@ -4436,35 +4436,35 @@ PrintPerson(person *P, typography *Typography)
bool ShouldFillSyntax = FALSE; bool ShouldFillSyntax = FALSE;
if(P->Name.Length > 0) if(P->Name.Length > 0)
{ {
fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); Print(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical);
config_pair Name = { .Key = IDENT_NAME, .String = P->Name, .Type = PT_STRING }; PrintPair(&Name, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); config_pair Name = { .Key = IDENT_NAME, .String = P->Name, .Type = PT_STRING }; PrintPair(&Name, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--RowsRequired; --RowsRequired;
} }
if(P->Abbreviations[AS_INITIAL].Length > 0) if(P->Abbreviations[AS_INITIAL].Length > 0)
{ {
fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); Print(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical);
config_pair AbbrevInitial = { .Key = IDENT_ABBREV_INITIAL, .String = P->Abbreviations[AS_INITIAL], .Type = PT_STRING }; PrintPair(&AbbrevInitial, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); config_pair AbbrevInitial = { .Key = IDENT_ABBREV_INITIAL, .String = P->Abbreviations[AS_INITIAL], .Type = PT_STRING }; PrintPair(&AbbrevInitial, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--RowsRequired; --RowsRequired;
} }
if(P->Abbreviations[AS_GIVEN_OR_NICKNAME].Length > 0) if(P->Abbreviations[AS_GIVEN_OR_NICKNAME].Length > 0)
{ {
fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); Print(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical);
config_pair AbbrevGivenOrNickname = { .Key = IDENT_ABBREV_GIVEN_OR_NICKNAME, .String = P->Abbreviations[AS_GIVEN_OR_NICKNAME], .Type = PT_STRING }; PrintPair(&AbbrevGivenOrNickname, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); config_pair AbbrevGivenOrNickname = { .Key = IDENT_ABBREV_GIVEN_OR_NICKNAME, .String = P->Abbreviations[AS_GIVEN_OR_NICKNAME], .Type = PT_STRING }; PrintPair(&AbbrevGivenOrNickname, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--RowsRequired; --RowsRequired;
} }
if(P->Abbreviations[AS_DOTTED_INITIAL_AND_SURNAME].Length > 0) if(P->Abbreviations[AS_DOTTED_INITIAL_AND_SURNAME].Length > 0)
{ {
fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); Print(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical);
config_pair AbbrevDottedInitialAndSurname = { .Key = IDENT_ABBREV_DOTTED_INITIAL_AND_SURNAME, .String = P->Abbreviations[AS_DOTTED_INITIAL_AND_SURNAME], .Type = PT_STRING }; PrintPair(&AbbrevDottedInitialAndSurname, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); config_pair AbbrevDottedInitialAndSurname = { .Key = IDENT_ABBREV_DOTTED_INITIAL_AND_SURNAME, .String = P->Abbreviations[AS_DOTTED_INITIAL_AND_SURNAME], .Type = PT_STRING }; PrintPair(&AbbrevDottedInitialAndSurname, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--RowsRequired; --RowsRequired;
} }
if(P->Homepage.Length > 0) if(P->Homepage.Length > 0)
{ {
fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); Print(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical);
config_pair Homepage = { .Key = IDENT_HOMEPAGE, .String = P->Homepage, .Type = PT_STRING }; PrintPair(&Homepage, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); config_pair Homepage = { .Key = IDENT_HOMEPAGE, .String = P->Homepage, .Type = PT_STRING }; PrintPair(&Homepage, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--RowsRequired; --RowsRequired;
} }
@ -4490,11 +4490,11 @@ void
PrintRole(role *R, typography *Typography) PrintRole(role *R, typography *Typography)
{ {
bool HaveInfo = R->Name.Length > 0 || R->Plural.Length > 0; bool HaveInfo = R->Name.Length > 0 || R->Plural.Length > 0;
fprintf(stderr, "\n" Print(stderr, "\n"
"%s%s%s%s%s ", HaveInfo ? Typography->UpperLeftCorner : Typography->UpperLeft, "%s%s%s%s%s ", HaveInfo ? Typography->UpperLeftCorner : Typography->UpperLeft,
Typography->Horizontal, Typography->Horizontal, Typography->Horizontal, Typography->UpperRight); Typography->Horizontal, Typography->Horizontal, Typography->Horizontal, Typography->UpperRight);
PrintStringC(CS_GREEN_BOLD, R->ID); PrintStringC(CS_GREEN_BOLD, R->ID);
fprintf(stderr, "\n"); Print(stderr, "\n");
uint8_t RowsRequired = GetRowsRequiredForRoleInfo(R); uint8_t RowsRequired = GetRowsRequiredForRoleInfo(R);
@ -4502,18 +4502,18 @@ PrintRole(role *R, typography *Typography)
bool ShouldFillSyntax = FALSE; bool ShouldFillSyntax = FALSE;
if(R->Name.Length > 0) if(R->Name.Length > 0)
{ {
fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); Print(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical);
config_pair Name = { .Key = IDENT_NAME, .String = R->Name, .Type = PT_STRING }; PrintPair(&Name, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); config_pair Name = { .Key = IDENT_NAME, .String = R->Name, .Type = PT_STRING }; PrintPair(&Name, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--RowsRequired; --RowsRequired;
} }
if(R->Plural.Length > 0) if(R->Plural.Length > 0)
{ {
fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); Print(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical);
config_pair Plural = { .Key = IDENT_PLURAL, .String = R->Plural, .Type = PT_STRING }; PrintPair(&Plural, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); config_pair Plural = { .Key = IDENT_PLURAL, .String = R->Plural, .Type = PT_STRING }; PrintPair(&Plural, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--RowsRequired; --RowsRequired;
} }
fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); Print(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical);
config_pair NonSpeaking = { .Key = IDENT_NON_SPEAKING, .bool = R->NonSpeaking, .Type = PT_BOOL }; PrintPair(&NonSpeaking, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); config_pair NonSpeaking = { .Key = IDENT_NON_SPEAKING, .bool = R->NonSpeaking, .Type = PT_BOOL }; PrintPair(&NonSpeaking, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
--RowsRequired; --RowsRequired;
} }
@ -4529,7 +4529,25 @@ PrintLineage(string Lineage, bool AppendNewline)
} }
string Us = GetFinalComponent(Lineage); string Us = GetFinalComponent(Lineage);
PrintStringC(CS_BLUE_BOLD, Us); PrintStringC(CS_BLUE_BOLD, Us);
if(AppendNewline) { fprintf(stderr, "\n"); } if(AppendNewline) { Print(stderr, "\n"); }
}
int
CopyLineageToBarePtr(char *Ptr, string Lineage, bool AppendNewline)
{
int Length = 0;
string Parent = StripComponentFromPath(Lineage);
Length += CopyStringCToBarePtr(CS_BLACK_BOLD, Ptr + Length, Parent);
if(Parent.Length > 0)
{
Length += CopyStringCToBarePtr(CS_BLACK_BOLD, Ptr + Length, Wrap0("/"));
}
string Us = GetFinalComponent(Lineage);
Length += CopyStringCToBarePtr(CS_BLUE_BOLD, Ptr + Length, Us);
if(AppendNewline) { Length += CopyStringToBarePtr(Ptr + Length, Wrap0("\n")); }
return Length;
} }
uint8_t uint8_t
@ -4554,20 +4572,20 @@ PrintTitle(char *Text, typography *T, uint8_t Generation, int AvailableColumns,
int InnerCharsRequired = AvailableColumns - LeftmostCharLength - StringLength(Text) - RightmostCharLength - SpacesRequired; int InnerCharsRequired = AvailableColumns - LeftmostCharLength - StringLength(Text) - RightmostCharLength - SpacesRequired;
int LeftCharsRequired = 4; int LeftCharsRequired = 4;
int RightCharsRequired = InnerCharsRequired - LeftCharsRequired; int RightCharsRequired = InnerCharsRequired - LeftCharsRequired;
fprintf(stderr, "%s", LeftmostChar); Print(stderr, "%s", LeftmostChar);
for(int i = 0; i < LeftCharsRequired; ++i) for(int i = 0; i < LeftCharsRequired; ++i)
{ {
fprintf(stderr, "%s", InnerChar); Print(stderr, "%s", InnerChar);
} }
fprintf(stderr, " %s ", Text); Print(stderr, " %s ", Text);
for(int i = 0; i < RightCharsRequired; ++i) for(int i = 0; i < RightCharsRequired; ++i)
{ {
fprintf(stderr, "%s", InnerChar); Print(stderr, "%s", InnerChar);
} }
fprintf(stderr, "%s", RightmostChar); Print(stderr, "%s", RightmostChar);
if(SectionItemCount == 0) if(SectionItemCount == 0)
{ {
//fprintf(stderr, "\n"); //Print(stderr, "\n");
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
} }
} }
@ -4577,10 +4595,10 @@ PrintMedia(project *P, typography *T, uint8_t Generation, int AvailableColumns)
{ {
int IndentationLevel = 0; int IndentationLevel = 0;
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
PrintTitle("Media", T, Generation, AvailableColumns, P->Medium.ItemCount); PrintTitle("Media", T, Generation, AvailableColumns, P->Medium.ItemCount);
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
//AvailableColumns -= Generation + 1; //AvailableColumns -= Generation + 1;
int RunningAvailableColumns = AvailableColumns; int RunningAvailableColumns = AvailableColumns;
medium *This = GetPlaceInBook(&P->Medium, 0); medium *This = GetPlaceInBook(&P->Medium, 0);
@ -4597,19 +4615,19 @@ PrintMedia(project *P, typography *T, uint8_t Generation, int AvailableColumns)
ColumnsRequired = GetColumnsRequiredForMedium(This, T); ColumnsRequired = GetColumnsRequiredForMedium(This, T);
if(RunningAvailableColumns >= StringLengthOfSpacePlusSeparator) if(RunningAvailableColumns >= StringLengthOfSpacePlusSeparator)
{ {
fprintf(stderr, " %s", T->Separator); Print(stderr, " %s", T->Separator);
RunningAvailableColumns -= StringLengthOfSpacePlusSeparator; RunningAvailableColumns -= StringLengthOfSpacePlusSeparator;
if(ColumnsRequired + 1 <= RunningAvailableColumns) if(ColumnsRequired + 1 <= RunningAvailableColumns)
{ {
fprintf(stderr, " "); Print(stderr, " ");
--RunningAvailableColumns; --RunningAvailableColumns;
PrintMedium(T, This, T->Delimiter, IndentationLevel, FALSE); PrintMedium(T, This, T->Delimiter, IndentationLevel, FALSE);
} }
else else
{ {
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
RunningAvailableColumns = AvailableColumns; RunningAvailableColumns = AvailableColumns;
PrintMedium(T, This, T->Delimiter, IndentationLevel, FALSE); PrintMedium(T, This, T->Delimiter, IndentationLevel, FALSE);
} }
@ -4617,9 +4635,9 @@ PrintMedia(project *P, typography *T, uint8_t Generation, int AvailableColumns)
else else
{ {
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
RunningAvailableColumns = AvailableColumns; RunningAvailableColumns = AvailableColumns;
fprintf(stderr, "%s ", T->Separator); Print(stderr, "%s ", T->Separator);
RunningAvailableColumns -= StringLengthOfSpacePlusSeparator; RunningAvailableColumns -= StringLengthOfSpacePlusSeparator;
PrintMedium(T, This, T->Delimiter, IndentationLevel, FALSE); PrintMedium(T, This, T->Delimiter, IndentationLevel, FALSE);
} }
@ -4647,7 +4665,7 @@ PrintCredits(config *C, project *P, typography *T, uint8_t Generation, int Inden
{ {
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
int Alignment = 0; int Alignment = 0;
Alignment += fprintf(stderr, "%s", T->Margin); Alignment += Print(stderr, "%s", T->Margin);
if(CreditCount == 1) if(CreditCount == 1)
{ {
Alignment += PrintStringC(CS_YELLOW_BOLD, Role->Name.Length ? Role->Name : Role->ID); Alignment += PrintStringC(CS_YELLOW_BOLD, Role->Name.Length ? Role->Name : Role->ID);
@ -4664,7 +4682,7 @@ PrintCredits(config *C, project *P, typography *T, uint8_t Generation, int Inden
Alignment += PrintStringC(CS_YELLOW_BOLD, Wrap0("s")); Alignment += PrintStringC(CS_YELLOW_BOLD, Wrap0("s"));
} }
} }
Alignment += fprintf(stderr, "%s", T->Delimiter); Alignment += Print(stderr, "%s", T->Delimiter);
bool Printed = FALSE; bool Printed = FALSE;
for(int j = 0; j < P->Credit.ItemCount; ++j) for(int j = 0; j < P->Credit.ItemCount; ++j)
{ {
@ -4688,13 +4706,13 @@ void
TypesetPair(typography *T, uint8_t Generation, config_identifier_id Key, string Value, int AvailableColumns) TypesetPair(typography *T, uint8_t Generation, config_identifier_id Key, string Value, int AvailableColumns)
{ {
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
int CharactersInKeyPlusDelimiter = StringLength(ConfigIdentifiers[Key].String) + StringLength(T->Delimiter); int CharactersInKeyPlusDelimiter = StringLength(ConfigIdentifiers[Key].String) + StringLength(T->Delimiter);
int AvailableColumnsForValue = AvailableColumns - CharactersInKeyPlusDelimiter; int AvailableColumnsForValue = AvailableColumns - CharactersInKeyPlusDelimiter;
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[Key].String); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[Key].String);
fprintf(stderr, "%s", T->Delimiter); Print(stderr, "%s", T->Delimiter);
int CharactersToWrite = Value.Length; int CharactersToWrite = Value.Length;
if(Value.Length > 0) if(Value.Length > 0)
@ -4706,10 +4724,10 @@ TypesetPair(typography *T, uint8_t Generation, config_identifier_id Key, string
while(CharactersToWrite > 0) while(CharactersToWrite > 0)
{ {
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
for(int i = 0; i < CharactersInKeyPlusDelimiter; ++i) for(int i = 0; i < CharactersInKeyPlusDelimiter; ++i)
{ {
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
} }
string Pen = { .Base = Value.Base + Value.Length - CharactersToWrite, string Pen = { .Base = Value.Base + Value.Length - CharactersToWrite,
@ -4728,7 +4746,7 @@ void
TypesetNumber(typography *T, uint8_t Generation, config_identifier_id Key, int64_t Value) TypesetNumber(typography *T, uint8_t Generation, config_identifier_id Key, int64_t Value)
{ {
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
config_pair Pair = { .Key = Key, .int64_t = Value, .Type = PT_INT64 }; config_pair Pair = { .Key = Key, .int64_t = Value, .Type = PT_INT64 };
bool ShouldFillSyntax = FALSE; bool ShouldFillSyntax = FALSE;
PrintPair(&Pair, T->Delimiter, ShouldFillSyntax, 0, FALSE, FALSE); PrintPair(&Pair, T->Delimiter, ShouldFillSyntax, 0, FALSE, FALSE);
@ -4738,7 +4756,7 @@ void
TypesetBool(typography *T, uint8_t Generation, config_identifier_id Key, bool Value) TypesetBool(typography *T, uint8_t Generation, config_identifier_id Key, bool Value)
{ {
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
config_pair Pair = { .Key = Key, .bool = Value, .Type = PT_BOOL }; config_pair Pair = { .Key = Key, .bool = Value, .Type = PT_BOOL };
bool ShouldFillSyntax = FALSE; bool ShouldFillSyntax = FALSE;
PrintPair(&Pair, T->Delimiter, ShouldFillSyntax, 0, FALSE, FALSE); PrintPair(&Pair, T->Delimiter, ShouldFillSyntax, 0, FALSE, FALSE);
@ -4748,9 +4766,9 @@ void
TypesetGenre(typography *T, uint8_t Generation, genre G) TypesetGenre(typography *T, uint8_t Generation, genre G)
{ {
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_GENRE].String); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_GENRE].String);
fprintf(stderr, "%s", T->Delimiter); Print(stderr, "%s", T->Delimiter);
PrintC(CS_GREEN_BOLD, GenreStrings[G]); PrintC(CS_GREEN_BOLD, GenreStrings[G]);
} }
@ -4758,9 +4776,9 @@ void
TypesetVODPlatform(typography *T, uint8_t Generation, vod_platform P) TypesetVODPlatform(typography *T, uint8_t Generation, vod_platform P)
{ {
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_VOD_PLATFORM].String); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_VOD_PLATFORM].String);
fprintf(stderr, "%s", T->Delimiter); Print(stderr, "%s", T->Delimiter);
if(IsValidVODPlatform(P)) if(IsValidVODPlatform(P))
{ {
PrintC(CS_GREEN_BOLD, VODPlatformStrings[P]); PrintC(CS_GREEN_BOLD, VODPlatformStrings[P]);
@ -4775,9 +4793,9 @@ void
TypesetNumberingMethod(typography *T, uint8_t Generation, numbering_method N) TypesetNumberingMethod(typography *T, uint8_t Generation, numbering_method N)
{ {
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_NUMBERING_METHOD].String); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_NUMBERING_METHOD].String);
fprintf(stderr, "%s", T-> Delimiter); Print(stderr, "%s", T-> Delimiter);
PrintC(CS_GREEN_BOLD, NumberingMethodStrings[N]); PrintC(CS_GREEN_BOLD, NumberingMethodStrings[N]);
} }
@ -4785,9 +4803,9 @@ void
TypesetNumberingScheme(typography *T, uint8_t Generation, numbering_scheme N) TypesetNumberingScheme(typography *T, uint8_t Generation, numbering_scheme N)
{ {
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_NUMBERING_SCHEME].String); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_NUMBERING_SCHEME].String);
fprintf(stderr, "%s", T-> Delimiter); Print(stderr, "%s", T-> Delimiter);
PrintC(CS_GREEN_BOLD, NumberingSchemeStrings[N]); PrintC(CS_GREEN_BOLD, NumberingSchemeStrings[N]);
} }
@ -4797,7 +4815,7 @@ PrintProject(config *C, project *P, typography *T, int Ancestors, int Indentatio
int Generation = Ancestors + 1; int Generation = Ancestors + 1;
CarriageReturn(T, Ancestors); CarriageReturn(T, Ancestors);
fprintf(stderr, "%s%s%s%s%s ", T->UpperLeftCorner, Print(stderr, "%s%s%s%s%s ", T->UpperLeftCorner,
T->Horizontal, T->Horizontal, T->Horizontal, T->UpperRight); T->Horizontal, T->Horizontal, T->Horizontal, T->UpperRight);
PrintLineage(P->Lineage, FALSE); PrintLineage(P->Lineage, FALSE);
@ -4810,7 +4828,7 @@ PrintProject(config *C, project *P, typography *T, int Ancestors, int Indentatio
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
PrintTitle("Settings", T, Generation, AvailableColumns, -1); PrintTitle("Settings", T, Generation, AvailableColumns, -1);
TypesetPair(T, Generation, IDENT_TITLE, P->Title, AvailableColumns); TypesetPair(T, Generation, IDENT_TITLE, P->Title, AvailableColumns);
@ -4858,7 +4876,7 @@ PrintProject(config *C, project *P, typography *T, int Ancestors, int Indentatio
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
PrintTitle("Credits", T, Generation, AvailableColumns, P->Credit.ItemCount); PrintTitle("Credits", T, Generation, AvailableColumns, P->Credit.ItemCount);
if(P->Credit.ItemCount > 0) if(P->Credit.ItemCount > 0)
{ {
@ -4866,7 +4884,7 @@ PrintProject(config *C, project *P, typography *T, int Ancestors, int Indentatio
} }
else else
{ {
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
PrintC(CS_YELLOW, "[none]"); PrintC(CS_YELLOW, "[none]");
} }
@ -4874,7 +4892,7 @@ PrintProject(config *C, project *P, typography *T, int Ancestors, int Indentatio
{ {
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
CarriageReturn(T, Generation); CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin); Print(stderr, "%s", T->Margin);
PrintTitle("Children", T, Generation, AvailableColumns, -1); PrintTitle("Children", T, Generation, AvailableColumns, -1);
++Ancestors; ++Ancestors;
for(int i = 0; i < P->Child.ItemCount; ++i) for(int i = 0; i < P->Child.ItemCount; ++i)
@ -4884,7 +4902,7 @@ PrintProject(config *C, project *P, typography *T, int Ancestors, int Indentatio
--Ancestors; --Ancestors;
} }
CarriageReturn(T, Ancestors); CarriageReturn(T, Ancestors);
fprintf(stderr, "%s%s%s%s%s ", T->LowerLeftCorner, Print(stderr, "%s%s%s%s%s ", T->LowerLeftCorner,
T->Horizontal, T->Horizontal, T->Horizontal, T->UpperRight); T->Horizontal, T->Horizontal, T->Horizontal, T->UpperRight);
PrintLineage(P->Lineage, FALSE); PrintLineage(P->Lineage, FALSE);
} }
@ -4911,7 +4929,7 @@ PrintConfig(config *C, bool ShouldClearTerminal)
}; };
// separate // separate
fprintf(stderr, "\n"); Print(stderr, "\n");
PrintTitle("Global Settings", &Typography, 0, TermCols, -1); PrintTitle("Global Settings", &Typography, 0, TermCols, -1);
int IndentationLevel = 0; int IndentationLevel = 0;
@ -4920,14 +4938,14 @@ PrintConfig(config *C, bool ShouldClearTerminal)
TypesetPair(&Typography, 0, IDENT_CACHE_DIR, C->CacheDir, AvailableColumns); TypesetPair(&Typography, 0, IDENT_CACHE_DIR, C->CacheDir, AvailableColumns);
TypesetPair(&Typography, 0, IDENT_INSTANCE_TITLE, C->InstanceTitle, AvailableColumns); TypesetPair(&Typography, 0, IDENT_INSTANCE_TITLE, C->InstanceTitle, AvailableColumns);
fprintf(stderr, "\n"); Print(stderr, "\n");
TypesetPair(&Typography, 0, IDENT_GLOBAL_TEMPLATES_DIR, C->GlobalTemplatesDir, AvailableColumns); TypesetPair(&Typography, 0, IDENT_GLOBAL_TEMPLATES_DIR, C->GlobalTemplatesDir, AvailableColumns);
TypesetPair(&Typography, 0, IDENT_GLOBAL_SEARCH_TEMPLATE, C->GlobalSearchTemplatePath, AvailableColumns); TypesetPair(&Typography, 0, IDENT_GLOBAL_SEARCH_TEMPLATE, C->GlobalSearchTemplatePath, AvailableColumns);
TypesetPair(&Typography, 0, IDENT_GLOBAL_SEARCH_DIR, C->GlobalSearchDir, AvailableColumns); TypesetPair(&Typography, 0, IDENT_GLOBAL_SEARCH_DIR, C->GlobalSearchDir, AvailableColumns);
TypesetPair(&Typography, 0, IDENT_GLOBAL_SEARCH_URL, C->GlobalSearchURL, AvailableColumns); TypesetPair(&Typography, 0, IDENT_GLOBAL_SEARCH_URL, C->GlobalSearchURL, AvailableColumns);
TypesetPair(&Typography, 0, IDENT_GLOBAL_THEME, C->GlobalTheme, AvailableColumns); TypesetPair(&Typography, 0, IDENT_GLOBAL_THEME, C->GlobalTheme, AvailableColumns);
fprintf(stderr, "\n"); Print(stderr, "\n");
TypesetPair(&Typography, 0, IDENT_ASSETS_ROOT_DIR, C->AssetsRootDir, AvailableColumns); TypesetPair(&Typography, 0, IDENT_ASSETS_ROOT_DIR, C->AssetsRootDir, AvailableColumns);
TypesetPair(&Typography, 0, IDENT_ASSETS_ROOT_URL, C->AssetsRootURL, AvailableColumns); TypesetPair(&Typography, 0, IDENT_ASSETS_ROOT_URL, C->AssetsRootURL, AvailableColumns);
TypesetPair(&Typography, 0, IDENT_CSS_PATH, C->CSSDir, AvailableColumns); TypesetPair(&Typography, 0, IDENT_CSS_PATH, C->CSSDir, AvailableColumns);
@ -4935,32 +4953,32 @@ PrintConfig(config *C, bool ShouldClearTerminal)
TypesetPair(&Typography, 0, IDENT_JS_PATH, C->JSDir, AvailableColumns); TypesetPair(&Typography, 0, IDENT_JS_PATH, C->JSDir, AvailableColumns);
TypesetPair(&Typography, 0, IDENT_QUERY_STRING, C->QueryString, AvailableColumns); TypesetPair(&Typography, 0, IDENT_QUERY_STRING, C->QueryString, AvailableColumns);
fprintf(stderr, "\n" Print(stderr, "\n"
"\n" "\n"
"%s", Typography.Margin); "%s", Typography.Margin);
bool ShouldFillSyntax = FALSE; bool ShouldFillSyntax = FALSE;
PrintBool("Respecting Privacy (derived from projects)", C->RespectingPrivacy, Typography.Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); PrintBool("Respecting Privacy (derived from projects)", C->RespectingPrivacy, Typography.Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
fprintf(stderr, "%s", Typography.Margin); Print(stderr, "%s", Typography.Margin);
int SecondsPerMinute = 60; int SecondsPerMinute = 60;
config_pair PrivacyCheckInterval = { .Key = IDENT_PRIVACY_CHECK_INTERVAL, .int64_t = C->PrivacyCheckInterval / SecondsPerMinute, .Type = PT_INT64 }; PrintPair(&PrivacyCheckInterval, Typography.Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); config_pair PrivacyCheckInterval = { .Key = IDENT_PRIVACY_CHECK_INTERVAL, .int64_t = C->PrivacyCheckInterval / SecondsPerMinute, .Type = PT_INT64 }; PrintPair(&PrivacyCheckInterval, Typography.Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE);
fprintf(stderr, "%s", Typography.Margin); Print(stderr, "%s", Typography.Margin);
PrintLogLevel(ConfigIdentifiers[IDENT_LOG_LEVEL].String, C->LogLevel, Typography.Delimiter, IndentationLevel, TRUE); PrintLogLevel(ConfigIdentifiers[IDENT_LOG_LEVEL].String, C->LogLevel, Typography.Delimiter, IndentationLevel, TRUE);
fprintf(stderr, "\n"); Print(stderr, "\n");
PrintTitle("People", &Typography, 0, TermCols, C->Person.ItemCount); PrintTitle("People", &Typography, 0, TermCols, C->Person.ItemCount);
for(int i = 0; i < C->Person.ItemCount; ++i) for(int i = 0; i < C->Person.ItemCount; ++i)
{ {
PrintPerson(GetPlaceInBook(&C->Person, i), &Typography); PrintPerson(GetPlaceInBook(&C->Person, i), &Typography);
} }
fprintf(stderr, "\n"); Print(stderr, "\n");
PrintTitle("Roles", &Typography, 0, TermCols, C->Role.ItemCount); PrintTitle("Roles", &Typography, 0, TermCols, C->Role.ItemCount);
for(int i = 0; i < C->Role.ItemCount; ++i) for(int i = 0; i < C->Role.ItemCount; ++i)
{ {
PrintRole(GetPlaceInBook(&C->Role, i), &Typography); PrintRole(GetPlaceInBook(&C->Role, i), &Typography);
} }
fprintf(stderr, "\n"); Print(stderr, "\n");
PrintTitle("Projects", &Typography, 0, TermCols, -1); PrintTitle("Projects", &Typography, 0, TermCols, -1);
for(int i = 0; i < C->Project.ItemCount; ++i) for(int i = 0; i < C->Project.ItemCount; ++i)
{ {
@ -5368,7 +5386,7 @@ ParseConfig(string Path, memory_book *TokensList)
int int
main(int ArgC, char **Args) main(int ArgC, char **Args)
{ {
//fprintf(stderr, "%s\n", ConfigFile.Buffer.Location); //Print(stderr, "%s\n", ConfigFile.Buffer.Location);
config_type_specs TypeSpecs = InitTypeSpecs(); config_type_specs TypeSpecs = InitTypeSpecs();
config *Config = ParseConfig(&TypeSpecs, Wrap0("cinera.conf")); config *Config = ParseConfig(&TypeSpecs, Wrap0("cinera.conf"));