Add optional parameter to HMML_Markers + fix stuff*

* make sure quoted attrs are unescaped properly
This commit is contained in:
Alex Baines 2017-03-18 17:29:10 +00:00
parent f4217d5057
commit c31b486cfa
2 changed files with 41 additions and 16 deletions

View File

@ -40,7 +40,8 @@ typedef enum {
typedef struct {
HMML_MarkerType type;
char* text;
char* marker;
char* parameter;
int offset;
} HMML_Marker;

View File

@ -27,17 +27,27 @@
return 1;\
} while(0)
#define CHECKESCAPE(x) do { if(!strchr("[]:@~\\\"", x)) HMML_ERR("Unknown backslash escape code '%c'", x); } 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;\
char* c = UNQUOTE(strndup(t, n));\
sb_last(yyextra->an.markers).marker = c;\
sb_last(yyextra->an.markers).offset = sb_count(yyextra->an.text);\
memcpy(sb_add(yyextra->an.text, n), c, n);\
if(yyextra->mnext == TEXT){\
memcpy(sb_add(yyextra->an.text, n), c, n);\
}\
} while(0)
#define MX_ADD(c) \
do { \
sb_push(sb_last(yyextra->an.markers).parameter, c);\
if(c) sb_push(yyextra->an.text, c);\
} while(0)
#define NEWANNO() \
do { \
if(!yyextra->first) sb_push(yyextra->annos, yyextra->an); \
@ -46,7 +56,19 @@
yyextra->first = false;\
} while(0)
#define CHECKESCAPE(x) do { if(!strchr("[]:@~\\", x)) HMML_ERR("Unknown backslash escape code '%c'", x); } while(0)
#define UNQUOTE(_attr) ({ \
typeof(_attr) attr = (_attr); \
size_t len = strlen(attr); \
for(char* c = attr; *c; ++c){\
if(*c == '\\'){ \
CHECKESCAPE(c[1]); \
memmove(c, c+1, len-(c-attr)); \
--len; \
} \
} \
attr; \
})
%}
%option reentrant
@ -99,7 +121,7 @@ RB \]
<V_ATTR>{S} { BEGIN(VIDEO); }
<V_ATTR>{ATTR_SIMPLE} { *yyextra->attr = strndup(yytext , yyleng ); BEGIN(VIDEO); }
<V_ATTR>{ATTR_QUOTED} { *yyextra->attr = strndup(yytext+1, yyleng-2); BEGIN(VIDEO); }
<V_ATTR>{ATTR_QUOTED} { *yyextra->attr = UNQUOTE(strndup(yytext+1, yyleng-2)); BEGIN(VIDEO); }
<V_ATTR>\] { yyless(0); BEGIN(VIDEO); }
<ANNOTATION>{TIMECODE}{LB}@ { NEWANNO(); yyextra->an.time = strndup(yytext+1, yyleng-4); BEGIN(AUTHOR); }
@ -125,16 +147,17 @@ RB \]
<TEXT>\] { BEGIN(AFTERTEXT); }
<TEXT>{LB}ref { yyextra->ref.offset = sb_count(yyextra->an.text); BEGIN(REF); }
<TEXT>{LB}
<TEXT>[ \r\t]{1,2} { sb_push(yyextra->an.text, ' '); }
<TEXT>{S} { sb_push(yyextra->an.text, ' '); }
<TEXT>. { sb_push(yyextra->an.text, *yytext); }
<MARKER>{ATTR_ALNUM} { M_ADD(yytext , yyleng ); BEGIN(yyextra->mnext); };
<MARKER>{ATTR_QUOTED} { M_ADD(yytext+1, yyleng-2); BEGIN(yyextra->mnext); };
<MARKER>. { HMML_ERR("Cannot parse Marker. Expected quoted or alphanumeric attribute."); }
/* TODO: store the extra text somewhere */
<MARKER_XTRA>\] { BEGIN(TEXT); }
<MARKER_XTRA>.
<MARKER_XTRA>\\] { MX_ADD(']'); }
<MARKER_XTRA>\] { MX_ADD('\0'); BEGIN(TEXT); }
<MARKER_XTRA>[ ] { if(sb_last(yyextra->an.markers).parameter){ MX_ADD(' '); } }
<MARKER_XTRA>. { MX_ADD(*yytext); }
<REF>{S}
<REF>site{S}= { yyextra->attr = R_(site); BEGIN(R_ATTR); }
@ -151,7 +174,7 @@ RB \]
<R_ATTR>{S}
<R_ATTR>{ATTR_SIMPLE} { *yyextra->attr = strndup(yytext , yyleng ); BEGIN(REF); }
<R_ATTR>{ATTR_QUOTED} { *yyextra->attr = strndup(yytext+1, yyleng-2); BEGIN(REF); }
<R_ATTR>{ATTR_QUOTED} { *yyextra->attr = UNQUOTE(strndup(yytext+1, yyleng-2)); BEGIN(REF); }
<AFTERTEXT,ANNOTATION>\[\/video\] { NEWANNO(); return 0; }
@ -166,8 +189,8 @@ RB \]
<AUTHOR>{S}
<CATEGORIES>{S}
<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>:{ATTR_SIMPLE} { HMML_Marker m = { HMML_CATEGORY, strndup(yytext+1, yyleng-1), NULL, -1 }; sb_push(yyextra->an.markers, m); }
<CATEGORIES>:{ATTR_QUOTED} { HMML_Marker m = { HMML_CATEGORY, UNQUOTE(strndup(yytext+2, yyleng-3)), NULL, -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); }
@ -243,7 +266,8 @@ static void _hmml_free_anno(HMML_Annotation* a){
sb_free(a->references);
for(size_t j = 0; j < sb_count(a->markers); ++j){
free(a->markers[j].text);
free(a->markers[j].marker);
sb_free(a->markers[j].parameter);
}
sb_free(a->markers);
@ -328,7 +352,7 @@ void hmml_dump(HMML_Output* hmml){
for(size_t j = 0; j < a->marker_count; ++j){
int type = a->markers[j].type;
char* text = a->markers[j].text;
char* text = a->markers[j].marker;
size_t len = strlen(text);
if(len > max_text_len){