add offsets to markers + references, cleanup
This commit is contained in:
parent
06854a7b66
commit
1614e88920
|
@ -0,0 +1,4 @@
|
||||||
|
example
|
||||||
|
hmml.a
|
||||||
|
hmmlib.o
|
||||||
|
hmmlib.c
|
|
@ -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 {
|
||||||
|
|
102
hmmlib/hmmlib.l
102
hmmlib/hmmlib.l
|
@ -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,29 +196,59 @@ 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;
|
||||||
output.annotation_count = sb_count(state.annos);
|
output.annotation_count = sb_count(state.annos);
|
||||||
|
|
||||||
for(size_t i = 0; i < output.annotation_count; ++i){
|
for(size_t i = 0; i < output.annotation_count; ++i){
|
||||||
HMML_Annotation* a = output.annotations + i;
|
HMML_Annotation* a = output.annotations + i;
|
||||||
sb_push(a->text, 0);
|
sb_push(a->text, 0);
|
||||||
a->marker_count = sb_count(a->markers);
|
a->marker_count = sb_count(a->markers);
|
||||||
a->reference_count = sb_count(a->references);
|
a->reference_count = sb_count(a->references);
|
||||||
|
|
||||||
if(a->is_quote && a->quote.author){
|
if(a->is_quote && a->quote.author){
|
||||||
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);
|
||||||
|
|
|
@ -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.:
|
||||||
|
|
Loading…
Reference in New Issue