diff --git a/cinera/cinera.c b/cinera/cinera.c index 2bf26b2..ecfcb6b 100644 --- a/cinera/cinera.c +++ b/cinera/cinera.c @@ -1,7 +1,7 @@ #if 0 ctime -begin ${0%.*}.ctm gcc -g -fsanitize=address -Wall -std=c99 -pipe $0 -o ${0%.*} hmml.a -lcurl -#gcc -Wall -std=c99 -pipe $0 -o ${0%.*} hmml.a -lcurl +#gcc -O2 -Wall -std=c99 -pipe $0 -o ${0%.*} hmml.a -lcurl ctime -end ${0%.*}.ctm exit #endif @@ -14,7 +14,7 @@ typedef struct version CINERA_APP_VERSION = { .Major = 0, .Minor = 5, - .Patch = 16 + .Patch = 17 }; // TODO(matt): Copy in the DB 3 stuff from cinera_working.c @@ -69,9 +69,7 @@ enum enum { - MODE_BARE = 1 << 0, - MODE_INTEGRATE = 1 << 1, - MODE_ONESHOT = 1 << 2 + MODE_ONESHOT = 1 << 0, } modes; enum @@ -95,35 +93,6 @@ enum RC_SUCCESS } returns; -typedef struct -{ - int Edition; - int LogLevel; - int Mode; - int UpdateInterval; - bool ForceIntegration; - char *RootDir; // Absolute - char *RootURL; - char *CSSDir; // Relative to RootDir and RootURL - char *ImagesDir; // Relative to RootDir and RootURL - char *JSDir; // Relative to RootDir and RootURL - char *ProjectID; - char *BaseDir; // Absolute - char *BaseURL; - char *IndexLocation; // Relative to BaseDir and BaseURL - char *PlayerLocation; // Relative to BaseDir and BaseURL - char *TemplateIndexLocation; // Relative to RootDir and RootURL - char *TemplatePlayerLocation; // Relative to RootDir and RootURL - char *Theme; - char CacheDir[256]; - char *DefaultMedium; - char *OutLocation; - char *OutIntegratedLocation; - char *ProjectDir; - char *PlayerURLPrefix; /* NOTE(matt): This will become a full blown customisable output URL. - For now it simply replaces the ProjectID */ -} config; - typedef struct { void *Location; @@ -132,10 +101,6 @@ typedef struct int Size; } arena; -// NOTE(matt): Globals -config Config; -arena MemoryArena; - typedef struct { char *Location; @@ -152,6 +117,23 @@ typedef struct int FileSize; } file_buffer; +typedef struct +{ + buffer IncludesIndex; + buffer Search; + buffer Index; // NOTE(matt): This buffer is malloc'd separately, rather than claimed from the memory_arena + buffer ScriptIndex; + buffer IncludesPlayer; + buffer Menus; + buffer Player; + buffer ScriptPlayer; + char ProjectName[32]; + char Title[256]; + char URLIndex[2048]; + char URLPlayer[2048]; + char VideoID[16]; +} buffers; + enum { // Contents Page @@ -210,20 +192,48 @@ typedef struct typedef struct { - buffer IncludesIndex; - buffer Search; - buffer Index; // NOTE(matt): This buffer is malloc'd separately, rather than claimed from the memory_arena - buffer ScriptIndex; - buffer IncludesPlayer; - buffer Menus; - buffer Player; - buffer ScriptPlayer; - char ProjectName[32]; - char Title[256]; - char URLIndex[2048]; - char URLPlayer[2048]; - char VideoID[16]; -} buffers; + // Universal + char CacheDir[256]; + int Edition; + int LogLevel; + int Mode; + int UpdateInterval; + bool ForceIntegration; + + // Advisedly universal, although could be per-project + char *RootDir; // Absolute + char *RootURL; + char *CSSDir; // Relative to Root{Dir,URL} + char *ImagesDir; // Relative to Root{Dir,URL} + char *JSDir; // Relative to Root{Dir,URL} + + // Per Project + char *ProjectID; + char *Theme; + char *DefaultMedium; + + // Per Project - Input + char *ProjectDir; // Absolute + char *TemplatesDir; // Absolute + char *TemplateIndexLocation; // Relative to TemplatesDir ??? + char *TemplatePlayerLocation; // Relative to TemplatesDir ??? + + // Per Project - Output + char *BaseDir; // Absolute + char *BaseURL; + char *IndexLocation; // Relative to Base{Dir,URL} + char *PlayerLocation; // Relative to Base{Dir,URL} + char *PlayerURLPrefix; /* NOTE(matt): This will become a full blown customisable output URL. + For now it simply replaces the ProjectID */ + + // Single Edition - Output + char *OutLocation; + char *OutIntegratedLocation; +} config; + +// NOTE(matt): Globals +config Config = {}; +arena MemoryArena; // TODO(matt): Consider putting the ref_info and quote_info into linked lists on the heap, just to avoid all the hardcoded sizes @@ -611,7 +621,7 @@ LogUsage(buffer *Buffer) FILE *LogFile; if(!(LogFile = fopen(LogPath, "a+"))) { - MakeDir(CacheDir); + MakeDir(Config.CacheDir); if(!(LogFile = fopen(LogPath, "a+"))) { perror("LogUsage"); @@ -693,9 +703,9 @@ ClaimBuffer(buffer *Buffer, char *ID, int Size) *Buffer->Location = '\0'; Buffer->Ptr = Buffer->Location; #if DEBUG - float PercentageUsed = (float)(MemoryArena->Ptr - MemoryArena->Location) / MemoryArena->Size * 100; + float PercentageUsed = (float)(MemoryArena.Ptr - MemoryArena.Location) / MemoryArena.Size * 100; printf(" ClaimBuffer(%s): %d\n" - " Total ClaimedMemory: %ld (%.2f%%, leaving %ld free)\n\n", Buffer->ID, Buffer->Size, MemoryArena->Ptr - MemoryArena->Location, PercentageUsed, MemoryArena->Size - (MemoryArena->Ptr - MemoryArena->Location)); + " Total ClaimedMemory: %ld (%.2f%%, leaving %ld free)\n\n", Buffer->ID, Buffer->Size, MemoryArena.Ptr - MemoryArena.Location, PercentageUsed, MemoryArena.Size - (MemoryArena.Ptr - MemoryArena.Location)); #endif return RC_SUCCESS; } @@ -741,20 +751,72 @@ void RewindBuffer(buffer *Buffer) Buffer->Ptr = Buffer->Location; } -int -ClaimTemplate(template **Template, char *Location) +enum { - *Template = (template *)MemoryArena.Ptr; - (*Template)->Buffer.Location = MemoryArena.Ptr + sizeof(template); - (*Template)->Buffer.Ptr = (*Template)->Buffer.Location; - (*Template)->Buffer.ID = Location; - if(Location[0] != '/') + TEMPLATE_INDEX, + TEMPLATE_PLAYER, + TEMPLATE_BESPOKE +} templates; + +void +ConstructTemplatePath(template *Template, int TemplateType) +{ + // TODO(matt): Consider just straight up having the TemplateDir relative to the ProjectDir... + if(Template->Metadata.Filename[0] != '/') { - CopyString((*Template)->Metadata.Filename, "%s/%s", Config.RootDir, Location); + char Temp[256]; + CopyString(Temp, Template->Metadata.Filename); + char *Ptr = Template->Metadata.Filename; + if(TemplateType == TEMPLATE_BESPOKE) + { + Ptr += CopyString(Ptr, "%s/", Config.ProjectDir); + } + else + { + Ptr += CopyString(Ptr, "%s/", Config.TemplatesDir); + } + CopyString(Ptr, "%s", Temp); } - else +} + +void +Clear(char *String, int Size) +{ + for(int i = 0; i < Size; ++i) { - CopyString((*Template)->Metadata.Filename, "%s", Location); + String[i] = 0; + } +} + +int +InitTemplate(template **Template) +{ + if(MemoryArena.Ptr - MemoryArena.Location + sizeof(template) > MemoryArena.Size) + { + return RC_ARENA_FULL; + } + *Template = (template *)MemoryArena.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; + } + MemoryArena.Ptr += sizeof(template); + return RC_SUCCESS; +} + +int +ClaimTemplate(template **Template, char *Location, int TemplateType) +{ + CopyString((*Template)->Metadata.Filename, Location); + ConstructTemplatePath((*Template), TemplateType); + + if(TemplateType == TEMPLATE_BESPOKE) + { + fprintf(stderr, "\e[0;35mPacking\e[0m template: %s\n", (*Template)->Metadata.Filename); } FILE *File; @@ -762,24 +824,30 @@ ClaimTemplate(template **Template, char *Location) { 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(MemoryArena.Ptr - MemoryArena.Location + sizeof(template) + (*Template)->Buffer.Size > MemoryArena.Size) + if(MemoryArena.Ptr - MemoryArena.Location + (*Template)->Buffer.Size > MemoryArena.Size) { + Clear((*Template)->Metadata.Filename, 256); // NOTE(matt): template_metadata specifies Filename[256] return RC_ARENA_FULL; } - MemoryArena.Ptr += sizeof(template) + (*Template)->Buffer.Size; + (*Template)->Buffer.Location = MemoryArena.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); + MemoryArena.Ptr += (*Template)->Buffer.Size; + #if DEBUG - printf(" ClaimTemplate(%s): %ld\n" - " Total ClaimedMemory: %ld\n\n", (*Template)->Metadata.Filename, sizeof(template) + (*Template)->Buffer.Size, MemoryArena->Ptr - MemoryArena->Location); + printf(" ClaimTemplate(%s): %d\n" + " Total ClaimedMemory: %ld\n\n", (*Template)->Metadata.Filename, (*Template)->Buffer.Size, MemoryArena.Ptr - MemoryArena.Location); #endif return RC_SUCCESS; } @@ -787,7 +855,16 @@ ClaimTemplate(template **Template, char *Location) int DeclaimTemplate(template *Template) { - MemoryArena.Ptr -= (sizeof(template) + (*Template).Buffer.Size); + 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.TagCount = 0; + MemoryArena.Ptr -= (*Template).Buffer.Size; + #if DEBUG printf("DeclaimTemplate(%s)\n" " Total ClaimedMemory: %ld\n\n", @@ -1678,72 +1755,110 @@ GenerateTopicColours(char *Topic) void PrintUsage(char *BinaryLocation, config *DefaultConfig) { - fprintf(stderr, "Usage: %s [option(s)] filename(s)\n" + fprintf(stderr, + "Usage: %s [option(s)] filename(s)\n" "\n" "Options:\n" - " Paths: \n" + " Paths: \e[1;30m(advisedly universal, but may be set per-(sub)project as required)\e[0m\n" " -r \n" " Override default root directory (\"%s\")\n" " -R \n" " Override default root URL (\"%s\")\n" " \e[1;31mIMPORTANT\e[0m: -r and -R must correspond to the same location\n" - " -c \n" - " Override default CSS directory (\"%s\"), relative to root\n" - " -i \n" - " Override default images directory (\"%s\"), relative to root\n" - " -j \n" - " Override default JS directory (\"%s\"), relative to root\n" + " \e[1;30mUNSUPPORTED: If you move files from RootDir, the RootURL should\n" + " correspond to the resulting location\e[0m\n" "\n" + " -c \n" + " Override default CSS directory (\"%s\"), relative to root\n" + " -i \n" + " Override default images directory (\"%s\"), relative to root\n" + " -j \n" + " Override default JS directory (\"%s\"), relative to root\n" + "\n" + " Project Settings:\n" + " -p \n" + " Set the project ID, equal to the \"project\" field in the HMML files\n" + " NOTE: Setting the project ID triggers PROJECT EDITION\n" + " -m \n" + " Override default default medium (\"%s\")\n" + " \e[1;30mKnown project defaults:\n", + BinaryLocation, + DefaultConfig->RootDir, + DefaultConfig->RootURL, + + DefaultConfig->CSSDir, + DefaultConfig->ImagesDir, + DefaultConfig->JSDir, + + DefaultConfig->DefaultMedium); + + for(int ProjectIndex = 0; ProjectIndex < ArrayCount(ProjectInfo); ++ProjectIndex) + { + fprintf(stderr, " %s:", + ProjectInfo[ProjectIndex].ProjectID); + + // NOTE(matt): This kind of thing really needs to loop over the dudes once to find the longest one + for(int i = 11; i > StringLength(ProjectInfo[ProjectIndex].ProjectID); i -= 4) + { + fprintf(stderr, "\t"); + } + + fprintf(stderr, "%s\n", + ProjectInfo[ProjectIndex].Medium); + } + + fprintf(stderr, + "\e[0m -s