From 06854a7b66fcf045c24e210c615713ce0a0ade76 Mon Sep 17 00:00:00 2001 From: Alex Baines Date: Mon, 27 Feb 2017 21:42:14 +0000 Subject: [PATCH] hmml parser C library --- hmmlib/example.c | 28 ++++ hmmlib/hmmlib.h | 86 ++++++++++ hmmlib/hmmlib.l | 390 ++++++++++++++++++++++++++++++++++++++++++++++ hmmlib/makefile | 10 ++ hmmlib/readme.txt | 11 ++ hmmlib/stb_sb.h | 128 +++++++++++++++ 6 files changed, 653 insertions(+) create mode 100644 hmmlib/example.c create mode 100644 hmmlib/hmmlib.h create mode 100644 hmmlib/hmmlib.l create mode 100644 hmmlib/makefile create mode 100644 hmmlib/readme.txt create mode 100644 hmmlib/stb_sb.h diff --git a/hmmlib/example.c b/hmmlib/example.c new file mode 100644 index 0000000..dea851f --- /dev/null +++ b/hmmlib/example.c @@ -0,0 +1,28 @@ +#if 0 + cc $0 -o ${0/.c/} hmml.a + exit +#endif + +#include "hmmlib.h" +#include + +int main(int argc, char** argv){ + if(argc < 2){ + fputs("gimme a file.\n", stderr); + return 1; + } + + FILE* f = fopen(argv[1], "r"); + + if(f){ + printf("Reading file: %s\n", argv[1]); + HMML_Output hmml = hmml_parse_file(f); + hmml_dump(&hmml); + hmml_free(&hmml); + fclose(f); + } else { + perror("Error reading file"); + } + + return 0; +} diff --git a/hmmlib/hmmlib.h b/hmmlib/hmmlib.h new file mode 100644 index 0000000..c55ae60 --- /dev/null +++ b/hmmlib/hmmlib.h @@ -0,0 +1,86 @@ +#ifndef HMML_H_ +#define HMML_H_ +#include +#include +#include +#include + +// Data structures + +typedef struct { + char* member; + char* twitch; + char* project; + char* title; + char* platform; + char* id; + char* annotator; +} HMML_VideoMetaData; + +typedef struct { + char* site; + char* page; + char* url; + char* title; + char* article; + char* author; + char* editor; + char* publisher; + char* isbn; +} HMML_Reference; + +typedef enum { + HMML_CATEGORY, + HMML_MEMBER, + HMML_PROJECT, + + HMML_MARKER_COUNT, +} HMML_MarkerType; + +typedef struct { + HMML_MarkerType type; + char* text; +} HMML_Marker; + +typedef struct { + int id; + char* author; +} HMML_Quote; + +typedef struct { + int line; + char* time; + char* text; + char* author; + + HMML_Reference* references; + size_t reference_count; + + HMML_Marker* markers; + size_t marker_count; + + HMML_Quote quote; + bool is_quote; + +} HMML_Annotation; + +typedef struct { + int line; + char* message; +} HMML_Error; + +typedef struct { + bool well_formed; + HMML_VideoMetaData metadata; + HMML_Annotation* annotations; + size_t annotation_count; + HMML_Error error; +} HMML_Output; + +// Functions + +HMML_Output hmml_parse_file (FILE* file); +void hmml_dump (HMML_Output* output); +void hmml_free (HMML_Output* output); + +#endif diff --git a/hmmlib/hmmlib.l b/hmmlib/hmmlib.l new file mode 100644 index 0000000..19f5cec --- /dev/null +++ b/hmmlib/hmmlib.l @@ -0,0 +1,390 @@ +%{ +#include +#include +#include +#include "stb_sb.h" +#include "hmmlib.h" + + typedef struct { + int line; + HMML_Annotation* annos; + + HMML_VideoMetaData meta; + HMML_Annotation an; + HMML_Reference ref; + + HMML_Error* error; + + char** attr; + int mnext; + bool first; + } HMML_ParseState; + +#define HMML_ERR(fmt, ...) \ + do { \ + asprintf(&yyextra->error->message, fmt, ##__VA_ARGS__);\ + yyextra->error->line = yyextra->line;\ + return 1;\ + } while(0) + +#define V_(x) &yyextra->meta.x +#define R_(x) &yyextra->ref.x +#define M_(x, state) do { HMML_Marker m = { HMML_ ## x }; sb_push(yyextra->an.markers, m); yyextra->mnext = state; } while(0) +#define M_ADD(t, n) do { char* c = strndup(t, n); sb_last(yyextra->an.markers).text = c; memcpy(sb_add(yyextra->an.text, n), c, n); } while(0) + +#define NEWANNO() \ + do { \ + if(!yyextra->first) sb_push(yyextra->annos, yyextra->an); \ + memset(&yyextra->an, 0, sizeof(yyextra->an));\ + yyextra->an.line = yyextra->line;\ + yyextra->first = false;\ + } while(0) + +#define CHECKESCAPE(x) do { if(!strchr("[]:@~\\", x)) HMML_ERR("Unknown backslash escape code '%c'", x); } while(0) +%} + +%option reentrant +%option extra-type="HMML_ParseState*" +%option noyywrap + +S [\t ]* +ATTR_SIMPLE [^\" \]\t\r\n][^ \]\t\r\n]* +ATTR_ALNUM [0-9a-zA-Z][0-9a-zA-Z_]* +ATTR_QUOTED \"([^\n\"\\]|\\.)*\" +TAG_VIDEO_OPEN \[video +TIMECODE \[[0-9]{1,2}(:[0-5][0-9]){1,2}\] +BAD_TIMECODE \[[0-9]{1,2}(:[6-9][0-9]){1,2}\] +LB \[ +RB \] + +%s VIDEO +%s V_ATTR +%s ANNOTATION +%s TEXT_START +%s TEXT +%s MARKER +%s MARKER_XTRA +%s REF +%s R_ATTR +%s AFTERTEXT +%s AUTHOR +%s CATEGORIES +%s QUOTES + +%% + +<> { HMML_ERR("Unexpected EOF, video close tag not found."); } +\n { yyextra->line++; } + +{TAG_VIDEO_OPEN} { BEGIN(VIDEO); } +. { HMML_ERR("Missing video tag."); } + +