add offsets to markers + references, cleanup

This commit is contained in:
Alex Baines 2017-02-27 22:53:05 +00:00
parent 06854a7b66
commit 1614e88920
4 changed files with 70 additions and 41 deletions

4
hmmlib/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
example
hmml.a
hmmlib.o
hmmlib.c

View File

@ -27,6 +27,7 @@ typedef struct {
char* editor; char* editor;
char* publisher; char* publisher;
char* isbn; char* isbn;
int offset;
} HMML_Reference; } HMML_Reference;
typedef enum { typedef enum {
@ -40,6 +41,7 @@ typedef enum {
typedef struct { typedef struct {
HMML_MarkerType type; HMML_MarkerType type;
char* text; char* text;
int offset;
} HMML_Marker; } HMML_Marker;
typedef struct { typedef struct {
@ -61,7 +63,6 @@ typedef struct {
HMML_Quote quote; HMML_Quote quote;
bool is_quote; bool is_quote;
} HMML_Annotation; } HMML_Annotation;
typedef struct { typedef struct {

View File

@ -13,7 +13,7 @@
HMML_Annotation an; HMML_Annotation an;
HMML_Reference ref; HMML_Reference ref;
HMML_Error* error; HMML_Error error;
char** attr; char** attr;
int mnext; int mnext;
@ -22,15 +22,21 @@
#define HMML_ERR(fmt, ...) \ #define HMML_ERR(fmt, ...) \
do { \ do { \
asprintf(&yyextra->error->message, fmt, ##__VA_ARGS__);\ asprintf(&yyextra->error.message, fmt, ##__VA_ARGS__);\
yyextra->error->line = yyextra->line;\ yyextra->error.line = yyextra->line;\
return 1;\ return 1;\
} while(0) } while(0)
#define V_(x) &yyextra->meta.x #define V_(x) &yyextra->meta.x
#define R_(x) &yyextra->ref.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_(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() \ #define NEWANNO() \
do { \ do { \
@ -116,7 +122,7 @@ RB \]
<TEXT>{LB}@ { M_(MEMBER , MARKER_XTRA); BEGIN(MARKER); } <TEXT>{LB}@ { M_(MEMBER , MARKER_XTRA); BEGIN(MARKER); }
<TEXT>{LB}~ { M_(PROJECT , MARKER_XTRA); BEGIN(MARKER); } <TEXT>{LB}~ { M_(PROJECT , MARKER_XTRA); BEGIN(MARKER); }
<TEXT>\] { BEGIN(AFTERTEXT); } <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>{LB}
<TEXT>{S}{S} { sb_push(yyextra->an.text, ' '); } <TEXT>{S}{S} { sb_push(yyextra->an.text, ' '); }
<TEXT>. { sb_push(yyextra->an.text, *yytext); } <TEXT>. { sb_push(yyextra->an.text, *yytext); }
@ -139,7 +145,7 @@ RB \]
<REF>editor{S}= { yyextra->attr = R_(editor); BEGIN(R_ATTR); } <REF>editor{S}= { yyextra->attr = R_(editor); BEGIN(R_ATTR); }
<REF>publisher{S}= { yyextra->attr = R_(publisher); BEGIN(R_ATTR); } <REF>publisher{S}= { yyextra->attr = R_(publisher); BEGIN(R_ATTR); }
<REF>isbn{S}= { yyextra->attr = R_(isbn); 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); } <REF>. { HMML_ERR("Unexpected item in ref: %s", yytext); }
<R_ATTR>{S} <R_ATTR>{S}
@ -159,8 +165,8 @@ RB \]
<AUTHOR>{S} <AUTHOR>{S}
<CATEGORIES>{S} <CATEGORIES>{S}
<CATEGORIES>:{ATTR_SIMPLE} { HMML_Marker m = { HMML_CATEGORY, strndup(yytext+1, yyleng-1) }; 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) }; 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>\]{LB} { BEGIN(QUOTES); }
<CATEGORIES>\] { BEGIN(ANNOTATION); } <CATEGORIES>\] { BEGIN(ANNOTATION); }
<CATEGORIES>. { HMML_ERR("Unexpected character in category tag: '%c'\n", *yytext); } <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 hmml_parse_file(FILE* f){
HMML_Output output = {}; HMML_Output output = {};
HMML_ParseState state = {}; HMML_ParseState state = {};
state.error = &output.error;
state.first = true; state.first = true;
state.line = 1; state.line = 1;
@ -186,7 +196,6 @@ HMML_Output hmml_parse_file(FILE* f){
output.well_formed = yylex(scan) == 0; 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.annotations = state.annos;
@ -202,13 +211,44 @@ HMML_Output hmml_parse_file(FILE* f){
sb_push(a->quote.author, 0); 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); yylex_destroy(scan);
return output; 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){ void hmml_free(HMML_Output* hmml){
if(!hmml) return; if(!hmml) return;
@ -217,23 +257,7 @@ void hmml_free(HMML_Output* hmml){
} }
for(size_t i = 0; i < hmml->annotation_count; ++i){ for(size_t i = 0; i < hmml->annotation_count; ++i){
HMML_Annotation* a = hmml->annotations + i; _hmml_free_anno(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);
} }
sb_free(hmml->annotations); sb_free(hmml->annotations);
@ -353,7 +377,7 @@ void hmml_dump(HMML_Output* hmml){
for(size_t j = 0; j < a->reference_count; ++j){ for(size_t j = 0; j < a->reference_count; ++j){
printf("\t%3d ", a->line); printf("\t%3d ", a->line);
HMML_Reference* r = a->references + j; 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]; char* item = ((char**)r)[k];
if(item){ if(item){
printf("[%s = %s] ", r_tags[k], item); printf("[%s = %s] ", r_tags[k], item);

View File

@ -1,5 +1,5 @@
This is a C hmml parser library thing made with flex. 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 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.: on the command line when you build stuff. e.g.: