From 2eddd7a7c26fcf0aef857e8f31419a5b74864b68 Mon Sep 17 00:00:00 2001 From: Matt Mascarenhas Date: Wed, 19 Sep 2018 20:50:21 +0100 Subject: [PATCH] cinera.c: Support limitless templates Previously we had a template tag limit of 16. This commit lifts that limit to support "unlimited" tags per template. Skip already offset landmarks most efficiently when adding a new asset. New template tags: __CINERA_SEARCH_URL__ __CINERA_VOD_PLATFORM__ --- README.md | 2 + cinera/cinera.c | 498 +++++++++++++++++++++++------------------------- 2 files changed, 245 insertions(+), 255 deletions(-) diff --git a/README.md b/README.md index 1e46538..d3848c9 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ directory. Typical operation will involve setting these flags: *Optional tags available for use in your Player Template* - `` - `` +- `` *Other tags available for use in either template* - Asset tags: @@ -114,6 +115,7 @@ trigger a rehash and edit of all HTML pages citing this asset. - `` - `` +- `` - `` - `` _Only really usable if BaseURL is set (-B)_ - `` diff --git a/cinera/cinera.c b/cinera/cinera.c index ebc7899..0f16e85 100644 --- a/cinera/cinera.c +++ b/cinera/cinera.c @@ -17,7 +17,7 @@ typedef struct version CINERA_APP_VERSION = { .Major = 0, .Minor = 6, - .Patch = 0 + .Patch = 1 }; #include // NOTE(matt): varargs @@ -424,7 +424,6 @@ typedef struct // NOTE(matt): Globals arena MemoryArena; -arena TemplateArena; config Config; assets Assets; int inotifyInstance; @@ -473,6 +472,7 @@ typedef struct char URLSearch[MAX_BASE_URL_LENGTH + 1 + MAX_RELATIVE_PAGE_LOCATION_LENGTH + 1]; char URLPlayer[MAX_BASE_URL_LENGTH + 1 + MAX_RELATIVE_PAGE_LOCATION_LENGTH + 1 + MAX_PLAYER_URL_PREFIX_LENGTH + MAX_BASE_FILENAME_LENGTH + 1]; char VideoID[16]; + char VODPlatform[16]; } buffers; enum @@ -509,6 +509,7 @@ enum TAG_TITLE, TAG_VIDEO_ID, + TAG_VOD_PLATFORM, // Anywhere Optional TAG_ASSET, @@ -517,6 +518,7 @@ enum TAG_JS, TAG_PROJECT, TAG_PROJECT_ID, + TAG_SEARCH_URL, TAG_THEME, TAG_URL, TEMPLATE_TAG_COUNT, @@ -551,6 +553,7 @@ char *TemplateTags[] = { "__CINERA_TITLE__", "__CINERA_VIDEO_ID__", + "__CINERA_VOD_PLATFORM__", "__CINERA_ASSET__", "__CINERA_CSS__", @@ -558,6 +561,7 @@ char *TemplateTags[] = { "__CINERA_JS__", "__CINERA_PROJECT__", "__CINERA_PROJECT_ID__", + "__CINERA_SEARCH_URL__", "__CINERA_THEME__", "__CINERA_URL__", }; @@ -566,21 +570,21 @@ typedef struct { int Offset; uint32_t AssetIndex; - enum8(template_tags) TagCode; + enum8(template_tag_codes) TagCode; } tag_offset; typedef struct { int Validity; // NOTE(matt): Bitmask describing which page the template is valid for, i.e. contents and / or player page + int TagCapacity; int TagCount; - char Filename[256]; - tag_offset Tag[16]; + tag_offset *Tags; } template_metadata; typedef struct { + file_buffer File; template_metadata Metadata; - buffer Buffer; } template; // TODO(matt): Consider putting the ref_info and quote_info into linked lists on the heap, just to avoid all the hardcoded sizes @@ -597,15 +601,14 @@ typedef struct int Identifier; } identifier; -#define REF_MAX_IDENTIFIER 64 - +#define MAX_REF_IDENTIFIER_COUNT 64 typedef struct { char RefTitle[620]; char ID[512]; char URL[512]; char Source[256]; - identifier Identifier[REF_MAX_IDENTIFIER]; + identifier Identifier[MAX_REF_IDENTIFIER_COUNT]; int IdentifierCount; } ref_info; @@ -1348,17 +1351,48 @@ LogError(int LogLevel, char *Format, ...) } } +int +ReadFileIntoBuffer(file_buffer *File, int BufferPadding) +{ + if(!(File->Handle = fopen(File->Path, "r"))) // TODO(matt): Fuller error handling + { + return RC_ERROR_FILE; + } + + fseek(File->Handle, 0, SEEK_END); + File->FileSize = ftell(File->Handle); + File->Buffer.Size = File->FileSize + 1 + BufferPadding; // NOTE(matt): +1 to accommodate a NULL terminator + fseek(File->Handle, 0, SEEK_SET); + + // TODO(matt): Consider using the MemoryArena? Maybe have separate ReadFileIntoMemory() and ReadFileIntoArena() + if(!(File->Buffer.Location = malloc(File->Buffer.Size))) + { + fclose(File->Handle); + return RC_ERROR_MEMORY; + } + File->Buffer.Ptr = File->Buffer.Location; + + fread(File->Buffer.Location, File->FileSize, 1, File->Handle); + File->Buffer.Location[File->FileSize] = '\0'; + fclose(File->Handle); + File->Buffer.ID = File->Path; + return RC_SUCCESS; +} + void FreeBuffer(buffer *Buffer) { free(Buffer->Location); Buffer->Location = 0; + Buffer->Ptr = 0; + Buffer->Size = 0; #if DEBUG_MEM FILE *MemLog = fopen("/home/matt/cinera_mem", "a+"); fprintf(MemLog, " Freed %s\n", Buffer->ID); fclose(MemLog); printf(" Freed %s\n", Buffer->ID); #endif + Buffer->ID = 0; } int @@ -1439,7 +1473,7 @@ enum TEMPLATE_SEARCH, TEMPLATE_PLAYER, TEMPLATE_BESPOKE -} templates; +} template_types; char * GetDirectoryPath(char *Filepath) @@ -1477,19 +1511,19 @@ GetBaseFilename(char *Filepath, } void -ConstructTemplatePath(template *Template, int TemplateType) +ConstructTemplatePath(template *Template, enum8(template_types) Type) { // NOTE(matt): Bespoke template paths are set relative to: // in Project Edition: ProjectDir // in Single Edition: Parent directory of .hmml file - if(Template->Metadata.Filename[0] != '/') + if(Template->File.Path[0] != '/') { char Temp[256]; - CopyString(Temp, sizeof(Temp), "%s", Template->Metadata.Filename); - char *Ptr = Template->Metadata.Filename; - char *End = Template->Metadata.Filename + sizeof(Template->Metadata.Filename); - if(TemplateType == TEMPLATE_BESPOKE) + CopyString(Temp, sizeof(Temp), "%s", Template->File.Path); + char *Ptr = Template->File.Path; + char *End = Template->File.Path + sizeof(Template->File.Path); + if(Type == TEMPLATE_BESPOKE) { if(Config.Edition == EDITION_SINGLE) { @@ -1508,87 +1542,61 @@ ConstructTemplatePath(template *Template, int TemplateType) } } -int -InitTemplate(template **Template) +void +FitTemplateTag(template *Template) { - if(TemplateArena.Ptr - TemplateArena.Location + sizeof(template) > TemplateArena.Size) + int BlockSize = 16; + if(Template->Metadata.TagCount == Template->Metadata.TagCapacity) { - return RC_ARENA_FULL; + Template->Metadata.TagCapacity += BlockSize; + if(Template->Metadata.Tags) + { + Template->Metadata.Tags = realloc(Template->Metadata.Tags, Template->Metadata.TagCapacity * sizeof(*Template->Metadata.Tags)); + } + else + { + Template->Metadata.Tags = calloc(Template->Metadata.TagCapacity, sizeof(*Template->Metadata.Tags)); + } } - *Template = (template *)TemplateArena.Ptr; - Clear((*Template)->Metadata.Filename, 256); // NOTE(matt): template_metadata specifies Filename[256] - (*Template)->Metadata.Validity = 0; - (*Template)->Metadata.TagCount = 0; - for(int i = 0; i < 16; ++i) // NOTE(matt): template_metadata specifies Tag[16] - { - (*Template)->Metadata.Tag[i].Offset = 0; - (*Template)->Metadata.Tag[i].TagCode = 0; - } - TemplateArena.Ptr += sizeof(template); - return RC_SUCCESS; } -int -ClaimTemplate(template **Template, char *Location, int TemplateType) +void +PushTemplateTag(template *Template, int Offset, enum8(template_tag_types) TagType, int AssetIndex) { - CopyString((*Template)->Metadata.Filename, sizeof((*Template)->Metadata.Filename), "%s", Location); - ConstructTemplatePath((*Template), TemplateType); - - fprintf(stderr, "%sPacking%s template: %s\n", ColourStrings[CS_ONGOING], ColourStrings[CS_END], (*Template)->Metadata.Filename); - - FILE *File; - if(!(File = fopen((*Template)->Metadata.Filename, "r"))) - { - LogError(LOG_ERROR, "Unable to open template %s: %s", (*Template)->Metadata.Filename, strerror(errno)); - fprintf(stderr, "Unable to open template %s: %s\n", (*Template)->Metadata.Filename, strerror(errno)); - Clear((*Template)->Metadata.Filename, 256); // NOTE(matt): template_metadata specifies Filename[256] - return RC_ERROR_FILE; - } - fseek(File, 0, SEEK_END); - (*Template)->Buffer.Size = ftell(File); - if(TemplateArena.Ptr - TemplateArena.Location + (*Template)->Buffer.Size > TemplateArena.Size) - { - Clear((*Template)->Metadata.Filename, 256); // NOTE(matt): template_metadata specifies Filename[256] - return RC_ARENA_FULL; - } - - (*Template)->Buffer.Location = TemplateArena.Ptr; - (*Template)->Buffer.Ptr = (*Template)->Buffer.Location; - (*Template)->Buffer.ID = (*Template)->Metadata.Filename; - - fseek(File, 0, SEEK_SET); - fread((*Template)->Buffer.Location, (*Template)->Buffer.Size, 1, File); - fclose(File); - - TemplateArena.Ptr += (*Template)->Buffer.Size; - -#if DEBUG - printf(" ClaimTemplate(%s): %d\n" - " Total ClaimedMemory: %ld\n\n", (*Template)->Metadata.Filename, (*Template)->Buffer.Size, TemplateArena.Ptr - TemplateArena.Location); -#endif - return RC_SUCCESS; + FitTemplateTag(Template); + Template->Metadata.Tags[Template->Metadata.TagCount].Offset = Offset; + Template->Metadata.Tags[Template->Metadata.TagCount].TagCode = TagType; + Template->Metadata.Tags[Template->Metadata.TagCount].AssetIndex = AssetIndex; + ++Template->Metadata.TagCount; } -int -DeclaimTemplate(template *Template) +void +ClearTemplateMetadata(template *Template) { - Clear(Template->Metadata.Filename, 256); - Template->Metadata.Validity = 0; - for(int i = 0; i < Template->Metadata.TagCount; ++i) - { - Template->Metadata.Tag[i].Offset = 0; - Template->Metadata.Tag[i].TagCode = 0; - } + Template->Metadata.TagCapacity = 0; Template->Metadata.TagCount = 0; - TemplateArena.Ptr -= (*Template).Buffer.Size; + Template->Metadata.Validity = 0; +} -#if DEBUG - printf("DeclaimTemplate(%s)\n" - " Total ClaimedMemory: %ld\n\n", - (*Template).Metadata.Filename, - TemplateArena.Ptr - TemplateArena.Location); -#endif - return RC_SUCCESS; +void +InitTemplate(template *Template, char *Location, enum8(template_types) Type) +{ + CopyStringNoFormat(Template->File.Path, sizeof(Template->File.Path), Location); + ConstructTemplatePath(Template, Type); + ReadFileIntoBuffer(&Template->File, 0); + ClearTemplateMetadata(Template); +} + +void +FreeTemplate(template *Template) +{ + FreeBuffer(&Template->File.Buffer); + Clear(Template->File.Path, sizeof(Template->File.Path)); + Template->File.FileSize = 0; + + free(Template->Metadata.Tags); + Template->Metadata.Tags = 0; + ClearTemplateMetadata(Template); } int @@ -1771,34 +1779,6 @@ enum CreditsError_NoCredentials } credits_errors; -int -ReadFileIntoBuffer(file_buffer *File, int BufferPadding) -{ - if(!(File->Handle = fopen(File->Path, "r"))) // TODO(matt): Fuller error handling - { - return RC_ERROR_FILE; - } - - fseek(File->Handle, 0, SEEK_END); - File->FileSize = ftell(File->Handle); - File->Buffer.Size = File->FileSize + 1 + BufferPadding; // NOTE(matt): +1 to accommodate a NULL terminator - fseek(File->Handle, 0, SEEK_SET); - - // TODO(matt): Consider using the MemoryArena? Maybe have separate ReadFileIntoMemory() and ReadFileIntoArena() - if(!(File->Buffer.Location = malloc(File->Buffer.Size))) - { - fclose(File->Handle); - return RC_ERROR_MEMORY; - } - File->Buffer.Ptr = File->Buffer.Location; - - fread(File->Buffer.Location, File->FileSize, 1, File->Handle); - File->Buffer.Location[File->FileSize] = '\0'; - fclose(File->Handle); - File->Buffer.ID = File->Path; - return RC_SUCCESS; -} - size_t StringToFletcher32(const char *Data, size_t Length) {// https://en.wikipedia.org/wiki/Fletcher%27s_checksum @@ -3556,6 +3536,7 @@ PrintUsage(char *BinaryLocation, config *DefaultConfig) " Optional tags available for use in your Player Template:\n" " \n" " \n" + " \n" "\n" " Other tags available for use in either template:\n" " Asset tags:\n" @@ -3585,6 +3566,7 @@ PrintUsage(char *BinaryLocation, config *DefaultConfig) "\n" " \n" " \n" + " \n" " \n" " \n" " Only really usable if BaseURL is set %s(-B)%s\n" @@ -3791,13 +3773,13 @@ StripPWDIndicators(char *Path) } int -ParseAssetString(template **Template, enum8(template_tag_codes) TagIndex, uint32_t *AssetIndexPtr) +ParseAssetString(template *Template, enum8(template_tag_codes) TagIndex, uint32_t *AssetIndexPtr) { - char *Ptr = (*Template)->Buffer.Ptr + StringLength(TemplateTags[TagIndex]); - ConsumeWhitespace(&(*Template)->Buffer, &Ptr); + char *Ptr = Template->File.Buffer.Ptr + StringLength(TemplateTags[TagIndex]); + ConsumeWhitespace(&Template->File.Buffer, &Ptr); buffer AssetString; ClaimBuffer(&AssetString, "AssetString", MAX_ASSET_FILENAME_LENGTH); - if(ParseQuotedString(&AssetString, &(*Template)->Buffer, &Ptr, TagIndex) == RC_ERROR_PARSING) + if(ParseQuotedString(&AssetString, &Template->File.Buffer, &Ptr, TagIndex) == RC_ERROR_PARSING) { DeclaimBuffer(&AssetString); return RC_ERROR_PARSING; @@ -3820,27 +3802,18 @@ ParseAssetString(template **Template, enum8(template_tag_codes) TagIndex, uint32 } int -ValidateTemplate(template **Template, char *Location, enum8(templates) TemplateType) +PackTemplate(template *Template, char *Location, enum8(template_types) Type) { // TODO(matt): Record line numbers and contextual information: // // // < > // "); } break; case TAG_CUSTOM0: CopyStringToBufferNoFormat(&Output, CollationBuffers->Custom0); break; @@ -6042,18 +6023,18 @@ BuffersToHTML(buffers *CollationBuffers, template *Template, char *OutputPath, i case TAG_CUSTOM15: CopyStringToBufferNoFormat(&Output, CollationBuffers->Custom15); break; } - DepartComment(&Template->Buffer); + DepartComment(&Template->File.Buffer); } - while(Template->Buffer.Ptr - Template->Buffer.Location < Template->Buffer.Size) + while(Template->File.Buffer.Ptr - Template->File.Buffer.Location < Template->File.Buffer.Size) { - *Output.Ptr++ = *Template->Buffer.Ptr++; + *Output.Ptr++ = *Template->File.Buffer.Ptr++; } FILE *OutFile; if(!(OutFile = fopen(Config.Edition == EDITION_PROJECT ? OutputPath : Config.OutIntegratedLocation, "w"))) { LogError(LOG_ERROR, "Unable to open output file %s: %s", Config.Edition == EDITION_PROJECT ? OutputPath : Config.OutIntegratedLocation, strerror(errno)); - free(Output.Location); + FreeBuffer(&Output); #if DEBUG_MEM MemLog = fopen("/home/matt/cinera_mem", "a+"); @@ -6067,7 +6048,7 @@ BuffersToHTML(buffers *CollationBuffers, template *Template, char *OutputPath, i fwrite(Output.Location, Output.Ptr - Output.Location, 1, OutFile); fclose(OutFile); - free(Output.Location); + FreeBuffer(&Output); #if DEBUG_MEM MemLog = fopen("/home/matt/cinera_mem", "a+"); @@ -6455,7 +6436,7 @@ SnipeEntryIntoMetadataBuffer(db_entry *Entry, int EntryIndex) } int -InsertIntoDB(neighbourhood *N, buffers *CollationBuffers, template **BespokeTemplate, char *BaseFilename, bool RecheckingPrivacy, bool *Reinserting) +InsertIntoDB(neighbourhood *N, buffers *CollationBuffers, template *BespokeTemplate, char *BaseFilename, bool RecheckingPrivacy, bool *Reinserting) { enum8(edit_types) EditType = EDIT_APPEND; int EntryInsertionStart = StringLength("---\n"); @@ -6630,7 +6611,7 @@ PrintLandmarks(void *FirstLandmark, int LandmarkCount) } void -ProcessPrevLandmarks(neighbourhood *N, void *FirstLandmark, int ExistingLandmarkCount, landmark_range *CurrentTarget, bool OffsetLandmarks, int *RunningIndex) +ProcessPrevLandmarks(neighbourhood *N, void *FirstLandmark, int ExistingLandmarkCount, landmark_range *CurrentTarget, int *RunningIndex) { if(N->PrevIndex >= 0) { @@ -6641,7 +6622,7 @@ ProcessPrevLandmarks(neighbourhood *N, void *FirstLandmark, int ExistingLandmark for(int j = 0; j < FormerTarget.Length; ++j, ++*RunningIndex) { db_landmark Landmark = *(db_landmark *)(FirstLandmark + sizeof(Landmark) * *RunningIndex); - if(!OffsetLandmarks && Landmark.Position >= N->PreLinkPrevOffsetTotal) + if(Landmark.Position >= N->PreLinkPrevOffsetTotal) { Landmark.Position += N->PrevOffsetModifier; } @@ -6656,7 +6637,7 @@ ProcessPrevLandmarks(neighbourhood *N, void *FirstLandmark, int ExistingLandmark } void -ProcessNextLandmarks(neighbourhood *N, void *FirstLandmark, int ExistingLandmarkCount, bool OffsetLandmarks, int *RunningIndex, enum8(edit_types) EditType) +ProcessNextLandmarks(neighbourhood *N, void *FirstLandmark, int ExistingLandmarkCount, int *RunningIndex, enum8(edit_types) EditType) { if(N->NextIndex >= 0 && *RunningIndex < ExistingLandmarkCount) { @@ -6666,7 +6647,7 @@ ProcessNextLandmarks(neighbourhood *N, void *FirstLandmark, int ExistingLandmark for(int j = 0; j < LatterTarget.Length; ++j, ++*RunningIndex) { Landmark = *(db_landmark *)(FirstLandmark + sizeof(Landmark) * *RunningIndex); - if(!OffsetLandmarks && Landmark.Position >= N->PreLinkNextOffsetTotal) + if(Landmark.Position >= N->PreLinkNextOffsetTotal) { Landmark.Position += N->NextOffsetModifier; } @@ -6763,11 +6744,11 @@ DeleteLandmarks(neighbourhood *N) DB.Asset.LandmarkCount -= DeletionTarget.Length; fwrite(&DB.Asset, sizeof(DB.Asset), 1, DB.Metadata.Handle); - ProcessPrevLandmarks(N, FirstLandmark, ExistingLandmarkCount, &DeletionTarget, Assets.Asset[AssetIndex].OffsetLandmarks, &RunningIndex); + ProcessPrevLandmarks(N, FirstLandmark, ExistingLandmarkCount, &DeletionTarget, &RunningIndex); RunningIndex += DeletionTarget.Length; - ProcessNextLandmarks(N, FirstLandmark, ExistingLandmarkCount, Assets.Asset[AssetIndex].OffsetLandmarks, &RunningIndex, EDIT_DELETION); + ProcessNextLandmarks(N, FirstLandmark, ExistingLandmarkCount, &RunningIndex, EDIT_DELETION); DB.Metadata.Buffer.Ptr += sizeof(db_landmark) * ExistingLandmarkCount; } CycleFile(&DB.Metadata); @@ -6800,37 +6781,45 @@ AddLandmarks(neighbourhood *N, enum8(edit_types) EditType) if(!StringsDiffer(DB.Asset.Filename, Assets.Asset[i].Filename) && DB.Asset.Type == Assets.Asset[i].Type) { Assets.Asset[i].Known = TRUE; - DB.Asset.LandmarkCount += Assets.Asset[i].PlayerLandmarkCount; - landmark_range ThisTarget; - if(ExistingLandmarkCount > 0) + if(!Assets.Asset[i].OffsetLandmarks) { - ThisTarget = BinarySearchForMetadataLandmark(FirstLandmark, N->ThisIndex, ExistingLandmarkCount); + DB.Asset.LandmarkCount += Assets.Asset[i].PlayerLandmarkCount; + landmark_range ThisTarget; + if(ExistingLandmarkCount > 0) + { + ThisTarget = BinarySearchForMetadataLandmark(FirstLandmark, N->ThisIndex, ExistingLandmarkCount); - if(EditType == EDIT_REINSERTION) { DB.Asset.LandmarkCount -= ThisTarget.Length; } + if(EditType == EDIT_REINSERTION) { DB.Asset.LandmarkCount -= ThisTarget.Length; } + } + + fwrite(&DB.Asset, sizeof(DB.Asset), 1, DB.Metadata.Handle); + + if(ExistingLandmarkCount > 0) + { + ProcessPrevLandmarks(N, FirstLandmark, ExistingLandmarkCount, &ThisTarget, &RunningIndex); + } + + for(int j = 0; j < Assets.Asset[i].PlayerLandmarkCount; ++j) + { + db_landmark Landmark; + Landmark.EntryIndex = N->ThisIndex; + Landmark.Position = Assets.Asset[i].PlayerLandmark[j]; + fwrite(&Landmark, sizeof(Landmark), 1, DB.Metadata.Handle); + } + + if(ExistingLandmarkCount > 0) + { + if(EditType == EDIT_REINSERTION) { RunningIndex += ThisTarget.Length; } + + ProcessNextLandmarks(N, FirstLandmark, ExistingLandmarkCount, &RunningIndex, EditType); + } + Assets.Asset[i].OffsetLandmarks = TRUE; } - - fwrite(&DB.Asset, sizeof(DB.Asset), 1, DB.Metadata.Handle); - - if(ExistingLandmarkCount > 0) + else { - ProcessPrevLandmarks(N, FirstLandmark, ExistingLandmarkCount, &ThisTarget, Assets.Asset[i].OffsetLandmarks, &RunningIndex); + fwrite(&DB.Asset, sizeof(DB.Asset), 1, DB.Metadata.Handle); + fwrite(DB.Metadata.Buffer.Ptr, sizeof(db_landmark) * ExistingLandmarkCount, 1, DB.Metadata.Handle); } - - for(int j = 0; j < Assets.Asset[i].PlayerLandmarkCount; ++j) - { - db_landmark Landmark; - Landmark.EntryIndex = N->ThisIndex; - Landmark.Position = Assets.Asset[i].PlayerLandmark[j]; - fwrite(&Landmark, sizeof(Landmark), 1, DB.Metadata.Handle); - } - - if(ExistingLandmarkCount > 0) - { - if(EditType == EDIT_REINSERTION) { RunningIndex += ThisTarget.Length; } - - ProcessNextLandmarks(N, FirstLandmark, ExistingLandmarkCount, Assets.Asset[i].OffsetLandmarks, &RunningIndex, EditType); - } - Assets.Asset[i].OffsetLandmarks = TRUE; break; } } @@ -7634,7 +7623,7 @@ GeneratePlayerPage(neighbourhood *N, buffers *CollationBuffers, template *Player bool SearchInTemplate = FALSE; for(int TagIndex = 0; TagIndex < PlayerTemplate->Metadata.TagCount; ++TagIndex) { - if(PlayerTemplate->Metadata.Tag[TagIndex].TagCode == TAG_SEARCH) + if(PlayerTemplate->Metadata.Tags[TagIndex].TagCode == TAG_SEARCH) { SearchInTemplate = TRUE; SearchToBuffer(CollationBuffers); @@ -7713,13 +7702,13 @@ int InsertEntry(neighbourhood *Neighbourhood, buffers *CollationBuffers, template *PlayerTemplate, template *BespokeTemplate, char *BaseFilename, bool RecheckingPrivacy) { bool Reinserting = FALSE; - if(InsertIntoDB(Neighbourhood, CollationBuffers, &BespokeTemplate, BaseFilename, RecheckingPrivacy, &Reinserting) == RC_SUCCESS) + if(InsertIntoDB(Neighbourhood, CollationBuffers, BespokeTemplate, BaseFilename, RecheckingPrivacy, &Reinserting) == RC_SUCCESS) { LinkNeighbours(Neighbourhood, LINK_INCLUDE); - if(StringsDiffer(BespokeTemplate->Metadata.Filename, "")) + if(BespokeTemplate->File.Buffer.Location) { GeneratePlayerPage(Neighbourhood, CollationBuffers, BespokeTemplate, BaseFilename, Reinserting); - DeclaimTemplate(BespokeTemplate); + FreeTemplate(BespokeTemplate); } else { @@ -8799,7 +8788,6 @@ main(int ArgC, char **Args) // NOTE(matt): Init MemoryArenas (they are global) InitMemoryArena(&MemoryArena, Megabytes(4)); - InitMemoryArena(&TemplateArena, Kilobytes(16)); // TODO(matt): Consider some way of making this growable #if DEBUG_MEM FILE *MemLog = fopen("/home/matt/cinera_mem", "a+"); @@ -9029,19 +9017,19 @@ main(int ArgC, char **Args) inotifyInstance = inotify_init1(IN_NONBLOCK); printf("┌╼ Hashing assets ╾┐\n"); - // NOTE(matt): This had to happen before ValidateTemplate() because those guys may need to do PushAsset() and we must + // NOTE(matt): This had to happen before PackTemplate() because those guys may need to do PushAsset() and we must // ensure that the builtin assets get placed correctly InitAssets(); } printf("┌╼ Packing templates ╾┐\n"); - template *SearchTemplate; InitTemplate(&SearchTemplate); - template *PlayerTemplate; InitTemplate(&PlayerTemplate); - template *BespokeTemplate; InitTemplate(&BespokeTemplate); + template SearchTemplate; + template PlayerTemplate; + template BespokeTemplate; if(StringsDiffer(Config.TemplatePlayerLocation, "")) { - switch(ValidateTemplate(&PlayerTemplate, Config.TemplatePlayerLocation, TEMPLATE_PLAYER)) + switch(PackTemplate(&PlayerTemplate, Config.TemplatePlayerLocation, TEMPLATE_PLAYER)) { case RC_INVALID_TEMPLATE: // Invalid template case RC_ERROR_FILE: // Could not load template @@ -9054,7 +9042,7 @@ main(int ArgC, char **Args) if(Config.Edition == EDITION_PROJECT && StringsDiffer(Config.TemplateSearchLocation, "")) { - switch(ValidateTemplate(&SearchTemplate, Config.TemplateSearchLocation, TEMPLATE_SEARCH)) + switch(PackTemplate(&SearchTemplate, Config.TemplateSearchLocation, TEMPLATE_SEARCH)) { case RC_INVALID_TEMPLATE: // Invalid template case RC_ERROR_MEMORY: // Could not allocate memory for template @@ -9068,7 +9056,7 @@ main(int ArgC, char **Args) if(Config.Edition == EDITION_PROJECT) { printf("\n┌╼ Synchronising with Annotations Directory ╾┐\n"); - SyncDBWithInput(&CollationBuffers, SearchTemplate, PlayerTemplate, BespokeTemplate); + SyncDBWithInput(&CollationBuffers, &SearchTemplate, &PlayerTemplate, &BespokeTemplate); if(Config.Mode & MODE_ONESHOT) { goto RIP; @@ -9081,7 +9069,7 @@ main(int ArgC, char **Args) // NOTE(matt): Do we want to also watch IN_DELETE_SELF events? PushHMMLWatchHandle(); - while(MonitorFilesystem(&CollationBuffers, SearchTemplate, PlayerTemplate, BespokeTemplate) != RC_ARENA_FULL) + while(MonitorFilesystem(&CollationBuffers, &SearchTemplate, &PlayerTemplate, &BespokeTemplate) != RC_ARENA_FULL) { // TODO(matt): Refetch the quotes and rebuild player pages if needed // @@ -9095,7 +9083,7 @@ main(int ArgC, char **Args) // if(!(Config.Mode & MODE_NOPRIVACY) && time(0) - LastPrivacyCheck > 60 * 60 * 4) { - RecheckPrivacy(&CollationBuffers, SearchTemplate, PlayerTemplate, BespokeTemplate); + RecheckPrivacy(&CollationBuffers, &SearchTemplate, &PlayerTemplate, &BespokeTemplate); } sleep(Config.UpdateInterval); } @@ -9141,16 +9129,16 @@ NextFile: break; }; - HasBespokeTemplate = StringsDiffer(BespokeTemplate->Metadata.Filename, ""); + HasBespokeTemplate = BespokeTemplate.File.Buffer.Location != NULL; switch(BuffersToHTML(&CollationBuffers, - HasBespokeTemplate ? BespokeTemplate : PlayerTemplate, + HasBespokeTemplate ? &BespokeTemplate : &PlayerTemplate, 0, PAGE_PLAYER, 0)) { // TODO(matt): Actually sort out the fatality of these cases case RC_INVALID_TEMPLATE: - if(HasBespokeTemplate) { DeclaimTemplate(BespokeTemplate); } + if(HasBespokeTemplate) { FreeTemplate(&BespokeTemplate); } if(FileIndex < (ArgC - 1)) { goto NextFile; } case RC_ERROR_MEMORY: case RC_ERROR_FILE: @@ -9160,20 +9148,20 @@ NextFile: #if 0 fprintf(stdout, "%sWritten%s %s\n", HasBespokeTemplate ? Config.OutIntegratedLocation : Config.OutLocation); #endif - if(HasBespokeTemplate) { DeclaimTemplate(BespokeTemplate); } + if(HasBespokeTemplate) { FreeTemplate(&BespokeTemplate); } break; }; } } } - if(StringsDiffer(PlayerTemplate->Metadata.Filename, "")) + if(PlayerTemplate.File.Buffer.Location) { - DeclaimTemplate(PlayerTemplate); + FreeTemplate(&PlayerTemplate); } - if(Config.Edition == EDITION_PROJECT && StringsDiffer(SearchTemplate->Metadata.Filename, "")) + if(Config.Edition == EDITION_PROJECT && SearchTemplate.File.Buffer.Location) { - DeclaimTemplate(SearchTemplate); + FreeTemplate(&SearchTemplate); } DeclaimBuffer(&CollationBuffers.SearchEntry);