diff --git a/cinera/cinera.c b/cinera/cinera.c index b950825..4c1882f 100644 --- a/cinera/cinera.c +++ b/cinera/cinera.c @@ -23,7 +23,7 @@ typedef struct version CINERA_APP_VERSION = { .Major = 0, .Minor = 8, - .Patch = 22 + .Patch = 23 }; #include // NOTE(matt): varargs @@ -69,6 +69,9 @@ typedef uint64_t bool; #define TRUE 1 #define FALSE 0 +#define SECONDS_PER_HOUR 3600 +#define SECONDS_PER_MINUTE 60 + #define enum8(type) int8_t #define enum16(type) int16_t #define enum32(type) int32_t @@ -2407,6 +2410,54 @@ GetIconTypeFromString(string *Filename, token *T) return NS_COUNT; } +char *VODPlatformStrings[] = +{ + 0, + "youtube", +}; + +typedef enum +{ + VP_DEFAULT_UNSET, + VP_YOUTUBE, + VP_COUNT, +} vod_platform; + +vod_platform +GetVODPlatformFromString(string *Filename, token *T) +{ + for(int i = 0; i < VP_COUNT; ++i) + { + if(!StringsDifferLv0(T->Content, VODPlatformStrings[i])) { return i; } + } + + ConfigError(Filename, T->LineNumber, S_ERROR, "Unknown vod_platform: ", &T->Content); + fprintf(stderr, " Valid vod_platforms:\n"); + int FirstValidVODPlatform = 1; + for(int i = FirstValidVODPlatform; i < VP_COUNT; ++i) + { + fprintf(stderr, " %s\n", VODPlatformStrings[i]); + } + + return VP_COUNT; +} + +vod_platform +GetVODPlatform(string VODPlatform) +{ + for(int i = 0; i < VP_COUNT; ++i) + { + if(!StringsDifferLv0(VODPlatform, VODPlatformStrings[i])) { return i; } + } + return VP_COUNT; +} + +bool +IsValidVODPlatform(vod_platform V) +{ + return V > VP_DEFAULT_UNSET && V < VP_COUNT; +} + // DBVersion 1 typedef struct { unsigned int DBVersion; version AppVersion; version HMMLVersion; unsigned int EntryCount; } db_header1; typedef struct { int Size; char BaseFilename[32]; } db_entry1; @@ -3249,7 +3300,7 @@ typedef struct char URLSearch[MAX_BASE_URL_LENGTH + 1 + MAX_RELATIVE_PAGE_LOCATION_LENGTH]; char URLPlayer[MAX_BASE_URL_LENGTH + 1 + MAX_RELATIVE_PAGE_LOCATION_LENGTH + 1 + MAX_BASE_FILENAME_LENGTH]; char VideoID[MAX_VOD_ID_LENGTH]; - char VODPlatform[16]; + vod_platform VODPlatform; } buffers; rc @@ -4148,9 +4199,6 @@ InitTemplate(template *Template, string Location, template_type Type) Template->Metadata.NavBuffer = InitBook(sizeof(navigation_buffer), 4); } -#define SECONDS_PER_HOUR 3600 -#define SECONDS_PER_MINUTE 60 - v3 V3(int A, int B, int C) { @@ -9156,13 +9204,13 @@ ExamineDB(void) DeclaimMenuBuffers(&MenuBuffers) bool -VideoIsPrivate(string VODPlatform, char *VideoID) +VideoIsPrivate(vod_platform VODPlatform, char *VideoID) { // TODO(matt): Redo this to only return once, at the end // NOTE(matt): Currently only supports YouTube // NOTE(matt): Stack-string - if(StringsMatch(Wrap0("youtube"), VODPlatform)) + if(VODPlatform == VP_YOUTUBE) { char Message[128]; CopyString(Message, sizeof(Message), "%sChecking%s privacy status of: https://youtube.com/watch?v=%s", ColourStrings[CS_ONGOING], ColourStrings[CS_END], VideoID); @@ -10240,7 +10288,7 @@ HMMLToBuffers(buffers *CollationBuffers, template *BespokeTemplate, string BaseF Clear(CollationBuffers->Title, sizeof(CollationBuffers->Title)); Clear(CollationBuffers->URLPlayer, sizeof(CollationBuffers->URLPlayer)); Clear(CollationBuffers->URLSearch, sizeof(CollationBuffers->URLSearch)); - Clear(CollationBuffers->VODPlatform, sizeof(CollationBuffers->VODPlatform)); + CollationBuffers->VODPlatform = VP_DEFAULT_UNSET; // TODO(matt): A "MakeString0OnStack()" sort of function? // NOTE(matt): Stack-string @@ -10342,24 +10390,30 @@ HMMLToBuffers(buffers *CollationBuffers, template *BespokeTemplate, string BaseF CopyString(CollationBuffers->VideoID, sizeof(CollationBuffers->VideoID), "%s", HMML.metadata.id); } - string VODPlatform = {}; + vod_platform VODPlatform = VP_DEFAULT_UNSET; if(HMML.metadata.vod_platform) { - VODPlatform = Wrap0(HMML.metadata.vod_platform); + VODPlatform = GetVODPlatform(Wrap0(HMML.metadata.vod_platform)); } - else if(CurrentProject->VODPlatform.Length > 0) + if(!IsValidVODPlatform(VODPlatform) && IsValidVODPlatform(CurrentProject->VODPlatform)) { VODPlatform = CurrentProject->VODPlatform; } - if(VODPlatform.Length == 0) + if(!IsValidVODPlatform(VODPlatform)) { - IndexingError(FilepathL, 0, S_ERROR, "The [video] node lacks an \"vod_platform\"", 0); + IndexingError(FilepathL, 0, S_ERROR, "The [video] node lacks a valid \"vod_platform\"", 0); + fprintf(stderr, " Valid vod_platforms:\n"); + int FirstValidVODPlatform = 1; + for(int i = FirstValidVODPlatform; i < VP_COUNT; ++i) + { + fprintf(stderr, " %s\n", VODPlatformStrings[i]); + } Result = RC_ERROR_HMML; } else { - CopyString(CollationBuffers->VODPlatform, sizeof(CollationBuffers->VODPlatform), "%s", HMML.metadata.vod_platform); + CollationBuffers->VODPlatform = VODPlatform; } buffer URLPlayer = {}; @@ -11627,7 +11681,7 @@ BuffersToHTML(config *C, project *Project, buffers *CollationBuffers, template * } break; case TAG_VIDEO_ID: CopyStringToBufferNoFormat(&Master, Wrap0i(CollationBuffers->VideoID, sizeof(CollationBuffers->VideoID))); break; - case TAG_VOD_PLATFORM: CopyStringToBufferNoFormat(&Master, Wrap0i(CollationBuffers->VODPlatform, sizeof(CollationBuffers->VODPlatform))); break; + case TAG_VOD_PLATFORM: CopyStringToBufferNoFormat(&Master, Wrap0(VODPlatformStrings[CollationBuffers->VODPlatform])); break; case TAG_SEARCH: { /* */ MEM_TEST_MID("BuffersToHTML()"); diff --git a/cinera/cinera_config.c b/cinera/cinera_config.c index fed0923..70e2690 100644 --- a/cinera/cinera_config.c +++ b/cinera/cinera_config.c @@ -535,7 +535,7 @@ typedef struct project #else string StreamUsername; #endif - string VODPlatform; // TODO(matt): Make this an enum + vod_platform VODPlatform; bool DenyBespokeTemplates; bool SingleBrowserTab; @@ -1205,34 +1205,31 @@ typedef struct uint64_t LineNumber; } token_position; +typedef enum +{ + PT_BOOL, + PT_INT64, + PT_STRING, +} pair_type; + typedef struct { config_identifier_id Key; - string Value; + union + { + string String; + int64_t int64_t; + bool bool; + }; token_position Position; + pair_type Type; } config_pair; -typedef struct -{ - config_identifier_id Key; - int64_t Value; - token_position Position; -} config_int_pair; - -typedef struct -{ - config_identifier_id Key; - bool Value; - token_position Position; -} config_bool_pair; - typedef struct scope_tree { config_pair ID; _memory_book(scope_tree) Trees; _memory_book(config_pair) Pairs; - _memory_book(config_int_pair) IntPairs; - _memory_book(config_bool_pair) BoolPairs; struct scope_tree *Parent; config_type_spec TypeSpec; //token_position Position; // NOTE(matt): We chose not to make ScopeTokens() set this value @@ -1419,8 +1416,6 @@ void FreeScopeTreeRecursively(scope_tree *T) { FreeBook(&T->Pairs); - FreeBook(&T->IntPairs); - FreeBook(&T->BoolPairs); FreeBook(&T->TypeSpec.Field); //Free(T->Position.Filename); for(int i = 0; i < T->Trees.ItemCount; ++i) @@ -1434,8 +1429,6 @@ void FreeScopeTree(scope_tree *T) { FreeBook(&T->Pairs); - FreeBook(&T->IntPairs); - FreeBook(&T->BoolPairs); FreeBook(&T->TypeSpec.Field); //Free(T->Position.Filename); for(int i = 0; i < T->Trees.ItemCount; ++i) @@ -1453,18 +1446,74 @@ PrintPair(config_pair *P, char *Delimiter, bool FillSyntax, uint64_t Indentation Indent(Indentation); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[P->Key].String); fprintf(stderr, "%s", Delimiter); - if(P->Value.Length) + if(P->Type == PT_BOOL) { - Colourise(CS_GREEN_BOLD); - if(FillSyntax) { fprintf(stderr, "\""); } - PrintString(P->Value); - if(FillSyntax) { fprintf(stderr, "\""); } + if(P->bool == TRUE) + { + Colourise(CS_GREEN); + if(FillSyntax) { fprintf(stderr, "\""); } + fprintf(stderr, "true"); + if(FillSyntax) { fprintf(stderr, "\""); } + } + else + { + Colourise(CS_RED); + if(FillSyntax) { fprintf(stderr, "\""); } + fprintf(stderr, "false"); + if(FillSyntax) { fprintf(stderr, "\""); } + } Colourise(CS_END); if(FillSyntax) { fprintf(stderr, ";"); } } - else + else if(P->Type == PT_INT64) { - PrintC(CS_YELLOW, "[unset]"); + switch(P->Key) + { + case IDENT_GENRE: + { + Colourise(CS_GREEN_BOLD); + if(FillSyntax) { fprintf(stderr, "\""); } + fprintf(stderr, "%s", GenreStrings[P->int64_t]); + if(FillSyntax) { fprintf(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, "\""); } + } break; + case IDENT_NUMBERING_SCHEME: + { + Colourise(CS_GREEN_BOLD); + if(FillSyntax) { fprintf(stderr, "\""); } + fprintf(stderr, "%s", NumberingSchemeStrings[P->int64_t]); + if(FillSyntax) { fprintf(stderr, "\""); } + } break; + default: + { + Colourise(CS_BLUE_BOLD); + fprintf(stderr, "%li", P->int64_t); + } break; + } + Colourise(CS_END); + if(FillSyntax) { fprintf(stderr, ";"); } + } + else if(P->Type == PT_STRING) + { + if(P->String.Length) + { + Colourise(CS_GREEN_BOLD); + if(FillSyntax) { fprintf(stderr, "\""); } + PrintString(P->String); + if(FillSyntax) { fprintf(stderr, "\""); } + Colourise(CS_END); + if(FillSyntax) { fprintf(stderr, ";"); } + } + else + { + PrintC(CS_YELLOW, "[unset]"); + } } if(AppendNewline) { fprintf(stderr, "\n"); } } @@ -1476,11 +1525,11 @@ PrintScopeID(config_pair *P, char *Delimiter, uint64_t Indentation) Indent(Indentation); PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[P->Key].String); fprintf(stderr, "%s", Delimiter); - if(P->Value.Length) + if(P->String.Length) { Colourise(CS_GREEN_BOLD); fprintf(stderr, "\""); - PrintString(P->Value); + PrintString(P->String); fprintf(stderr, "\""); Colourise(CS_END); IndentedCarriageReturn(Indentation); @@ -1490,48 +1539,6 @@ PrintScopeID(config_pair *P, char *Delimiter, uint64_t Indentation) { PrintC(CS_YELLOW, "[unset]"); } - //fprintf(stderr, "\n"); -} - -void -PrintIntPair(config_int_pair *P, char *Delimiter, bool FillSyntax, uint64_t Indentation, bool PrependNewline, bool AppendNewline) -{ - if(PrependNewline) { fprintf(stderr, "\n"); } - Indent(Indentation); - PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[P->Key].String); - fprintf(stderr, "%s", Delimiter); - switch(P->Key) - { - case IDENT_GENRE: - { - Colourise(CS_GREEN_BOLD); - if(FillSyntax) { fprintf(stderr, "\""); } - fprintf(stderr, "%s", GenreStrings[P->Value]); - if(FillSyntax) { fprintf(stderr, "\""); } - } break; - case IDENT_LOG_LEVEL: - { - Colourise(CS_GREEN_BOLD); - if(FillSyntax) { fprintf(stderr, "\""); } - fprintf(stderr, "%s", LogLevelStrings[P->Value]); - if(FillSyntax) { fprintf(stderr, "\""); } - } break; - case IDENT_NUMBERING_SCHEME: - { - Colourise(CS_GREEN_BOLD); - if(FillSyntax) { fprintf(stderr, "\""); } - fprintf(stderr, "%s", NumberingSchemeStrings[P->Value]); - if(FillSyntax) { fprintf(stderr, "\""); } - } break; - default: - { - Colourise(CS_BLUE_BOLD); - fprintf(stderr, "%li", P->Value); - } break; - } - Colourise(CS_END); - if(FillSyntax) { fprintf(stderr, ";"); } - if(AppendNewline) { fprintf(stderr, "\n"); } } void @@ -1556,16 +1563,9 @@ PrintBool(char *Title, bool Bool, char *Delimiter, bool FillSyntax, uint64_t Ind if(FillSyntax) { fprintf(stderr, "\""); } } Colourise(CS_END); - if(FillSyntax) { fprintf(stderr, ";"); } if(AppendNewline) { fprintf(stderr, "\n"); } } -void -PrintBoolPair(config_bool_pair *P, char *Delimiter, bool FillSyntax, uint64_t Indentation, bool PrependNewline, bool AppendNewline) -{ - PrintBool(ConfigIdentifiers[P->Key].String, P->Value, Delimiter, FillSyntax, Indentation, PrependNewline, AppendNewline); -} - void PrintScopeTree(scope_tree *T, int IndentationLevel); void PrintScopeTree(scope_tree *T, int IndentationLevel) @@ -1583,14 +1583,6 @@ PrintScopeTree(scope_tree *T, int IndentationLevel) { PrintPair(GetPlaceInBook(&T->Pairs, i), " = ", ShouldFillSyntax, IndentationLevel, ShouldPrependNewline, FALSE); } - for(int i = 0; i < T->IntPairs.ItemCount; ++i) - { - PrintIntPair(GetPlaceInBook(&T->IntPairs, i), " = ", ShouldFillSyntax, IndentationLevel, ShouldPrependNewline, FALSE); - } - for(int i = 0; i < T->BoolPairs.ItemCount; ++i) - { - PrintBoolPair(GetPlaceInBook(&T->BoolPairs, i), " = ", ShouldFillSyntax, IndentationLevel, ShouldPrependNewline, FALSE); - } for(int i = 0; i < T->Trees.ItemCount; ++i) { PrintScopeTree(GetPlaceInBook(&T->Trees, i), IndentationLevel); @@ -1627,43 +1619,11 @@ GetPair(scope_tree *Parent, config_identifier_id FieldID) return Result; } -void -PushIntPair(scope_tree *Parent, config_int_pair *I) -{ - config_int_pair *New = MakeSpaceInBook(&Parent->IntPairs); - *New = *I; -} - -config_int_pair * -GetIntPair(scope_tree *Parent, config_identifier_id FieldID) -{ - config_int_pair *Result = 0; - for(int i = 0; i < Parent->IntPairs.ItemCount; ++i) - { - config_int_pair *This = GetPlaceInBook(&Parent->IntPairs, i); - if(This->Key == FieldID) - { - Result = This; - break; - } - } - return Result; -} - -void -PushBoolPair(scope_tree *Parent, config_bool_pair *B) -{ - config_bool_pair *New = MakeSpaceInBook(&Parent->BoolPairs); - *New = *B; -} - void InitScopeBooks(scope_tree *Scope) { Scope->Trees = InitBook(sizeof(scope_tree), 4); Scope->Pairs = InitBook(sizeof(config_pair), 4); - Scope->IntPairs = InitBook(sizeof(config_int_pair), 4); - Scope->BoolPairs = InitBook(sizeof(config_bool_pair), 4); } scope_tree * @@ -1732,17 +1692,36 @@ FieldIsInSpec(config_type_spec *Spec, config_identifier_id ID) bool PairsMatch(config_pair *A, config_pair *B) { - return A->Key == B->Key && StringsMatch(A->Value, B->Value); + bool Result = FALSE; + if(A->Type == B->Type && A->Key == B->Key) + { + switch(A->Type) + { + case PT_BOOL: + { + Result = A->bool == B->bool; + } break; + case PT_INT64: + { + Result = A->int64_t == B->int64_t; + } break; + case PT_STRING: + { + Result = StringsMatch(A->String, B->String); + } break; + } + } + return Result; } scope_tree * -GetScope(scope_tree *T, config_pair *ID, bool Singleton) +GetScope(scope_tree *T, config_pair *ID, bool IsSingleton) { scope_tree *Result = 0; for(int i = 0; i < T->Trees.ItemCount; ++i) { scope_tree *This = GetPlaceInBook(&T->Trees, i); - if(Singleton) + if(IsSingleton) { if(ID->Key == This->ID.Key) { @@ -1763,15 +1742,15 @@ GetScope(scope_tree *T, config_pair *ID, bool Singleton) } config_pair * -GetAssignment(scope_tree *T, config_pair *Assignment, bool Singleton) +GetAssignment(scope_tree *T, config_pair *Assignment, bool IsSingleton) { config_pair *Result = 0; for(int i = 0; i < T->Pairs.ItemCount; ++i) { config_pair *This = GetPlaceInBook(&T->Pairs, i); - if(Singleton) + if(IsSingleton) { - if(Assignment->Key == This->Key) + if(Assignment->Type == This->Type && Assignment->Key == This->Key) { Result = This; break; @@ -1789,44 +1768,6 @@ GetAssignment(scope_tree *T, config_pair *Assignment, bool Singleton) return Result; } -config_int_pair * -GetIntAssignment(scope_tree *T, config_int_pair *Assignment, bool Singleton) -{ - config_int_pair *Result = 0; - for(int i = 0; i < T->IntPairs.ItemCount; ++i) - { - config_int_pair *This = GetPlaceInBook(&T->IntPairs, i); - if(Assignment->Key == This->Key) - { - if(Singleton || Assignment->Value == This->Value) - { - Result = This; - break; - } - } - } - return Result; -} - -config_bool_pair * -GetBoolAssignment(scope_tree *T, config_bool_pair *Assignment, bool Singleton) -{ - config_bool_pair *Result = 0; - for(int i = 0; i < T->BoolPairs.ItemCount; ++i) - { - config_bool_pair *This = GetPlaceInBook(&T->BoolPairs, i); - if(Assignment->Key == This->Key) - { - if(Singleton || Assignment->Value == This->Value) - { - Result = This; - break; - } - } - } - return Result; -} - scope_tree *CopyScope(memory_book *TypeSpecs, scope_tree *Dest, scope_tree *Src); void CopyScopeContents(memory_book *TypeSpecs, scope_tree *Dest, scope_tree *Src) @@ -1836,16 +1777,6 @@ CopyScopeContents(memory_book *TypeSpecs, scope_tree *Dest, scope_tree *Src) config_pair *Pair = GetPlaceInBook(&Src->Pairs, i); PushPair(Dest, Pair); } - for(int i = 0; i < Src->IntPairs.ItemCount; ++i) - { - config_int_pair *IntPair = GetPlaceInBook(&Src->IntPairs, i); - PushIntPair(Dest, IntPair); - } - for(int i = 0; i < Src->BoolPairs.ItemCount; ++i) - { - config_bool_pair *BoolPair = GetPlaceInBook(&Src->BoolPairs, i); - PushBoolPair(Dest, BoolPair); - } for(int i = 0; i < Src->Trees.ItemCount; ++i) { scope_tree *Tree = GetPlaceInBook(&Src->Trees, i); @@ -1876,26 +1807,6 @@ MergeScopes(memory_book *TypeSpecs, scope_tree *Dest, scope_tree *Src, bool Inte if(!ThisAssignment) { PushPair(Dest, Pair); } } } - for(int i = 0; i < Src->IntPairs.ItemCount; ++i) - { - config_int_pair *IntPair = GetPlaceInBook(&Src->IntPairs, i); - config_type_field *Field = FieldIsInSpec(&Dest->TypeSpec, IntPair->Key); - if(Field) - { - config_int_pair *ThisAssignment = GetIntAssignment(Dest, IntPair, Field->Singleton); - if(!ThisAssignment) { PushIntPair(Dest, IntPair); } - } - } - for(int i = 0; i < Src->BoolPairs.ItemCount; ++i) - { - config_bool_pair *BoolPair = GetPlaceInBook(&Src->BoolPairs, i); - config_type_field *Field = FieldIsInSpec(&Dest->TypeSpec, BoolPair->Key); - if(Field) - { - config_bool_pair *ThisAssignment = GetBoolAssignment(Dest, BoolPair, Field->Singleton); - if(!ThisAssignment) { PushBoolPair(Dest, BoolPair); } - } - } for(int i = 0; i < Src->Trees.ItemCount; ++i) { scope_tree *Tree = GetPlaceInBook(&Src->Trees, i); @@ -2122,29 +2033,29 @@ ResetFields(config_type_spec *S) scope_tree * PushDefaultScope(memory_book *TypeSpecs, scope_tree *Parent, config_identifier_id Key, string Value) { - config_pair ID = { .Key = Key, .Value = Value }; + config_pair ID = { .Key = Key, .String = Value, .Type = PT_STRING }; return PushScope(TypeSpecs, Parent, &ID); } void PushDefaultPair(scope_tree *Parent, config_identifier_id Key, string Value) { - config_pair Pair = { .Key = Key, .Value = Value }; + config_pair Pair = { .Key = Key, .String = Value, .Type = PT_STRING }; return PushPair(Parent, &Pair); } void PushDefaultIntPair(scope_tree *Parent, config_identifier_id Key, uint64_t Value) { - config_int_pair IntPair = { .Key = Key, .Value = Value }; - return PushIntPair(Parent, &IntPair); + config_pair IntPair = { .Key = Key, .int64_t = Value, .Type = PT_INT64 }; + return PushPair(Parent, &IntPair); } void PushDefaultBoolPair(scope_tree *Parent, config_identifier_id Key, bool Value) { - config_bool_pair BoolPair = { .Key = Key, .Value = Value }; - return PushBoolPair(Parent, &BoolPair); + config_pair BoolPair = { .Key = Key, .bool = Value, .Type = PT_BOOL }; + return PushPair(Parent, &BoolPair); } #define DEFAULT_PRIVACY_CHECK_INTERVAL 60 * 4 @@ -2181,6 +2092,22 @@ SetDefaults(scope_tree *Root, memory_book *TypeSpecs) PushDefaultIntPair(Root, IDENT_LOG_LEVEL, LOG_ERROR); } +void +AssignOrPushEnumValue(scope_tree *Parent, config_pair *Pair, bool IsSingleton, int Value) +{ + Pair->int64_t = Value; + Pair->Type = PT_INT64; + config_pair *Assignment = 0; + if((Assignment = GetAssignment(Parent, Pair, IsSingleton))) + { + Assignment->int64_t = Pair->int64_t; + } + else + { + PushPair(Parent, Pair); + } +} + scope_tree * ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *TypeSpecs, config_include_rules *Rules) { @@ -2203,11 +2130,9 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T // NOTE(matt): If we get rid of FT_BARE, then the ++T->CurrentIndex that all cases perform could happen // right here config_pair Pair = {}; - config_int_pair IntPair = {}; - config_bool_pair BoolPair = {}; - Pair.Key = IntPair.Key = BoolPair.Key = Field->ID; - Pair.Position.Filename = IntPair.Position.Filename = BoolPair.Position.Filename = T->File.Path; + Pair.Key = Field->ID; + Pair.Position.Filename = T->File.Path; switch(Field->Type) { @@ -2216,6 +2141,7 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T token *This = GetPlaceInBook(&T->Token, T->CurrentIndex); token Value = *This; Pair.Position.LineNumber = Value.LineNumber; + Pair.Type = PT_STRING; ++T->CurrentIndex; if(!ExpectToken(T, TOKEN_SEMICOLON, 0)) { FreeScopeTree(Tree); return 0; } @@ -2232,21 +2158,22 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T token Value = {}; if(!ExpectToken(T, TOKEN_STRING, &Value)) { FreeScopeTree(Tree); return 0; } - BoolPair.Position.LineNumber = Value.LineNumber; + Pair.Position.LineNumber = Value.LineNumber; + Pair.Type = PT_BOOL; if(!ExpectToken(T, TOKEN_SEMICOLON, 0)) { FreeScopeTree(Tree); return 0; } bool Bool = GetBoolFromString(&Filepath, &Value); if(Bool != -1) { - BoolPair.Value = Bool; - config_bool_pair *Assignment = 0; - if((Assignment = GetBoolAssignment(Parent, &BoolPair, Field->Singleton))) + Pair.bool = Bool; + config_pair *Assignment = 0; + if((Assignment = GetAssignment(Parent, &Pair, Field->Singleton))) { - Assignment->Value = BoolPair.Value; + Assignment->bool = Pair.bool; } else { - PushBoolPair(Parent, &BoolPair); + PushPair(Parent, &Pair); } } else { FreeScopeTree(Tree); return 0; } @@ -2259,7 +2186,6 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T token Value = {}; if(!ExpectToken(T, TOKEN_STRING, &Value)) { FreeScopeTree(Tree); return 0; } Pair.Position.LineNumber = Value.LineNumber; - IntPair.Position.LineNumber = Value.LineNumber; if(!ExpectToken(T, TOKEN_SEMICOLON, 0)) { FreeScopeTree(Tree); return 0; } @@ -2268,16 +2194,7 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T numbering_scheme NumberingScheme = GetNumberingSchemeFromString(&Filepath, &Value); if(NumberingScheme != NS_COUNT) { - IntPair.Value = NumberingScheme; - config_int_pair *Assignment = 0; - if((Assignment = GetIntAssignment(Parent, &IntPair, Field->Singleton))) - { - Assignment->Value = IntPair.Value; - } - else - { - PushIntPair(Parent, &IntPair); - } + AssignOrPushEnumValue(Parent, &Pair, Field->Singleton, NumberingScheme); } else { FreeScopeTree(Tree); return 0; } } @@ -2286,16 +2203,7 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T log_level LogLevel = GetLogLevelFromString(&Filepath, &Value); if(LogLevel != LOG_COUNT) { - IntPair.Value = LogLevel; - config_int_pair *Assignment = 0; - if((Assignment = GetIntAssignment(Parent, &IntPair, Field->Singleton))) - { - Assignment->Value = IntPair.Value; - } - else - { - PushIntPair(Parent, &IntPair); - } + AssignOrPushEnumValue(Parent, &Pair, Field->Singleton, LogLevel); } else { FreeScopeTree(Tree); return 0; } } @@ -2304,16 +2212,7 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T genre Genre = GetGenreFromString(&Filepath, &Value); if(Genre != GENRE_COUNT) { - IntPair.Value = Genre; - config_int_pair *Assignment = 0; - if((Assignment = GetIntAssignment(Parent, &IntPair, Field->Singleton))) - { - Assignment->Value = IntPair.Value; - } - else - { - PushIntPair(Parent, &IntPair); - } + AssignOrPushEnumValue(Parent, &Pair, Field->Singleton, Genre); } else { FreeScopeTree(Tree); return 0; } } @@ -2322,16 +2221,16 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T icon_type IconType = GetIconTypeFromString(&Filepath, &Value); if(IconType != IT_COUNT) { - IntPair.Value = IconType; - config_int_pair *Assignment = 0; - if((Assignment = GetIntAssignment(Parent, &IntPair, Field->Singleton))) - { - Assignment->Value = IntPair.Value; - } - else - { - PushIntPair(Parent, &IntPair); - } + AssignOrPushEnumValue(Parent, &Pair, Field->Singleton, IconType); + } + else { FreeScopeTree(Tree); return 0; } + } + else if(Field->ID == IDENT_VOD_PLATFORM) + { + vod_platform VODPlatform = GetVODPlatformFromString(&Filepath, &Value); + if(VODPlatform != VP_COUNT) + { + AssignOrPushEnumValue(Parent, &Pair, Field->Singleton, VODPlatform); } else { FreeScopeTree(Tree); return 0; } } @@ -2340,27 +2239,29 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T int64_t ArtVariants = ParseArtVariantsString(&Filepath, &Value); if(ArtVariants != -1) { - IntPair.Value = ArtVariants; - config_int_pair *Assignment = 0; - if((Assignment = GetIntAssignment(Parent, &IntPair, Field->Singleton))) + Pair.int64_t = ArtVariants; + Pair.Type = PT_INT64; + config_pair *Assignment = 0; + if((Assignment = GetAssignment(Parent, &Pair, Field->Singleton))) { - Assignment->Value = IntPair.Value; + Assignment->int64_t = Pair.int64_t; } else { - PushIntPair(Parent, &IntPair); + PushPair(Parent, &Pair); } } else { FreeScopeTree(Tree); return 0; } } else { - Pair.Value = Value.Content; + Pair.String = Value.Content; + Pair.Type = PT_STRING; config_pair *Assignment = 0; if((Assignment = GetAssignment(Parent, &Pair, Field->Singleton))) { - Assignment->Value = Pair.Value; + Assignment->String = Pair.String; Assignment->Position.LineNumber = Pair.Position.LineNumber; Assignment->Position.Filename = Pair.Position.Filename; } @@ -2383,18 +2284,19 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T ++T->CurrentIndex; } if(!ExpectToken(T, TOKEN_NUMBER, &Value)) { FreeScopeTree(Tree); return 0; } - IntPair.Value = IsNegative ? 0 - Value.int64_t : Value.int64_t; + Pair.int64_t = IsNegative ? 0 - Value.int64_t : Value.int64_t; + Pair.Type = PT_INT64; if(!ExpectToken(T, TOKEN_SEMICOLON, 0)) { FreeScopeTree(Tree); return 0; } - config_int_pair *Assignment = 0; - if((Assignment = GetIntAssignment(Parent, &IntPair, Field->Singleton))) + config_pair *Assignment = 0; + if((Assignment = GetAssignment(Parent, &Pair, Field->Singleton))) { - Assignment->Value = IntPair.Value; + Assignment->int64_t = Pair.int64_t; } else { - PushIntPair(Parent, &IntPair); + PushPair(Parent, &Pair); } } break; case FT_SCOPE: @@ -2404,7 +2306,8 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T token Value = {}; if(!ExpectToken(T, TOKEN_STRING, &Value)) { FreeScopeTree(Tree); return 0; } - Pair.Value = Value.Content; + Pair.Type = PT_STRING; + Pair.String = Value.Content; Pair.Position.LineNumber = Value.LineNumber; if(Field->ID == IDENT_INCLUDE) @@ -2417,7 +2320,7 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T case RC_SUCCESS: { string IncluderFilePath = Wrap0(T->File.Path); - char *IncludePath = ExpandPath(Pair.Value, &IncluderFilePath); + char *IncludePath = ExpandPath(Pair.String, &IncluderFilePath); if(IncludePath) { string IncludePathL = Wrap0(IncludePath); @@ -2455,7 +2358,7 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T } else { - ConfigError(&IncluderFilePath, Pair.Position.LineNumber, S_WARNING, "Unable to include file: ", &Pair.Value); + ConfigError(&IncluderFilePath, Pair.Position.LineNumber, S_WARNING, "Unable to include file: ", &Pair.String); } } break; case RC_SYNTAX_ERROR: @@ -2506,10 +2409,11 @@ ScopeTokens(scope_tree *Tree, memory_book *TokensList, tokens *T, memory_book *T Parent = PushScope(TypeSpecs, Parent, &Pair); if(Parent->ID.Key == IDENT_MEDIUM) { - config_bool_pair Hidden = {}; + config_pair Hidden = {}; Hidden.Key = IDENT_HIDDEN; - Hidden.Value = FALSE; - PushBoolPair(Parent, &Hidden); + Hidden.bool = FALSE; + Hidden.Type = PT_BOOL; + PushPair(Parent, &Hidden); } MergeScopes(TypeSpecs, Parent, Parent->Parent, TRUE); } @@ -2691,7 +2595,7 @@ GetRole(config *C, resolution_errors *E, config_pair *RoleID) for(int i = 0; i < C->Role.ItemCount; ++i) { role *Role = GetPlaceInBook(&C->Role, i); - if(!StringsDifferCaseInsensitive(Role->ID, RoleID->Value)) + if(!StringsDifferCaseInsensitive(Role->ID, RoleID->String)) { Result = Role; break; @@ -2701,7 +2605,7 @@ GetRole(config *C, resolution_errors *E, config_pair *RoleID) if(!Result && !GetError(E, S_WARNING, &RoleID->Position, IDENT_ROLE)) { string Filepath = Wrap0(RoleID->Position.Filename); - ConfigError(&Filepath, RoleID->Position.LineNumber, S_WARNING, "Could not find role: ", &RoleID->Value); + ConfigError(&Filepath, RoleID->Position.LineNumber, S_WARNING, "Could not find role: ", &RoleID->String); PushError(E, S_WARNING, &RoleID->Position, IDENT_ROLE); WaitForInput(); } @@ -2737,7 +2641,7 @@ GetPerson(config *C, resolution_errors *E, config_pair *PersonID) for(int i = 0; i < C->Person.ItemCount; ++i) { person *Person = GetPlaceInBook(&C->Person, i); - if(!StringsDifferCaseInsensitive(Person->ID, PersonID->Value)) + if(!StringsDifferCaseInsensitive(Person->ID, PersonID->String)) { Result = Person; break; @@ -2747,7 +2651,7 @@ GetPerson(config *C, resolution_errors *E, config_pair *PersonID) if(!Result && !GetError(E, S_WARNING, &PersonID->Position, IDENT_PERSON)) { string Filepath = Wrap0(PersonID->Position.Filename); - ConfigError(&Filepath, PersonID->Position.LineNumber, S_WARNING, "Could not find person: ", &PersonID->Value); + ConfigError(&Filepath, PersonID->Position.LineNumber, S_WARNING, "Could not find person: ", &PersonID->String); PushError(E, S_WARNING, &PersonID->Position, IDENT_PERSON); } return Result; @@ -2761,7 +2665,7 @@ DeriveLineageOfProject(config *C, scope_tree *Project) if(Project) { string **Writer = MakeSpaceInBook(&StringList); - *Writer = &Project->ID.Value; + *Writer = &Project->ID.String; Project = Project->Parent; } @@ -2772,7 +2676,7 @@ DeriveLineageOfProject(config *C, scope_tree *Project) *Writer = &Slash; Writer = MakeSpaceInBook(&StringList); - *Writer = &Project->ID.Value; + *Writer = &Project->ID.String; Project = Project->Parent; } @@ -2801,7 +2705,7 @@ DeriveLineageWithoutOriginOfProject(config *C, scope_tree *Project) if(Project->Parent && Project->Parent->ID.Key == IDENT_PROJECT) { string **Writer = MakeSpaceInBook(&StringList); - *Writer = &Project->ID.Value; + *Writer = &Project->ID.String; Project = Project->Parent; } @@ -2812,7 +2716,7 @@ DeriveLineageWithoutOriginOfProject(config *C, scope_tree *Project) *Writer = &Slash; Writer = MakeSpaceInBook(&StringList); - *Writer = &Project->ID.Value; + *Writer = &Project->ID.String; Project = Project->Parent; } @@ -2879,7 +2783,7 @@ ResolveLocalVariable(config *C, resolution_errors *E, scope_tree *Scope, config_ { Scope = Scope->Parent; } - Result = ExtendStringInBook(&C->ResolvedVariables, Scope->ID.Value); + Result = ExtendStringInBook(&C->ResolvedVariables, Scope->ID.String); } else { @@ -2903,7 +2807,7 @@ ResolveLocalVariable(config *C, resolution_errors *E, scope_tree *Scope, config_ { if(GetPerson(C, E, Pair)) { - Result = ExtendStringInBook(&C->ResolvedVariables, Pair->Value); + Result = ExtendStringInBook(&C->ResolvedVariables, Pair->String); Processed = TRUE; break; } @@ -2911,7 +2815,7 @@ ResolveLocalVariable(config *C, resolution_errors *E, scope_tree *Scope, config_ { if(!GetError(E, S_WARNING, Position, Variable)) { - ConfigError(&Filepath, Position->LineNumber, S_WARNING, "Owner set, but the person does not exist: ", &Pair->Value); + ConfigError(&Filepath, Position->LineNumber, S_WARNING, "Owner set, but the person does not exist: ", &Pair->String); PushError(E, S_WARNING, Position, Variable); } Processed = TRUE; @@ -2942,7 +2846,7 @@ ResolveLocalVariable(config *C, resolution_errors *E, scope_tree *Scope, config_ { if(Scope && Scope->ID.Key == Variable) { - Result = ExtendStringInBook(&C->ResolvedVariables, Scope->ID.Value); + Result = ExtendStringInBook(&C->ResolvedVariables, Scope->ID.String); } else { @@ -2974,19 +2878,19 @@ ResolveString(config *C, resolution_errors *E, scope_tree *Parent, config_pair * //PrintFunctionName("ResolveString()"); string Result = {}; ResetPen(&C->ResolvedVariables); - for(int i = 0; i < S->Value.Length;) + for(int i = 0; i < S->String.Length;) { - switch(S->Value.Base[i]) + switch(S->String.Base[i]) { case '$': { string Test = {}; ++i; - if(i < S->Value.Length && S->Value.Base[i] == '{') + if(i < S->String.Length && S->String.Base[i] == '{') { ++i; - Test.Base = S->Value.Base + i; - while(i < S->Value.Length && S->Value.Base[i] != '}') + Test.Base = S->String.Base + i; + while(i < S->String.Length && S->String.Base[i] != '}') { ++Test.Length; ++i; @@ -2994,8 +2898,8 @@ ResolveString(config *C, resolution_errors *E, scope_tree *Parent, config_pair * } else { - Test.Base = S->Value.Base + i; - while(i < S->Value.Length && IsValidIdentifierCharacter(S->Value.Base[i])) + Test.Base = S->String.Base + i; + while(i < S->String.Length && IsValidIdentifierCharacter(S->String.Base[i])) { ++Test.Length; ++i; @@ -3015,7 +2919,7 @@ ResolveString(config *C, resolution_errors *E, scope_tree *Parent, config_pair * } break; case '~': { - string Char = { .Base = S->Value.Base + i, .Length = 1 }; + string Char = { .Base = S->String.Base + i, .Length = 1 }; if(AbsoluteFilePath && i == 0) { Result = ResolveEnvironmentVariable(&C->ResolvedVariables, Char); @@ -3028,7 +2932,7 @@ ResolveString(config *C, resolution_errors *E, scope_tree *Parent, config_pair * case '\\': { ++i; }; // NOTE(matt): Intentional fall-through default: { - string Char = { .Base = S->Value.Base + i, .Length = 1 }; + string Char = { .Base = S->String.Base + i, .Length = 1 }; Result = ExtendStringInBook(&C->ResolvedVariables, Char); } break; @@ -3165,23 +3069,17 @@ PushMedium(config *C, resolution_errors *E, config_verifiers *V, project *P, sco } } - for(int i = 0; i < MediumTree->IntPairs.ItemCount; ++i) + for(int i = 0; i < MediumTree->Pairs.ItemCount; ++i) { - config_int_pair *This = GetPlaceInBook(&MediumTree->IntPairs, i); + config_pair *This = GetPlaceInBook(&MediumTree->Pairs, i); switch(This->Key) { - case IDENT_ICON_TYPE: { Medium->IconType = This->Value; } break; - case IDENT_ICON_VARIANTS: { Medium->IconVariants = This->Value; } break; - default: break; - } - } + // int64_t + case IDENT_ICON_TYPE: { Medium->IconType = This->int64_t; } break; + case IDENT_ICON_VARIANTS: { Medium->IconVariants = This->int64_t; } break; - for(int i = 0; i < MediumTree->BoolPairs.ItemCount; ++i) - { - config_bool_pair *This = GetPlaceInBook(&MediumTree->BoolPairs, i); - switch(This->Key) - { - case IDENT_HIDDEN: { Medium->Hidden = This->Value; } break; + // bool + case IDENT_HIDDEN: { Medium->Hidden = This->bool; } break; default: break; } } @@ -3251,13 +3149,13 @@ PushSupport(config *C, resolution_errors *E, config_verifiers *V, person *P, sco } } - for(int i = 0; i < SupportTree->IntPairs.ItemCount; ++i) + for(int i = 0; i < SupportTree->Pairs.ItemCount; ++i) { - config_int_pair *This = GetPlaceInBook(&SupportTree->IntPairs, i); + config_pair *This = GetPlaceInBook(&SupportTree->Pairs, i); switch(This->Key) { - case IDENT_ICON_TYPE: { Support->IconType = This->Value; } break; - case IDENT_ICON_VARIANTS: { Support->IconVariants = This->Value; } break; + case IDENT_ICON_TYPE: { Support->IconType = This->int64_t; } break; + case IDENT_ICON_VARIANTS: { Support->IconVariants = This->int64_t; } break; default: break; } } @@ -3341,21 +3239,21 @@ PushRoleOntoConfig(config *C, resolution_errors *E, config_verifiers *V, scope_t for(int i = 0; i < RoleTree->Pairs.ItemCount; ++i) { config_pair *Pair = GetPlaceInBook(&RoleTree->Pairs, i); - if(IDENT_NAME == Pair->Key) + switch(Pair->Key) { - This->Name = ResolveString(C, E, RoleTree, Pair, FALSE); - } - else if(IDENT_PLURAL == Pair->Key) - { - This->Plural = ResolveString(C, E, RoleTree, Pair, FALSE); - } - } - for(int i = 0; i < RoleTree->BoolPairs.ItemCount; ++i) - { - config_bool_pair *BoolPair = GetPlaceInBook(&RoleTree->BoolPairs, i); - if(IDENT_NON_SPEAKING == BoolPair->Key) - { - This->NonSpeaking = BoolPair->Value; + case IDENT_NAME: + { + This->Name = ResolveString(C, E, RoleTree, Pair, FALSE); + } break; + case IDENT_PLURAL: + { + This->Plural = ResolveString(C, E, RoleTree, Pair, FALSE); + } break; + case IDENT_NON_SPEAKING: + { + This->NonSpeaking = Pair->bool; + } break; + default: break; } } } @@ -3394,8 +3292,8 @@ PushPersonOntoProject(config *C, resolution_errors *E, project *P, config_pair * void PushCredit(config *C, resolution_errors *E, project *P, scope_tree *CreditTree) { - CreditTree->ID.Value = ResolveString(C, E, CreditTree, &CreditTree->ID, FALSE); - if(CreditTree->ID.Value.Base) + CreditTree->ID.String = ResolveString(C, E, CreditTree, &CreditTree->ID, FALSE); + if(CreditTree->ID.String.Base) { person *Person = GetPerson(C, E, &CreditTree->ID); if(Person) @@ -3573,8 +3471,9 @@ PushProject(config *C, resolution_errors *E, config_verifiers *V, project *P, sc string Filepath = Wrap0(This->Position.Filename); switch(This->Key) { + // NOTE(matt): String case IDENT_DEFAULT_MEDIUM: - { P->DefaultMedium = GetMediumFromProject(P, This->Value); } break; + { P->DefaultMedium = GetMediumFromProject(P, This->String); } break; case IDENT_HMML_DIR: { SetUniqueHMMLDir(C, E, HMMLDirs, P, ProjectTree, This); } break; #if(HMMLIB_MAJOR_VERSION == 2) @@ -3661,8 +3560,6 @@ PushProject(config *C, resolution_errors *E, config_verifiers *V, project *P, sc case IDENT_STREAM_USERNAME: { P->StreamUsername = ResolveString(C, E, ProjectTree, This, FALSE); } break; #endif - case IDENT_VOD_PLATFORM: - { P->VODPlatform = ResolveString(C, E, ProjectTree, This, FALSE); } break; case IDENT_ART: { P->Art = StripSlashes(ResolveString(C, E, ProjectTree, This, FALSE), P_REL); } break; case IDENT_ICON: { P->Icon = StripSlashes(ResolveString(C, E, ProjectTree, This, FALSE), P_REL); } break; @@ -3670,35 +3567,22 @@ PushProject(config *C, resolution_errors *E, config_verifiers *V, project *P, sc case IDENT_ICON_FOCUSED: { P->IconFocused = ResolveString(C, E, ProjectTree, This, FALSE); } break; case IDENT_ICON_DISABLED: { P->IconDisabled = ResolveString(C, E, ProjectTree, This, FALSE); } break; - default: break; - } - } + // NOTE(matt): int64_t + case IDENT_GENRE: { P->Genre = This->int64_t; } break; + case IDENT_ART_VARIANTS: { P->ArtVariants = This->int64_t; } break; + case IDENT_ICON_TYPE: { P->IconType = This->int64_t; } break; + case IDENT_ICON_VARIANTS: { P->IconVariants = This->int64_t; } break; + case IDENT_NUMBERING_SCHEME: { P->NumberingScheme = This->int64_t; } break; + case IDENT_VOD_PLATFORM: { P->VODPlatform = This->int64_t; } break; - for(int i = 0; i < ProjectTree->IntPairs.ItemCount; ++i) - { - config_int_pair *This = GetPlaceInBook(&ProjectTree->IntPairs, i); - switch(This->Key) - { - case IDENT_GENRE: { P->Genre = This->Value; } break; - case IDENT_ART_VARIANTS: { P->ArtVariants = This->Value; } break; - case IDENT_ICON_TYPE: { P->IconType = This->Value; } break; - case IDENT_ICON_VARIANTS: { P->IconVariants = This->Value; } break; - case IDENT_NUMBERING_SCHEME: { P->NumberingScheme = This->Value; } break; - default: break; - } - } - - for(int i = 0; i < ProjectTree->BoolPairs.ItemCount; ++i) - { - config_bool_pair *This = GetPlaceInBook(&ProjectTree->BoolPairs, i); - switch(This->Key) - { + // NOTE(matt): bool case IDENT_DENY_BESPOKE_TEMPLATES: - { P->DenyBespokeTemplates = This->Value; } break; + { P->DenyBespokeTemplates = This->bool; } break; case IDENT_IGNORE_PRIVACY: - { P->IgnorePrivacy = This->Value; } break; + { P->IgnorePrivacy = This->bool; } break; case IDENT_SINGLE_BROWSER_TAB: - { P->SingleBrowserTab = This->Value; } break; + { P->SingleBrowserTab = This->bool; } break; + default: break; } } @@ -3844,12 +3728,12 @@ PrintAssociationClashes(config_string_associations *A) { ConfigError(0, 0, S_ERROR, "Multiple projects share the same:", 0); - config_pair Assoc0 = { .Key = A->ID0, .Value = Association->String0 }; + config_pair Assoc0 = { .Key = A->ID0, .String = Association->String0, .Type = PT_STRING }; int IndentLevel = 2; PrintPair(&Assoc0, ": ", FALSE, IndentLevel, FALSE, FALSE); if(A->ID1 != IDENT_NULL) { - config_pair Assoc1 = { .Key = A->ID1, .Value = Association->String1 }; + config_pair Assoc1 = { .Key = A->ID1, .String = Association->String1, .Type = PT_STRING }; PrintPair(&Assoc1, ": ", FALSE, IndentLevel, TRUE, FALSE); } fprintf(stderr, "\n"); @@ -4162,13 +4046,13 @@ void PrintSupport(support *S, typography *Typography, int IndentationLevel, uint8_t *RowsRequired) { bool ShouldFillSyntax = FALSE; - config_pair ID = { .Key = IDENT_SUPPORT, .Value = S->ID }; + config_pair ID = { .Key = IDENT_SUPPORT, .String = S->ID, .Type = PT_STRING }; fprintf(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, .Value = S->URL }; + config_pair URL = { .Key = IDENT_URL, .String = S->URL, .Type = PT_STRING }; fprintf(stderr, "%s%s ", *RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical, Typography->Margin); PrintPair(&URL, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); --*RowsRequired; @@ -4176,21 +4060,21 @@ PrintSupport(support *S, typography *Typography, int IndentationLevel, uint8_t * if(S->Icon.Length > 0) { - config_pair Icon = { .Key = IDENT_ICON, .Value = S->Icon }; + config_pair Icon = { .Key = IDENT_ICON, .String = S->Icon, .Type = PT_STRING }; fprintf(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, .Value = S->IconNormal }; + 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); PrintPair(&IconNormal, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); --*RowsRequired; } if(S->IconFocused.Length > 0) { - config_pair IconFocused = { .Key = IDENT_ICON_FOCUSED, .Value = S->IconFocused }; + 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); PrintPair(&IconFocused, Typography->Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); --*RowsRequired; @@ -4273,14 +4157,14 @@ PrintPerson(person *P, typography *Typography) if(P->Name.Length > 0) { fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); - config_pair Name = { .Key = IDENT_NAME, .Value = P->Name }; 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; } if(P->Homepage.Length > 0) { fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); - config_pair Homepage = { .Key = IDENT_HOMEPAGE, .Value = P->Homepage }; 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; } @@ -4318,18 +4202,18 @@ PrintRole(role *R, typography *Typography) if(R->Name.Length > 0) { fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); - config_pair Name = { .Key = IDENT_NAME, .Value = R->Name }; 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; } if(R->Plural.Length > 0) { fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); - config_pair Plural = { .Key = IDENT_PLURAL, .Value = R->Plural }; 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; } fprintf(stderr, "%s ", RowsRequired == 1 ? Typography->LowerLeft : Typography->Vertical); - config_bool_pair NonSpeaking = { .Key = IDENT_NON_SPEAKING, .Value = R->NonSpeaking }; PrintBoolPair(&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; } @@ -4544,9 +4428,9 @@ TypesetBool(typography *T, uint8_t Generation, config_identifier_id Key, bool Va { CarriageReturn(T, Generation); fprintf(stderr, "%s", T->Margin); - config_bool_pair Pair = { .Key = Key, .Value = Value }; + config_pair Pair = { .Key = Key, .bool = Value, .Type = PT_BOOL }; bool ShouldFillSyntax = FALSE; - PrintBoolPair(&Pair, T->Delimiter, ShouldFillSyntax, 0, FALSE, FALSE); + PrintPair(&Pair, T->Delimiter, ShouldFillSyntax, 0, FALSE, FALSE); } void @@ -4559,6 +4443,23 @@ TypesetGenre(typography *T, uint8_t Generation, genre G) PrintC(CS_GREEN_BOLD, GenreStrings[G]); } +void +TypesetVODPlatform(typography *T, uint8_t Generation, vod_platform P) +{ + CarriageReturn(T, Generation); + fprintf(stderr, "%s", T->Margin); + PrintC(CS_YELLOW_BOLD, ConfigIdentifiers[IDENT_VOD_PLATFORM].String); + fprintf(stderr, "%s", T->Delimiter); + if(IsValidVODPlatform(P)) + { + PrintC(CS_GREEN_BOLD, VODPlatformStrings[P]); + } + else + { + PrintC(CS_YELLOW, "[unset]"); + } +} + void TypesetNumberingScheme(typography *T, uint8_t Generation, numbering_scheme N) { @@ -4610,7 +4511,6 @@ PrintProject(config *C, project *P, typography *T, int Ancestors, int Indentatio #else TypesetPair(T, Generation, IDENT_STREAM_USERNAME, P->StreamUsername, AvailableColumns); #endif - TypesetPair(T, Generation, IDENT_VOD_PLATFORM, P->VODPlatform, AvailableColumns); TypesetPair(T, Generation, IDENT_THEME, P->Theme, AvailableColumns); CarriageReturn(T, Generation); @@ -4625,6 +4525,7 @@ PrintProject(config *C, project *P, typography *T, int Ancestors, int Indentatio CarriageReturn(T, Generation); TypesetGenre(T, Generation, P->Genre); + TypesetVODPlatform(T, Generation, P->VODPlatform); TypesetNumberingScheme(T, Generation, P->NumberingScheme); TypesetBool(T, Generation, IDENT_IGNORE_PRIVACY, P->IgnorePrivacy); TypesetBool(T, Generation, IDENT_SINGLE_BROWSER_TAB, P->SingleBrowserTab); @@ -4735,7 +4636,7 @@ PrintConfig(config *C, bool ShouldClearTerminal) PrintBool("Respecting Privacy (derived from projects)", C->RespectingPrivacy, Typography.Delimiter, ShouldFillSyntax, IndentationLevel, FALSE, TRUE); fprintf(stderr, "%s", Typography.Margin); int SecondsPerMinute = 60; - config_int_pair PrivacyCheckInterval = { .Key = IDENT_PRIVACY_CHECK_INTERVAL, .Value = C->PrivacyCheckInterval / SecondsPerMinute }; PrintIntPair(&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); PrintLogLevel(ConfigIdentifiers[IDENT_LOG_LEVEL].String, C->LogLevel, Typography.Delimiter, IndentationLevel, TRUE); @@ -4826,9 +4727,9 @@ InitVerifiers(void) } bool -IsPositioned(config_int_pair *Position) +IsPositioned(config_pair *Position) { - return Position && Position->Value != 0; + return Position && Position->int64_t != 0; } void @@ -4851,13 +4752,13 @@ PositionRolesInConfig(config *C, resolution_errors *E, config_verifiers *V, scop for(int i = 0; i < SlotCount; ++i) { scope_tree **Role = GetPlaceInBook(&RolesStaging, i); - config_int_pair *Position = GetIntPair(*Role, IDENT_POSITION); + config_pair *Position = GetPair(*Role, IDENT_POSITION); if(IsPositioned(Position)) { int TargetPos; - if(Position->Value < 0) + if(Position->int64_t < 0) { - TargetPos = SlotCount + Position->Value; + TargetPos = SlotCount + Position->int64_t; Clamp(0, TargetPos, SlotCount - 1); while(RoleSlot[TargetPos] && TargetPos > 0) { @@ -4869,9 +4770,9 @@ PositionRolesInConfig(config *C, resolution_errors *E, config_verifiers *V, scop ++TargetPos; } } - else if(Position->Value > 0) + else if(Position->int64_t > 0) { - TargetPos = Position->Value - 1; + TargetPos = Position->int64_t - 1; Clamp(0, TargetPos, SlotCount - 1); while(RoleSlot[TargetPos] && TargetPos < SlotCount - 1) { @@ -4890,7 +4791,7 @@ PositionRolesInConfig(config *C, resolution_errors *E, config_verifiers *V, scop for(int i = 0; i < SlotCount; ++i) { scope_tree **Role = GetPlaceInBook(&RolesStaging, i); - config_int_pair *Position = GetIntPair(*Role, IDENT_POSITION); + config_pair *Position = GetPair(*Role, IDENT_POSITION); if(!IsPositioned(Position)) { for(int j = 0; j < SlotCount; ++j) @@ -4934,6 +4835,7 @@ ResolveVariables(scope_tree *S) string Filepath = Wrap0(Pair->Position.Filename); switch(Pair->Key) { + // NOTE(matt): String case IDENT_DB_LOCATION: { Result->DatabaseLocation = StripSlashes(ResolveString(Result, &Errors, S, Pair, TRUE), P_ABS); } break; case IDENT_GLOBAL_SEARCH_DIR: @@ -5024,31 +4926,16 @@ ResolveVariables(scope_tree *S) { Result->QueryString = ResolveString(Result, &Errors, S, Pair, FALSE); } break; case IDENT_CACHE_DIR: { Result->CacheDir = StripSlashes(ResolveString(Result, &Errors, S, Pair, TRUE), P_ABS); } break; - default: break; - } - } - int SecondsPerMinute = 60; - for(int i = 0; i < S->IntPairs.ItemCount; ++i) - { - config_int_pair *IntPair = GetPlaceInBook(&S->IntPairs, i); - switch(IntPair->Key) - { + // NOTE(matt): int64_t case IDENT_PRIVACY_CHECK_INTERVAL: - { Result->PrivacyCheckInterval = SecondsPerMinute * IntPair->Value; } break; + { Result->PrivacyCheckInterval = SECONDS_PER_MINUTE * Pair->int64_t; } break; case IDENT_LOG_LEVEL: - { Result->LogLevel = IntPair->Value; } break; - default: break; - } - } + { Result->LogLevel = Pair->int64_t; } break; - for(int i = 0; i < S->BoolPairs.ItemCount; ++i) - { - config_bool_pair *BoolPair = GetPlaceInBook(&S->BoolPairs, i); - switch(BoolPair->Key) - { + // NOTE(matt): bool case IDENT_SUPPRESS_PROMPTS: - { Result->SuppressingPrompts = BoolPair->Value; } break; + { Result->SuppressingPrompts = Pair->bool; } break; default: break; } }