From: Thibaut VARÈNE Date: 2021年8月14日 14:19:32 +0000 (+0200) Subject: parser: implement label unpacking X-Git-Tag: v1.0~25 X-Git-Url: http://vcs.slashdirt.org/git/?a=commitdiff_plain;h=3664db52b4fad04bec05c0ede50e1bedcdef6f7e;p=sw%2Ftic2json.git parser: implement label unpacking This exposes the full description as well as label unit as per specification, at the cost of slightly increased stack usage --- diff --git a/tic.h b/tic.h index 32dfd91..44bf626 100644 --- a/tic.h +++ b/tic.h @@ -30,8 +30,8 @@ enum f_type { F_STRING, F_INT, F_HEX }; struct tic_field { enum f_type type; - const char *label; char *horodate; + struct tic_etiquette etiq; union { char *s; int i; diff --git a/tic.y b/tic.y index aacdfae..8759957 100644 --- a/tic.y +++ b/tic.y @@ -8,7 +8,8 @@ /* * Outputs as JSON a series of frames formatted as a list of fields. - * Fields are { "label": "xxx", "data": "xxx", horodate: "xxx" } with horodate optional and data possibly empty. + * Fields are { "label": "xxx", "desc": "xxx", "unit": "xxx", "data": "xxx", horodate: "xxx" } + * with horodate optional, unit and data possibly empty and data being either quoted string or number. * Data errors can result in some/all fields being omitted in the output frame: the JSON list is then empty. * Output JSON is guaranteed to always be valid for each frame. * This parser complies with Enedis-NOI-CPT_54E.pdf version 3. @@ -31,14 +32,26 @@ static int hooked; static char fdelim; static int mask_allzeros; -void make_field(struct tic_field *field, enum f_type type, const char *label, char *horodate, char *data) +static const char * tic_units[] = { + [U_SANS] = "", + [U_WH] = "Wh", + [U_VARH] = "VArh", + [U_A] = "A", + [U_V] = "V", + [U_KVA] = "kVA", + [U_VA] = "VA", + [U_W] = "W", +}; + +void make_field(struct tic_field *field, enum f_type type, const struct tic_etiquette *etiq, char *horodate, char *data) { if (!field) return; - field->label = label; - field->horodate = horodate; field->type = type; + field->horodate = horodate; + memcpy(&field->etiq, etiq, sizeof(field->etiq)); + switch (type) { case F_STRING: field->data.s = data; @@ -61,7 +74,7 @@ void print_field(struct tic_field *field) if (mask_allzeros && (F_INT == field->type) && (0 == field->data.i)) return; - printf("%c{ \"label\": \"%.8s\", \"data\": ", fdelim, field->label); + printf("%c{ \"label\": \"%.8s\", \"desc\": \"%s\", \"unit\": \"%s\", \"data\": ", fdelim, field->etiq.label, field->etiq.desc, tic_units[field->etiq.unit]); switch (field->type) { case F_STRING: printf("\"%s\"", field->data.s ? field->data.s : ""); @@ -165,15 +178,15 @@ field: field_horodate ; field_horodate: - etiquette_str_horodate TOK_SEP TOK_HDATE TOK_SEP TOK_SEP { make_field(&$,ドル F_STRING, 1ドル.label, 3,ドル NULL); } - | etiquette_str_horodate TOK_SEP TOK_HDATE TOK_SEP TOK_DATA TOK_SEP { make_field(&$,ドル F_STRING, 1ドル.label, 3,ドル 5ドル); } - | etiquette_int_horodate TOK_SEP TOK_HDATE TOK_SEP TOK_DATA TOK_SEP { make_field(&$,ドル F_INT, 1ドル.label, 3,ドル 5ドル); } + etiquette_str_horodate TOK_SEP TOK_HDATE TOK_SEP TOK_SEP { make_field(&$,ドル F_STRING, &1,ドル 3,ドル NULL); } + | etiquette_str_horodate TOK_SEP TOK_HDATE TOK_SEP TOK_DATA TOK_SEP { make_field(&$,ドル F_STRING, &1,ドル 3,ドル 5ドル); } + | etiquette_int_horodate TOK_SEP TOK_HDATE TOK_SEP TOK_DATA TOK_SEP { make_field(&$,ドル F_INT, &1,ドル 3,ドル 5ドル); } ; field_nodate: - etiquette_str_nodate TOK_SEP TOK_DATA TOK_SEP { make_field(&$,ドル F_STRING, 1ドル.label, NULL, 3ドル); } - | etiquette_int_nodate TOK_SEP TOK_DATA TOK_SEP { make_field(&$,ドル F_INT, 1ドル.label, NULL, 3ドル); } - | etiquette_hex_nodate TOK_SEP TOK_DATA TOK_SEP { make_field(&$,ドル F_HEX, 1ドル.label, NULL, 3ドル); } + etiquette_str_nodate TOK_SEP TOK_DATA TOK_SEP { make_field(&$,ドル F_STRING, &1,ドル NULL, 3ドル); } + | etiquette_int_nodate TOK_SEP TOK_DATA TOK_SEP { make_field(&$,ドル F_INT, &1,ドル NULL, 3ドル); } + | etiquette_hex_nodate TOK_SEP TOK_DATA TOK_SEP { make_field(&$,ドル F_HEX, &1,ドル NULL, 3ドル); } ; etiquette_str_horodate:

AltStyle によって変換されたページ (->オリジナル) /