diff --git a/hmmlconv/hmmlconv.c b/hmmlconv/hmmlconv.c index c933bff..47fb0a8 100644 --- a/hmmlconv/hmmlconv.c +++ b/hmmlconv/hmmlconv.c @@ -11,7 +11,6 @@ exit #include // open #include // open, mkdir #include // open, mkdir -#include typedef struct { @@ -143,21 +142,70 @@ Resource *LookupResource(char *Tag, char *Line) return Res; } -void ProcessAnnotation(char *Line, FILE *OutFile) +int +ValidateTimecode(char *Timecode) +{ + int HMS[3] = { 0, 0, 0 }; // 0 == Seconds; 1 == Minutes; 2 == Hours + int Colons = 0; + while(*Timecode) + { + if(!(*Timecode >= '0' && *Timecode <= '9') && *Timecode != ':') { return 1; } + + if(*Timecode == ':') + { + ++Colons; + if(Colons > 2) { return 2; } + for(int i = 0; i < Colons; ++i) + { + HMS[Colons - i] = HMS[Colons - (i + 1)]; + } + HMS[0] = 0; + } + else + { + HMS[0] = HMS[0] * 10 + *Timecode - '0'; + } + + ++Timecode; + } + + if(HMS[0] > 59 || HMS[1] > 59 || Timecode[-1] == ':') { return 3; } + + return 0; +} + +void ProcessAnnotation(char *Line, int LineNumber, FILE *OutFile) { SkipWhitespace(&Line); - assert(*Line == '"'); + if(*Line != '"') { fprintf(stderr, " l.%d: Syntax error, line must begin with a \": %.*s...\n", LineNumber, 8, Line); exit(1); } fputc('[', OutFile); - while(*++Line != '"') + char Timecode[9]; + char *Ptr = Timecode; + while(*++Line != '"' && *Line != '\n') { - fputc(*Line, OutFile); + *Ptr++ = *Line; } + *Ptr = '\0'; + + switch(ValidateTimecode(Timecode)) + { + case 0: break; + case 1: fprintf(stderr, " l.%d: Invalid timecode, not a number: %s\n", LineNumber, Timecode); exit(1); + case 2: fprintf(stderr, " l.%d: Invalid timecode, too many colons: %s\n", LineNumber, Timecode); exit(1); + case 3: fprintf(stderr, " l.%d: Invalid timecode, not 0-59: %s\n", LineNumber, Timecode); exit(1); + } + + fputs(Timecode, OutFile); fputc(']', OutFile); - assert(*++Line == ':'); - assert(*++Line == ' '); - assert(*++Line == '"'); + if(*++Line != ':') { fprintf(stderr, " l.%d: Syntax error, missing : before: %.*s...\n", LineNumber, 8, Line); exit(1); } + if(*++Line != ' ') { fprintf(stderr, " l.%d: Syntax error, missing space before: %.*s...\n", LineNumber, 8, Line); exit(1); } + if(*++Line != '"') { fprintf(stderr, " l.%d: Syntax error, missing \" before: %.*s...\n", LineNumber, 8, Line); exit(1); } + + char *LinePtr = Line; + while(*LinePtr) { ++LinePtr; } + if(LinePtr[-1] != '"') { fprintf(stderr, " l.%d: Syntax error, missing closing \": %.*s\n", LineNumber, LinePtr-Line, Line); exit(1); } Line = InPlaceUnescape(Line); @@ -165,7 +213,7 @@ void ProcessAnnotation(char *Line, FILE *OutFile) if(Line[0] == '@') { char *P = strchr(Line, ' '); - assert(P); + if(!P) { fprintf(stderr, " l.%d: Invalid annotation, cannot contain only a member: %.*s...\n", LineNumber, 8, Line); exit(1); } if(P[-1] == ':') { @@ -177,7 +225,6 @@ void ProcessAnnotation(char *Line, FILE *OutFile) } char RefBuf[256]; - char *LinePtr; char *RunStart = Line; char *FirstSpace = NULL; int ConsiderQuote = 0; @@ -192,6 +239,8 @@ void ProcessAnnotation(char *Line, FILE *OutFile) int TmpQuoteID; // convert Resource -> ref + // TODO(matt): Gather the whole Resources section, and prompt if we match more than one resource + // TODO(matt): (Maybe) Lookup individual words from the [see Resources] thing if(LinePtr[0] == ' ' && LinePtr[1] == '[' && sscanf(LinePtr+1, "[see Resources, %255[^]]]%n", RefBuf, &ScanBytes) == 1 && ScanBytes) { //printf("Find Resource [%s]\n", RefBuf); @@ -211,7 +260,7 @@ void ProcessAnnotation(char *Line, FILE *OutFile) } else { - fprintf(stderr, "WARNING: can't find resource [%s] :(\n", RefBuf); + fprintf(stderr, " l.%d: WARNING: can't find resource: %s :(\n", LineNumber, RefBuf); } } @@ -274,7 +323,10 @@ int ProcessFile(char *InFileName, FILE *InFile, FILE *OutFile) char *Contents = ReadWholeFile(InFile); char *Ptr; - printf("Processing [%s]...\n", InFileName); + if(!(getenv("HERO"))) + { + printf("Processing [%s]...\n", InFileName); + } // Resources ResCount = 0; @@ -348,7 +400,10 @@ int ProcessFile(char *InFileName, FILE *InFile, FILE *OutFile) LinePtr = Separator + 1; } - printf("Add Res: %s\n", Resources[ResCount].Site); + if(!(getenv("HERO"))) + { + printf("Add Res: %s\n", Resources[ResCount].Site); + } ++ResCount; } @@ -362,7 +417,7 @@ int ProcessFile(char *InFileName, FILE *InFile, FILE *OutFile) STATE_MARKERS, } State = STATE_METADATA; - int LineNumber = 0; + int LineNumber = 1; char *LineState; char *LinePtr = strtok_r(Contents, "\r\n", &LineState); @@ -390,7 +445,7 @@ int ProcessFile(char *InFileName, FILE *InFile, FILE *OutFile) if(strncmp(LinePtr, "---", 3) == 0){ goto Done; } else { - ProcessAnnotation(LinePtr, OutFile); + ProcessAnnotation(LinePtr, LineNumber, OutFile); } } break; } @@ -438,6 +493,10 @@ int main(int ArgC, char **Args) int Errors = 0; int AlwaysOverwrite = 0; + if(getenv("HERO")) + { + AlwaysOverwrite = 1; + } for(int i = 1; i < ArgC-1; ++i) {