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* 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 {
|
||||
|
|
102
hmmlib/hmmlib.l
102
hmmlib/hmmlib.l
|
@ -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);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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.:
|
||||
|
|
Loading…
Reference in New Issue