Commit 1614e889 authored by Alex Baines's avatar Alex Baines

add offsets to markers + references, cleanup

parent 06854a7b
example
hmml.a
hmmlib.o
hmmlib.c
......@@ -27,6 +27,7 @@ typedef struct {
char* editor;
char* publisher;
char* isbn;
int offset;
} HMML_Reference;
typedef enum {
......@@ -40,6 +41,7 @@ typedef enum {
typedef struct {
HMML_MarkerType type;
char* text;
int offset;
} HMML_Marker;
typedef struct {
......@@ -61,7 +63,6 @@ typedef struct {
HMML_Quote quote;
bool is_quote;
} HMML_Annotation;
typedef struct {
......
......@@ -13,7 +13,7 @@
HMML_Annotation an;
HMML_Reference ref;
HMML_Error* error;
HMML_Error error;
char** attr;
int mnext;
......@@ -22,15 +22,21 @@
#define HMML_ERR(fmt, ...) \
do { \
asprintf(&yyextra->error->message, fmt, ##__VA_ARGS__);\
yyextra->error->line = yyextra->line;\
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 M_ADD(t, n) \
do { \
char* c = strndup(t, n);\
sb_last(yyextra->an.markers).text = c;\
sb_last(yyextra->an.markers).offset = sb_count(yyextra->an.text);\
memcpy(sb_add(yyextra->an.text, n), c, n);\
} while(0)
#define NEWANNO() \
do { \
......@@ -116,7 +122,7 @@ RB \]
<TEXT>{LB}@ { M_(MEMBER , MARKER_XTRA); BEGIN(MARKER); }
<TEXT>{LB}~ { M_(PROJECT , MARKER_XTRA); BEGIN(MARKER); }
<TEXT>\] { BEGIN(AFTERTEXT); }
<TEXT>{LB}ref { memset(&yyextra->ref, 0, sizeof(yyextra->ref)); BEGIN(REF); }
<TEXT>{LB}ref { yyextra->ref.offset = sb_count(yyextra->an.text); BEGIN(REF); }
<TEXT>{LB}
<TEXT>{S}{S} { sb_push(yyextra->an.text, ' '); }
<TEXT>. { sb_push(yyextra->an.text, *yytext); }
......@@ -139,7 +145,7 @@ RB \]
<REF>editor{S}= { yyextra->attr = R_(editor); BEGIN(R_ATTR); }
<REF>publisher{S}= { yyextra->attr = R_(publisher); BEGIN(R_ATTR); }
<REF>isbn{S}= { yyextra->attr = R_(isbn); BEGIN(R_ATTR); }
<REF>\] { sb_push(yyextra->an.references, yyextra->ref); BEGIN(TEXT); }
<REF>\] { sb_push(yyextra->an.references, yyextra->ref); memset(&yyextra->ref, 0, sizeof(yyextra->ref)); BEGIN(TEXT); }
<REF>. { HMML_ERR("Unexpected item in ref: %s", yytext); }
<R_ATTR>{S}
......@@ -159,8 +165,8 @@ RB \]
<AUTHOR>{S}
<CATEGORIES>{S}
<CATEGORIES>:{ATTR_SIMPLE} { HMML_Marker m = { HMML_CATEGORY, strndup(yytext+1, yyleng-1) }; sb_push(yyextra->an.markers, m); }
<CATEGORIES>:{ATTR_QUOTED} { HMML_Marker m = { HMML_CATEGORY, strndup(yytext+2, yyleng-3) }; sb_push(yyextra->an.markers, m); }
<CATEGORIES>:{ATTR_SIMPLE} { HMML_Marker m = { HMML_CATEGORY, strndup(yytext+1, yyleng-1), -1 }; sb_push(yyextra->an.markers, m); }
<CATEGORIES>:{ATTR_QUOTED} { HMML_Marker m = { HMML_CATEGORY, strndup(yytext+2, yyleng-3), -1 }; sb_push(yyextra->an.markers, m); }
<CATEGORIES>\]{LB} { BEGIN(QUOTES); }
<CATEGORIES>\] { BEGIN(ANNOTATION); }
<CATEGORIES>. { HMML_ERR("Unexpected character in category tag: '%c'\n", *yytext); }
......@@ -172,11 +178,15 @@ RB \]
%%
#define HMML_REF_ITEMS 9
static void _hmml_free_ref(HMML_Reference*);
static void _hmml_free_anno(HMML_Annotation*);
HMML_Output hmml_parse_file(FILE* f){
HMML_Output output = {};
HMML_ParseState state = {};
state.error = &output.error;
state.first = true;
state.line = 1;
......@@ -186,29 +196,59 @@ HMML_Output hmml_parse_file(FILE* f){
output.well_formed = yylex(scan) == 0;
if(output.well_formed){
memcpy(&output.metadata, &state.meta, sizeof(HMML_VideoMetaData));
memcpy(&output.metadata, &state.meta, sizeof(HMML_VideoMetaData));
output.annotations = state.annos;
output.annotation_count = sb_count(state.annos);
output.annotations = state.annos;
output.annotation_count = sb_count(state.annos);
for(size_t i = 0; i < output.annotation_count; ++i){
HMML_Annotation* a = output.annotations + i;
sb_push(a->text, 0);
a->marker_count = sb_count(a->markers);
a->reference_count = sb_count(a->references);
for(size_t i = 0; i < output.annotation_count; ++i){
HMML_Annotation* a = output.annotations + i;
sb_push(a->text, 0);
a->marker_count = sb_count(a->markers);
a->reference_count = sb_count(a->references);
if(a->is_quote && a->quote.author){
sb_push(a->quote.author, 0);
}
if(a->is_quote && a->quote.author){
sb_push(a->quote.author, 0);
}
}
if(!output.well_formed){
hmml_free(&output);
memcpy(&output.error, &state.error, sizeof(HMML_Error));
}
_hmml_free_anno(&state.an);
_hmml_free_ref(&state.ref);
yylex_destroy(scan);
return output;
}
static void _hmml_free_ref(HMML_Reference* r){
for(size_t k = 0; k < HMML_REF_ITEMS; ++k){
free(((char**)r)[k]);
}
}
static void _hmml_free_anno(HMML_Annotation* a){
free(a->time);
free(a->author);
sb_free(a->text);
for(size_t j = 0; j < a->reference_count; ++j){
_hmml_free_ref(a->references + j);
}
sb_free(a->references);
for(size_t j = 0; j < a->marker_count; ++j){
free(a->markers[j].text);
}
sb_free(a->markers);
sb_free(a->quote.author);
}
void hmml_free(HMML_Output* hmml){
if(!hmml) return;
......@@ -217,23 +257,7 @@ void hmml_free(HMML_Output* hmml){
}
for(size_t i = 0; i < hmml->annotation_count; ++i){
HMML_Annotation* a = hmml->annotations + i;
free(a->time);
free(a->author);
sb_free(a->text);
for(size_t j = 0; j < a->reference_count; ++j){
for(size_t k = 0; k < sizeof(HMML_Reference)/sizeof(char*); ++k){
free(((char**)a->references + j)[k]);
}
}
sb_free(a->references);
for(size_t j = 0; j < a->marker_count; ++j){
free(a->markers[j].text);
}
sb_free(a->markers);
sb_free(a->quote.author);
_hmml_free_anno(hmml->annotations + i);
}
sb_free(hmml->annotations);
......@@ -353,7 +377,7 @@ void hmml_dump(HMML_Output* hmml){
for(size_t j = 0; j < a->reference_count; ++j){
printf("\t%3d ", a->line);
HMML_Reference* r = a->references + j;
for(size_t k = 0; k < 9; ++k){
for(size_t k = 0; k < HMML_REF_ITEMS; ++k){
char* item = ((char**)r)[k];
if(item){
printf("[%s = %s] ", r_tags[k], item);
......
This is a C hmml parser library thing made with flex.
It has just 3 functions, look at hmml.h for the API.
It has just 3 functions, look at hmmlib.h for the API.
To build it, run make, and it'll spit out hmml.a that you just need to include
on the command line when you build stuff. e.g.:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment