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);
if(FormatLength != ArgCount)
{
Colourise(CS_FAILURE); fprintf(stderr, "%s:%d MakeString()", Filename, LineNumber); Colourise(CS_END);
fprintf(stderr,
Colourise(CS_FAILURE); Print(stderr, "%s:%d MakeString()", Filename, LineNumber); Colourise(CS_END);
Print(stderr,
"\n"
" 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"
" 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");
}
@ -161,8 +161,8 @@ MakeString_(char *Filename, int LineNumber, char *Format, int ArgCount, ...)
} break;
default:
{
Colourise(CS_FAILURE); fprintf(stderr, "%s:%d", Filename, LineNumber); Colourise(CS_END);
fprintf(stderr, "\n"
Colourise(CS_FAILURE); Print(stderr, "%s:%d", Filename, LineNumber); Colourise(CS_END);
Print(stderr, "\n"
" MakeString() has been passed an unsupported format specifier: %c\n", Format[i]);
__asm__("int3");
} break;
@ -197,20 +197,20 @@ MakeString0_(char *Filename, int LineNumber, char *Format, int ArgCount, ...)
int FormatLength = StringLength(Format);
if(FormatLength != ArgCount)
{
Colourise(CS_FAILURE); fprintf(stderr, "%s:%d MakeString0()", Filename, LineNumber); Colourise(CS_END);
fprintf(stderr,
Colourise(CS_FAILURE); Print(stderr, "%s:%d MakeString0()", Filename, LineNumber); Colourise(CS_END);
Print(stderr,
"\n"
" 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"
" 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");
}
@ -264,8 +264,8 @@ MakeString0_(char *Filename, int LineNumber, char *Format, int ArgCount, ...)
} break;
default:
{
Colourise(CS_FAILURE); fprintf(stderr, "%s:%d", Filename, LineNumber); Colourise(CS_END);
fprintf(stderr, "\n"
Colourise(CS_FAILURE); Print(stderr, "%s:%d", Filename, LineNumber); Colourise(CS_END);
Print(stderr, "\n"
" MakeString0() has been passed an unsupported format specifier: %c\n", Format[i]);
__asm__("int3");
} break;
@ -304,11 +304,11 @@ PushToken(tokens *Set, token *Token)
void
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)
{
Colourise(CS_BLUE_BOLD);
fprintf(stderr, "%li", T->int64_t);
Print(stderr, "%li", T->int64_t);
Colourise(CS_END);
}
@ -320,7 +320,7 @@ PrintToken(token *T, uint64_t Index)
{
PrintString(T->Content);
}
fprintf(stderr, "\n");
Print(stderr, "\n");
}
void
@ -1094,7 +1094,7 @@ PrintTypeField(config_type_field *F, config_identifier_id ParentScopeID, int Ind
}
else{
Colourise(CS_GREEN_BOLD);
fprintf(stderr, "\"%s\"", FieldTypeNames[F->Type]);
Print(stderr, "\"%s\"", FieldTypeNames[F->Type]);
Colourise(CS_END);
}
PrintC(CS_BLACK_BOLD, "");
@ -1190,7 +1190,7 @@ PrintTypeSpec(config_type_spec *S, int IndentationLevel)
void
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
// we only print out the "id" of scopes, omitting their containing fields
for(int i = 0; i < TypeSpecs->ItemCount; ++i)
@ -1453,28 +1453,28 @@ FreeScopeTree(scope_tree *T)
void
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);
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[P->Key].String);
fprintf(stderr, "%s", Delimiter);
Print(stderr, "%s", Delimiter);
if(P->Type == PT_BOOL)
{
if(P->bool == TRUE)
{
Colourise(CS_GREEN);
if(FillSyntax) { fprintf(stderr, "\""); }
fprintf(stderr, "true");
if(FillSyntax) { fprintf(stderr, "\""); }
if(FillSyntax) { Print(stderr, "\""); }
Print(stderr, "true");
if(FillSyntax) { Print(stderr, "\""); }
}
else
{
Colourise(CS_RED);
if(FillSyntax) { fprintf(stderr, "\""); }
fprintf(stderr, "false");
if(FillSyntax) { fprintf(stderr, "\""); }
if(FillSyntax) { Print(stderr, "\""); }
Print(stderr, "false");
if(FillSyntax) { Print(stderr, "\""); }
}
Colourise(CS_END);
if(FillSyntax) { fprintf(stderr, ";"); }
if(FillSyntax) { Print(stderr, ";"); }
}
else if(P->Type == PT_INT64)
{
@ -1483,68 +1483,68 @@ PrintPair(config_pair *P, char *Delimiter, bool FillSyntax, uint64_t Indentation
case IDENT_GENRE:
{
Colourise(CS_GREEN_BOLD);
if(FillSyntax) { fprintf(stderr, "\""); }
fprintf(stderr, "%s", GenreStrings[P->int64_t]);
if(FillSyntax) { fprintf(stderr, "\""); }
if(FillSyntax) { Print(stderr, "\""); }
Print(stderr, "%s", GenreStrings[P->int64_t]);
if(FillSyntax) { Print(stderr, "\""); }
} break;
case IDENT_LOG_LEVEL:
{
Colourise(CS_GREEN_BOLD);
if(FillSyntax) { fprintf(stderr, "\""); }
fprintf(stderr, "%s", LogLevelStrings[P->int64_t]);
if(FillSyntax) { fprintf(stderr, "\""); }
if(FillSyntax) { Print(stderr, "\""); }
Print(stderr, "%s", LogLevelStrings[P->int64_t]);
if(FillSyntax) { Print(stderr, "\""); }
} break;
case IDENT_NUMBERING_SCHEME:
{
Colourise(CS_GREEN_BOLD);
if(FillSyntax) { fprintf(stderr, "\""); }
fprintf(stderr, "%s", NumberingSchemeStrings[P->int64_t]);
if(FillSyntax) { fprintf(stderr, "\""); }
if(FillSyntax) { Print(stderr, "\""); }
Print(stderr, "%s", NumberingSchemeStrings[P->int64_t]);
if(FillSyntax) { Print(stderr, "\""); }
} break;
default:
{
Colourise(CS_BLUE_BOLD);
fprintf(stderr, "%li", P->int64_t);
Print(stderr, "%li", P->int64_t);
} break;
}
Colourise(CS_END);
if(FillSyntax) { fprintf(stderr, ";"); }
if(FillSyntax) { Print(stderr, ";"); }
}
else if(P->Type == PT_STRING)
{
if(P->String.Length)
{
Colourise(CS_GREEN_BOLD);
if(FillSyntax) { fprintf(stderr, "\""); }
if(FillSyntax) { Print(stderr, "\""); }
PrintString(P->String);
if(FillSyntax) { fprintf(stderr, "\""); }
if(FillSyntax) { Print(stderr, "\""); }
Colourise(CS_END);
if(FillSyntax) { fprintf(stderr, ";"); }
if(FillSyntax) { Print(stderr, ";"); }
}
else
{
PrintC(CS_YELLOW, "[unset]");
}
}
if(AppendNewline) { fprintf(stderr, "\n"); }
if(AppendNewline) { Print(stderr, "\n"); }
}
void
PrintScopeID(config_pair *P, char *Delimiter, uint64_t Indentation)
{
fprintf(stderr, "\n");
Print(stderr, "\n");
Indent(Indentation);
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[P->Key].String);
fprintf(stderr, "%s", Delimiter);
Print(stderr, "%s", Delimiter);
if(P->String.Length)
{
Colourise(CS_GREEN_BOLD);
fprintf(stderr, "\"");
Print(stderr, "\"");
PrintString(P->String);
fprintf(stderr, "\"");
Print(stderr, "\"");
Colourise(CS_END);
IndentedCarriageReturn(Indentation);
fprintf(stderr, "{");
Print(stderr, "{");
}
else
{
@ -1555,26 +1555,26 @@ PrintScopeID(config_pair *P, char *Delimiter, uint64_t Indentation)
void
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);
PrintC(CS_YELLOW_BOLD, Title);
fprintf(stderr, "%s", Delimiter);
Print(stderr, "%s", Delimiter);
if(Bool == TRUE)
{
Colourise(CS_GREEN);
if(FillSyntax) { fprintf(stderr, "\""); }
fprintf(stderr, "true");
if(FillSyntax) { fprintf(stderr, "\""); }
if(FillSyntax) { Print(stderr, "\""); }
Print(stderr, "true");
if(FillSyntax) { Print(stderr, "\""); }
}
else
{
Colourise(CS_RED);
if(FillSyntax) { fprintf(stderr, "\""); }
fprintf(stderr, "false");
if(FillSyntax) { fprintf(stderr, "\""); }
if(FillSyntax) { Print(stderr, "\""); }
Print(stderr, "false");
if(FillSyntax) { Print(stderr, "\""); }
}
Colourise(CS_END);
if(AppendNewline) { fprintf(stderr, "\n"); }
if(AppendNewline) { Print(stderr, "\n"); }
}
void PrintScopeTree(scope_tree *T, int IndentationLevel);
@ -1602,7 +1602,7 @@ PrintScopeTree(scope_tree *T, int IndentationLevel)
{
--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);
ConfigError(&Filepath, This->LineNumber, S_WARNING, "Invalid identifier in \"include\" scope: ", &This->Content);
fprintf(stderr,
Print(stderr,
" Valid identifiers:\n"
" allow\n"
" deny\n");
@ -4013,11 +4013,11 @@ PrintAssociationClashes(config_string_associations *A)
config_pair Assoc1 = { .Key = A->ID1, .String = Association->String1, .Type = PT_STRING };
PrintPair(&Assoc1, ": ", FALSE, IndentLevel, TRUE, FALSE);
}
fprintf(stderr, "\n");
Print(stderr, "\n");
for(int j = 0; j < Association->Projects.ItemCount; ++j)
{
project **P = GetPlaceInBook(&Association->Projects, j);
fprintf(stderr, " ");
Print(stderr, " ");
if(*P)
{
PrintStringC(CS_CYAN, (*P)->Lineage);
@ -4032,7 +4032,7 @@ PrintAssociationClashes(config_string_associations *A)
}
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);
if(RunningAvailableColumns - Length >= 0)
{
fprintf(stderr, "%s", NeedsSpacing ? " " : "");
Print(stderr, "%s", NeedsSpacing ? " " : "");
}
else
{
fprintf(stderr, "\n");
Print(stderr, "\n");
PrintString(Margin);
NeedsSpacing = FALSE;
RunningAvailableColumns = AvailableColumnsForValue;
@ -4091,7 +4091,7 @@ PrintVariantInconsistencies(memory_book *VariantStrings)
string Margin = Wrap0(" ");
variant V = *(variant *)GetPlaceInBook(&ThisVariantsString->Variants, j);
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);
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_LOG_LEVEL].String);
fprintf(stderr, "%s", Delimiter);
Print(stderr, "%s", Delimiter);
PrintC(CS_GREEN_BOLD, LogLevelStrings[Level]);
if(AppendNewline) { fprintf(stderr, "\n"); }
if(AppendNewline) { Print(stderr, "\n"); }
}
typedef struct
@ -4157,14 +4157,14 @@ PrintVerticals(typography *T, int Count)
{
for(int i = 0; i < Count; ++i)
{
fprintf(stderr, "%s", T->Vertical);
Print(stderr, "%s", T->Vertical);
}
}
void
CarriageReturn(typography *T, int VerticalsRequired)
{
fprintf(stderr, "\n");
Print(stderr, "\n");
PrintVerticals(T, VerticalsRequired);
}
@ -4176,12 +4176,12 @@ TypesetIconType(typography *T, uint8_t Generation, icon_type Type, bool PrependN
// TODO(matt): Implement me, please!
//CarriageReturn(T, Generation);
//fprintf(stderr, "%s", T.Margin);
//Print(stderr, "%s", T.Margin);
#if 0
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]);
fprintf(stderr, "\n");
Print(stderr, "\n");
#endif
@ -4195,10 +4195,10 @@ TypesetIconType(typography *T, uint8_t Generation, icon_type Type, bool PrependN
++Result;
}
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
config_identifier_id Key = IDENT_ICON_TYPE;
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[Key].String);
fprintf(stderr, "%s", T->Delimiter);
Print(stderr, "%s", T->Delimiter);
if(Type == IT_DEFAULT_UNSET)
{
PrintC(CS_YELLOW, "[unset]");
@ -4229,17 +4229,17 @@ TypesetVariants(typography *T, uint8_t Generation, config_identifier_id Key, uin
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 AvailableColumnsForValue = AvailableColumns - CharactersInKeyPlusDelimiter;
int RunningAvailableColumns = AvailableColumnsForValue;
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[Key].String);
fprintf(stderr, "%s", T->Delimiter);
Print(stderr, "%s", T->Delimiter);
bool NeedsSpacing = FALSE;
if(Value)
@ -4252,7 +4252,7 @@ TypesetVariants(typography *T, uint8_t Generation, config_identifier_id Key, uin
int Length = StringLength(String);
if(RunningAvailableColumns - Length >= 0)
{
fprintf(stderr, "%s", NeedsSpacing ? " " : "");
Print(stderr, "%s", NeedsSpacing ? " " : "");
}
else
{
@ -4260,12 +4260,12 @@ TypesetVariants(typography *T, uint8_t Generation, config_identifier_id Key, uin
if(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)
{
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
}
NeedsSpacing = FALSE;
RunningAvailableColumns = AvailableColumnsForValue;
@ -4295,9 +4295,9 @@ PrintMedium(typography *T, medium *M, char *Delimiter, uint64_t Indentation, boo
{
PrintC(CS_BLACK_BOLD, " [hidden]");
}
fprintf(stderr, "%s", Delimiter);
Print(stderr, "%s", Delimiter);
PrintStringC(CS_MAGENTA, M->Name);
fprintf(stderr, " (");
Print(stderr, " (");
if(M->Icon.Length > 0)
{
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);
TypesetVariants(T, Indentation, IDENT_ICON_VARIANTS, M->IconVariants, 0, 0, FALSE, AppendNewline);
fprintf(stderr, ")");
Print(stderr, ")");
if(AppendNewline)
{
fprintf(stderr, "\n");
Print(stderr, "\n");
}
}
@ -4324,13 +4324,13 @@ PrintSupport(support *S, typography *Typography, int IndentationLevel, uint8_t *
{
bool ShouldFillSyntax = FALSE;
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);
--*RowsRequired;
if(S->URL.Length > 0)
{
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);
--*RowsRequired;
}
@ -4338,28 +4338,28 @@ PrintSupport(support *S, typography *Typography, int IndentationLevel, uint8_t *
if(S->Icon.Length > 0)
{
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);
--*RowsRequired;
}
if(S->IconNormal.Length > 0)
{
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);
--*RowsRequired;
}
if(S->IconFocused.Length > 0)
{
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);
--*RowsRequired;
}
#if 1
// 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);
uint8_t StartingColumn = 4;
uint64_t AvailableColumns = GetTerminalColumns() - StartingColumn;
@ -4424,11 +4424,11 @@ void
PrintPerson(person *P, typography *Typography)
{
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,
Typography->Horizontal, Typography->Horizontal, Typography->Horizontal, Typography->UpperRight);
PrintStringC(CS_GREEN_BOLD, P->ID);
fprintf(stderr, "\n");
Print(stderr, "\n");
uint8_t RowsRequired = GetRowsRequiredForPersonInfo(Typography, P);
@ -4436,35 +4436,35 @@ PrintPerson(person *P, typography *Typography)
bool ShouldFillSyntax = FALSE;
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);
--RowsRequired;
}
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);
--RowsRequired;
}
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);
--RowsRequired;
}
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);
--RowsRequired;
}
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);
--RowsRequired;
}
@ -4490,11 +4490,11 @@ void
PrintRole(role *R, typography *Typography)
{
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,
Typography->Horizontal, Typography->Horizontal, Typography->Horizontal, Typography->UpperRight);
PrintStringC(CS_GREEN_BOLD, R->ID);
fprintf(stderr, "\n");
Print(stderr, "\n");
uint8_t RowsRequired = GetRowsRequiredForRoleInfo(R);
@ -4502,18 +4502,18 @@ PrintRole(role *R, typography *Typography)
bool ShouldFillSyntax = FALSE;
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);
--RowsRequired;
}
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);
--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);
--RowsRequired;
}
@ -4529,7 +4529,25 @@ PrintLineage(string Lineage, bool AppendNewline)
}
string Us = GetFinalComponent(Lineage);
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
@ -4554,20 +4572,20 @@ PrintTitle(char *Text, typography *T, uint8_t Generation, int AvailableColumns,
int InnerCharsRequired = AvailableColumns - LeftmostCharLength - StringLength(Text) - RightmostCharLength - SpacesRequired;
int LeftCharsRequired = 4;
int RightCharsRequired = InnerCharsRequired - LeftCharsRequired;
fprintf(stderr, "%s", LeftmostChar);
Print(stderr, "%s", LeftmostChar);
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)
{
fprintf(stderr, "%s", InnerChar);
Print(stderr, "%s", InnerChar);
}
fprintf(stderr, "%s", RightmostChar);
Print(stderr, "%s", RightmostChar);
if(SectionItemCount == 0)
{
//fprintf(stderr, "\n");
//Print(stderr, "\n");
CarriageReturn(T, Generation);
}
}
@ -4577,10 +4595,10 @@ PrintMedia(project *P, typography *T, uint8_t Generation, int AvailableColumns)
{
int IndentationLevel = 0;
CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
PrintTitle("Media", T, Generation, AvailableColumns, P->Medium.ItemCount);
CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
//AvailableColumns -= Generation + 1;
int RunningAvailableColumns = AvailableColumns;
medium *This = GetPlaceInBook(&P->Medium, 0);
@ -4597,19 +4615,19 @@ PrintMedia(project *P, typography *T, uint8_t Generation, int AvailableColumns)
ColumnsRequired = GetColumnsRequiredForMedium(This, T);
if(RunningAvailableColumns >= StringLengthOfSpacePlusSeparator)
{
fprintf(stderr, " %s", T->Separator);
Print(stderr, " %s", T->Separator);
RunningAvailableColumns -= StringLengthOfSpacePlusSeparator;
if(ColumnsRequired + 1 <= RunningAvailableColumns)
{
fprintf(stderr, " ");
Print(stderr, " ");
--RunningAvailableColumns;
PrintMedium(T, This, T->Delimiter, IndentationLevel, FALSE);
}
else
{
CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
RunningAvailableColumns = AvailableColumns;
PrintMedium(T, This, T->Delimiter, IndentationLevel, FALSE);
}
@ -4617,9 +4635,9 @@ PrintMedia(project *P, typography *T, uint8_t Generation, int AvailableColumns)
else
{
CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
RunningAvailableColumns = AvailableColumns;
fprintf(stderr, "%s ", T->Separator);
Print(stderr, "%s ", T->Separator);
RunningAvailableColumns -= StringLengthOfSpacePlusSeparator;
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);
int Alignment = 0;
Alignment += fprintf(stderr, "%s", T->Margin);
Alignment += Print(stderr, "%s", T->Margin);
if(CreditCount == 1)
{
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 += fprintf(stderr, "%s", T->Delimiter);
Alignment += Print(stderr, "%s", T->Delimiter);
bool Printed = FALSE;
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)
{
CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
int CharactersInKeyPlusDelimiter = StringLength(ConfigIdentifiers[Key].String) + StringLength(T->Delimiter);
int AvailableColumnsForValue = AvailableColumns - CharactersInKeyPlusDelimiter;
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[Key].String);
fprintf(stderr, "%s", T->Delimiter);
Print(stderr, "%s", T->Delimiter);
int CharactersToWrite = Value.Length;
if(Value.Length > 0)
@ -4706,10 +4724,10 @@ TypesetPair(typography *T, uint8_t Generation, config_identifier_id Key, string
while(CharactersToWrite > 0)
{
CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
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,
@ -4728,7 +4746,7 @@ void
TypesetNumber(typography *T, uint8_t Generation, config_identifier_id Key, int64_t Value)
{
CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
config_pair Pair = { .Key = Key, .int64_t = Value, .Type = PT_INT64 };
bool ShouldFillSyntax = 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)
{
CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
config_pair Pair = { .Key = Key, .bool = Value, .Type = PT_BOOL };
bool ShouldFillSyntax = FALSE;
PrintPair(&Pair, T->Delimiter, ShouldFillSyntax, 0, FALSE, FALSE);
@ -4748,9 +4766,9 @@ void
TypesetGenre(typography *T, uint8_t Generation, genre G)
{
CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_GENRE].String);
fprintf(stderr, "%s", T->Delimiter);
Print(stderr, "%s", T->Delimiter);
PrintC(CS_GREEN_BOLD, GenreStrings[G]);
}
@ -4758,9 +4776,9 @@ void
TypesetVODPlatform(typography *T, uint8_t Generation, vod_platform P)
{
CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_VOD_PLATFORM].String);
fprintf(stderr, "%s", T->Delimiter);
Print(stderr, "%s", T->Delimiter);
if(IsValidVODPlatform(P))
{
PrintC(CS_GREEN_BOLD, VODPlatformStrings[P]);
@ -4775,9 +4793,9 @@ void
TypesetNumberingMethod(typography *T, uint8_t Generation, numbering_method N)
{
CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
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]);
}
@ -4785,9 +4803,9 @@ void
TypesetNumberingScheme(typography *T, uint8_t Generation, numbering_scheme N)
{
CarriageReturn(T, Generation);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
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]);
}
@ -4797,7 +4815,7 @@ PrintProject(config *C, project *P, typography *T, int Ancestors, int Indentatio
int Generation = Ancestors + 1;
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);
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);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
PrintTitle("Settings", T, Generation, AvailableColumns, -1);
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);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
PrintTitle("Credits", T, Generation, AvailableColumns, P->Credit.ItemCount);
if(P->Credit.ItemCount > 0)
{
@ -4866,7 +4884,7 @@ PrintProject(config *C, project *P, typography *T, int Ancestors, int Indentatio
}
else
{
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
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);
fprintf(stderr, "%s", T->Margin);
Print(stderr, "%s", T->Margin);
PrintTitle("Children", T, Generation, AvailableColumns, -1);
++Ancestors;
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;
}
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);
PrintLineage(P->Lineage, FALSE);
}
@ -4911,7 +4929,7 @@ PrintConfig(config *C, bool ShouldClearTerminal)
};
// separate
fprintf(stderr, "\n");
Print(stderr, "\n");
PrintTitle("Global Settings", &Typography, 0, TermCols, -1);
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_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_SEARCH_TEMPLATE, C->GlobalSearchTemplatePath, 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_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_URL, C->AssetsRootURL, 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_QUERY_STRING, C->QueryString, AvailableColumns);
fprintf(stderr, "\n"
Print(stderr, "\n"
"\n"
"%s", Typography.Margin);
bool ShouldFillSyntax = FALSE;
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;
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);
fprintf(stderr, "\n");
Print(stderr, "\n");
PrintTitle("People", &Typography, 0, TermCols, C->Person.ItemCount);
for(int i = 0; i < C->Person.ItemCount; ++i)
{
PrintPerson(GetPlaceInBook(&C->Person, i), &Typography);
}
fprintf(stderr, "\n");
Print(stderr, "\n");
PrintTitle("Roles", &Typography, 0, TermCols, C->Role.ItemCount);
for(int i = 0; i < C->Role.ItemCount; ++i)
{
PrintRole(GetPlaceInBook(&C->Role, i), &Typography);
}
fprintf(stderr, "\n");
Print(stderr, "\n");
PrintTitle("Projects", &Typography, 0, TermCols, -1);
for(int i = 0; i < C->Project.ItemCount; ++i)
{
@ -5368,7 +5386,7 @@ ParseConfig(string Path, memory_book *TokensList)
int
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 *Config = ParseConfig(&TypeSpecs, Wrap0("cinera.conf"));