hmml_to_html.c: Always On
This commit is contained in:
parent
d82e665310
commit
b133f15a11
|
@ -25,7 +25,8 @@ typedef unsigned int bool;
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <string.h> // NOTE(matt): strerror
|
#include <string.h> // NOTE(matt): strerror
|
||||||
#include <errno.h> //NOTE(matt): errno
|
#include <errno.h> //NOTE(matt): errno
|
||||||
|
#include <sys/inotify.h> // NOTE(matt): inotify
|
||||||
|
#include <unistd.h> // NOTE(matt): sleep()
|
||||||
|
|
||||||
#define Kilobytes(Bytes) Bytes << 10
|
#define Kilobytes(Bytes) Bytes << 10
|
||||||
#define Megabytes(Bytes) Bytes << 20
|
#define Megabytes(Bytes) Bytes << 20
|
||||||
|
@ -450,6 +451,7 @@ MakeDir(char *Path)
|
||||||
void
|
void
|
||||||
LogUsage(buffer Buffer, char *CacheDir)
|
LogUsage(buffer Buffer, char *CacheDir)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
char LogPath[255];
|
char LogPath[255];
|
||||||
CopyString(LogPath, "%s/%s", CacheDir, "buffers.log");
|
CopyString(LogPath, "%s/%s", CacheDir, "buffers.log");
|
||||||
FILE *LogFile;
|
FILE *LogFile;
|
||||||
|
@ -468,6 +470,7 @@ LogUsage(buffer Buffer, char *CacheDir)
|
||||||
Buffer.Ptr - Buffer.Location,
|
Buffer.Ptr - Buffer.Location,
|
||||||
Buffer.Size);
|
Buffer.Size);
|
||||||
fclose(LogFile);
|
fclose(LogFile);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__ ((format (printf, 3, 4)))
|
__attribute__ ((format (printf, 3, 4)))
|
||||||
|
@ -3144,6 +3147,7 @@ RefreshIndex(arena *MemoryArena, buffers *CollationBuffers, config Config, char
|
||||||
{
|
{
|
||||||
LogError(Config, LOG_ERROR, "RefreshIndex(): %s", strerror(errno));
|
LogError(Config, LOG_ERROR, "RefreshIndex(): %s", strerror(errno));
|
||||||
free(Index.Location);
|
free(Index.Location);
|
||||||
|
fclose(IndexFile);
|
||||||
return RC_ERROR_MEMORY;
|
return RC_ERROR_MEMORY;
|
||||||
}
|
}
|
||||||
Scratch.Ptr = Scratch.Location;
|
Scratch.Ptr = Scratch.Location;
|
||||||
|
@ -3154,14 +3158,17 @@ RefreshIndex(arena *MemoryArena, buffers *CollationBuffers, config Config, char
|
||||||
*Scratch.Ptr = '\0';
|
*Scratch.Ptr = '\0';
|
||||||
|
|
||||||
Index.Ptr = Index.Location + Head;
|
Index.Ptr = Index.Location + Head;
|
||||||
CopyStringToBuffer(&Index, "%s,%s\n", BaseFilename, CollationBuffers->Title);
|
CopyStringToBuffer(&Index, "%s,%s\n"
|
||||||
|
"%s",
|
||||||
|
BaseFilename, CollationBuffers->Title,
|
||||||
|
Scratch.Location);
|
||||||
|
|
||||||
CopyStringToBuffer(&Index, Scratch.Location);
|
|
||||||
free(Scratch.Location);
|
free(Scratch.Location);
|
||||||
|
Index.Size = Index.Ptr - Index.Location;
|
||||||
|
|
||||||
fclose(IndexFile);
|
fclose(IndexFile);
|
||||||
IndexFile = fopen(IndexPath, "w");
|
IndexFile = fopen(IndexPath, "w");
|
||||||
fwrite(Index.Location, Index.Ptr - Index.Location, 1, IndexFile);
|
fwrite(Index.Location, Index.Size, 1, IndexFile);
|
||||||
|
|
||||||
Inserted = TRUE;
|
Inserted = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -3176,19 +3183,22 @@ RefreshIndex(arena *MemoryArena, buffers *CollationBuffers, config Config, char
|
||||||
++EntryCount;
|
++EntryCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Found == FALSE)
|
if(!Found)
|
||||||
{
|
{
|
||||||
++EntryCount;
|
++EntryCount;
|
||||||
// TODO(matt): Write the EntryCount into the index
|
// TODO(matt): Write the EntryCount into the index
|
||||||
if(Inserted == FALSE)
|
if(!Inserted)
|
||||||
{
|
{
|
||||||
|
CopyStringToBuffer(&Index, "%s,%s\n", BaseFilename, CollationBuffers->Title);
|
||||||
fprintf(IndexFile, "%s,%s\n", BaseFilename, CollationBuffers->Title);
|
fprintf(IndexFile, "%s,%s\n", BaseFilename, CollationBuffers->Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
RewindBuffer(&CollationBuffers->Index);
|
RewindBuffer(&CollationBuffers->Index);
|
||||||
|
Index.Size = Index.Ptr - Index.Location;
|
||||||
|
RewindBuffer(&Index);
|
||||||
|
|
||||||
CopyStringToBuffer(&CollationBuffers->Index, "<dl>\n");
|
CopyStringToBuffer(&CollationBuffers->Index, "<dl>\n");
|
||||||
Index.Ptr = Index.Location;
|
while(Index.Ptr - Index.Location < Index.Size)
|
||||||
while(Index.Ptr - Index.Location < IndexFileSize)
|
|
||||||
{
|
{
|
||||||
char IndexedFile[32];
|
char IndexedFile[32];
|
||||||
char *Ptr = IndexedFile;
|
char *Ptr = IndexedFile;
|
||||||
|
@ -3198,6 +3208,13 @@ RefreshIndex(arena *MemoryArena, buffers *CollationBuffers, config Config, char
|
||||||
Ptr = Title;
|
Ptr = Title;
|
||||||
Index.Ptr += CopyStringNoFormatT(Ptr, Index.Ptr, '\n') + 1;
|
Index.Ptr += CopyStringNoFormatT(Ptr, Index.Ptr, '\n') + 1;
|
||||||
|
|
||||||
|
// TODO(matt): Fully figure out why the Table of Contents doesn't always get all the stuff from the index
|
||||||
|
// Steps to reproduce:
|
||||||
|
// 1. mv riscy04{4..6}.hmml out of the way
|
||||||
|
// 2. Call the program
|
||||||
|
// 3. mv riscy046.hmml into the project directory
|
||||||
|
// 4. See that riscy046 is in the index file, has its own player page, but is not mentioned in the Table of Contents
|
||||||
|
|
||||||
CopyStringToBuffer(&CollationBuffers->Index,
|
CopyStringToBuffer(&CollationBuffers->Index,
|
||||||
" <dt>\n"
|
" <dt>\n"
|
||||||
" <a href=\"%s\">%s</a>\n"
|
" <a href=\"%s\">%s</a>\n"
|
||||||
|
@ -3330,6 +3347,38 @@ NextFile:
|
||||||
return RC_SUCCESS;
|
return RC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
MonitorDirectory(arena *MemoryArena, buffers *CollationBuffers, template *IndexTemplateMetadata, template *PlayerTemplateMetadata, config Config, int inotifyInstance, int WatchDescriptor)
|
||||||
|
{
|
||||||
|
buffer Events;
|
||||||
|
if(ClaimBuffer(MemoryArena, &Events, "inotify Events", Kilobytes(4)) == RC_ARENA_FULL) { return RC_ARENA_FULL; };
|
||||||
|
|
||||||
|
struct inotify_event *Event;
|
||||||
|
int BytesRead;
|
||||||
|
|
||||||
|
while((BytesRead = read(inotifyInstance, Events.Location, Events.Size)) != -1 && errno == EAGAIN && BytesRead > 0)
|
||||||
|
{
|
||||||
|
for(Events.Ptr = Events.Location;
|
||||||
|
Events.Ptr < Events.Location + BytesRead;
|
||||||
|
Events.Ptr += sizeof(struct inotify_event) + Event->len)
|
||||||
|
{
|
||||||
|
Event = (struct inotify_event *)Events.Ptr;
|
||||||
|
switch(RefreshProject(MemoryArena, CollationBuffers, IndexTemplateMetadata, PlayerTemplateMetadata, Config))
|
||||||
|
{
|
||||||
|
case RC_ERROR_DIRECTORY:
|
||||||
|
case RC_ERROR_FATAL:
|
||||||
|
DeclaimBuffer(MemoryArena, &Events);
|
||||||
|
return RC_ERROR_FATAL;
|
||||||
|
case RC_SUCCESS:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DeclaimBuffer(MemoryArena, &Events);
|
||||||
|
return RC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int ArgC, char **Args)
|
main(int ArgC, char **Args)
|
||||||
{
|
{
|
||||||
|
@ -3550,11 +3599,19 @@ main(int ArgC, char **Args)
|
||||||
{
|
{
|
||||||
case RC_ERROR_DIRECTORY:
|
case RC_ERROR_DIRECTORY:
|
||||||
case RC_ERROR_FATAL:
|
case RC_ERROR_FATAL:
|
||||||
// HERE
|
|
||||||
goto RIP;
|
goto RIP;
|
||||||
case RC_SUCCESS:
|
case RC_SUCCESS:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int inotifyInstance = inotify_init1(IN_NONBLOCK);
|
||||||
|
int WatchDescriptor = inotify_add_watch(inotifyInstance, Config.ProjectDir, IN_CLOSE_WRITE | IN_MOVED_TO);
|
||||||
|
|
||||||
|
while(MonitorDirectory(&MemoryArena, &CollationBuffers, IndexTemplateMetadata, PlayerTemplateMetadata, Config, inotifyInstance, WatchDescriptor) == RC_SUCCESS)
|
||||||
|
{
|
||||||
|
// TODO(matt): Make this update frequency configurable
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3578,7 +3635,8 @@ NextFile:
|
||||||
case RC_ERROR_MAX_REFS:
|
case RC_ERROR_MAX_REFS:
|
||||||
case RC_ERROR_QUOTE:
|
case RC_ERROR_QUOTE:
|
||||||
case RC_INVALID_REFERENCE:
|
case RC_INVALID_REFERENCE:
|
||||||
goto NextFile;
|
if(FileIndex < (ArgC - 1)) { goto NextFile; }
|
||||||
|
else { goto RIP; }
|
||||||
case RC_SUCCESS:
|
case RC_SUCCESS:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue