diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index b8ef493b4..514ed0c2d 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -618,9 +618,9 @@ PACK(struct ModelData { uint8_t extendedTrims:1; uint8_t throttleReversed:1; BeepANACenter beepANACenter; - MixData mixData[MAX_MIXERS]; + MixData mixData[MAX_MIXERS] NO_IDX; LimitData limitData[MAX_OUTPUT_CHANNELS]; - ExpoData expoData[MAX_EXPOS]; + ExpoData expoData[MAX_EXPOS] NO_IDX; CurveHeader curves[MAX_CURVES]; int8_t points[MAX_CURVE_POINTS]; diff --git a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp index e7681804b..a4b57d5af 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp @@ -414,7 +414,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -447,7 +446,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_t12.cpp b/radio/src/storage/yaml/yaml_datastructs_t12.cpp index 6d1a376cc..925ddfeb3 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t12.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t12.cpp @@ -384,7 +384,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -417,7 +416,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_t8.cpp b/radio/src/storage/yaml/yaml_datastructs_t8.cpp index 6d1a376cc..925ddfeb3 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t8.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t8.cpp @@ -384,7 +384,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -417,7 +416,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_tlite.cpp b/radio/src/storage/yaml/yaml_datastructs_tlite.cpp index 6d1a376cc..925ddfeb3 100644 --- a/radio/src/storage/yaml/yaml_datastructs_tlite.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_tlite.cpp @@ -384,7 +384,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -417,7 +416,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_tx12.cpp b/radio/src/storage/yaml/yaml_datastructs_tx12.cpp index 198068835..10339f3ad 100644 --- a/radio/src/storage/yaml/yaml_datastructs_tx12.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_tx12.cpp @@ -384,7 +384,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -417,7 +416,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x10.cpp b/radio/src/storage/yaml/yaml_datastructs_x10.cpp index f4943e675..57c58c304 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x10.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x10.cpp @@ -431,7 +431,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -464,7 +463,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x12s.cpp b/radio/src/storage/yaml/yaml_datastructs_x12s.cpp index 9b0c07a6f..d31960c8e 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x12s.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x12s.cpp @@ -431,7 +431,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -464,7 +463,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x7.cpp b/radio/src/storage/yaml/yaml_datastructs_x7.cpp index 6d1a376cc..925ddfeb3 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x7.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x7.cpp @@ -384,7 +384,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -417,7 +416,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x9d.cpp b/radio/src/storage/yaml/yaml_datastructs_x9d.cpp index 4a44167c8..3c6ad7cf4 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9d.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9d.cpp @@ -392,7 +392,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -425,7 +424,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x9e.cpp b/radio/src/storage/yaml/yaml_datastructs_x9e.cpp index 76ca804e0..6fc3341ec 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9e.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9e.cpp @@ -431,7 +431,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -464,7 +463,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x9lite.cpp b/radio/src/storage/yaml/yaml_datastructs_x9lite.cpp index b5f062019..ee0e08ad5 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9lite.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9lite.cpp @@ -369,7 +369,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -402,7 +401,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x9lites.cpp b/radio/src/storage/yaml/yaml_datastructs_x9lites.cpp index af38095d0..953e8576c 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9lites.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9lites.cpp @@ -379,7 +379,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -412,7 +411,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_xlite.cpp b/radio/src/storage/yaml/yaml_datastructs_xlite.cpp index 5acfa240d..e874be5a2 100644 --- a/radio/src/storage/yaml/yaml_datastructs_xlite.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_xlite.cpp @@ -376,7 +376,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -409,7 +408,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_datastructs_xlites.cpp b/radio/src/storage/yaml/yaml_datastructs_xlites.cpp index 3837ff5d4..b93615484 100644 --- a/radio/src/storage/yaml/yaml_datastructs_xlites.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_xlites.cpp @@ -380,7 +380,6 @@ static const struct YamlNode struct_CurveRef[] = { YAML_END }; static const struct YamlNode struct_MixData[] = { - YAML_IDX, YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), YAML_UNSIGNED( "destCh", 5 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), @@ -413,7 +412,6 @@ static const struct YamlNode struct_LimitData[] = { YAML_END }; static const struct YamlNode struct_ExpoData[] = { - YAML_IDX, YAML_UNSIGNED( "mode", 2 ), YAML_UNSIGNED( "scale", 14 ), YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), diff --git a/radio/src/storage/yaml/yaml_defs.h b/radio/src/storage/yaml/yaml_defs.h index 45d5d4258..2f5c0e874 100644 --- a/radio/src/storage/yaml/yaml_defs.h +++ b/radio/src/storage/yaml/yaml_defs.h @@ -32,6 +32,7 @@ #define ENUM(label) _yaml_attribute("enum:" _yaml_note(label)) #define SKIP _yaml_attribute("skip:true") #define USE_IDX _yaml_attribute("idx:true") +#define NO_IDX _yaml_attribute("idx:false") #define FUNC(name) _yaml_attribute("func:" _yaml_note(name)) #define NAME(label) _yaml_attribute("name:" _yaml_note(label)) @@ -56,6 +57,7 @@ #define ENUM(label) #define SKIP #define USE_IDX +#define NO_IDX #define FUNC(name) #define NAME(label) #define CUST(read, write) diff --git a/radio/src/storage/yaml/yaml_parser.cpp b/radio/src/storage/yaml/yaml_parser.cpp index c782f2329..92e601946 100644 --- a/radio/src/storage/yaml/yaml_parser.cpp +++ b/radio/src/storage/yaml/yaml_parser.cpp @@ -35,6 +35,7 @@ void YamlParser::init(const YamlParserCalls* parser_calls, void* parser_ctx) indent = 0; level = 0; memset(indents, 0, sizeof(indents)); + saved_state = 0; calls = parser_calls; ctx = parser_ctx; @@ -43,8 +44,11 @@ void YamlParser::init(const YamlParserCalls* parser_calls, void* parser_ctx) void YamlParser::reset() { - state = ps_Indent; - indents[level] = indent; + state = saved_state; + if (state != ps_Dash) { + indents[level] = indent; + state = saved_state = ps_Indent; + } indent = scratch_len = 0; node_found = false; } @@ -105,6 +109,12 @@ YamlParser::parse(const char* buffer, unsigned int size) break; } + if (*c == '\r' || *c == '\n') { + saved_state = state; + state = ps_CRLF; + continue; + } + if (indent < getLastIndent()) { // go up as many levels as necessary do { @@ -114,6 +124,7 @@ YamlParser::parse(const char* buffer, unsigned int size) } } while (indent < getLastIndent()); + // attribute on same line as dash if (state == ps_Dash) { if (!calls->to_next_elmt(ctx)) { return DONE_PARSING; @@ -122,13 +133,15 @@ YamlParser::parse(const char* buffer, unsigned int size) } // go down one level else if (indent > getLastIndent()) { + // TODO: check dash? if (!toChild()) { TRACE_YAML("STOP (stack full)!\n"); return DONE_PARSING; // ERROR } } // same level, next element - else if (state == ps_Dash) { + else if (state == ps_Dash || saved_state == ps_Dash) { + // attribute on same line or next line as dash if (!calls->to_next_elmt(ctx)) { return DONE_PARSING; } @@ -160,6 +173,7 @@ YamlParser::parse(const char* buffer, unsigned int size) scratch_len, scratch_buf); } } + saved_state = state; state = ps_CRLF; continue; } @@ -180,6 +194,7 @@ YamlParser::parse(const char* buffer, unsigned int size) if (*c == ' ') break; if (*c == '\r' || *c == '\n'){ + saved_state = state; state = ps_CRLF; continue; } @@ -251,6 +266,7 @@ YamlParser::parse(const char* buffer, unsigned int size) if (node_found) { calls->set_attr(ctx, scratch_buf, scratch_len); } + saved_state = state; state = ps_CRLF; continue; } diff --git a/radio/src/storage/yaml/yaml_parser.h b/radio/src/storage/yaml/yaml_parser.h index a5812ec63..74b26db47 100644 --- a/radio/src/storage/yaml/yaml_parser.h +++ b/radio/src/storage/yaml/yaml_parser.h @@ -63,6 +63,7 @@ class YamlParser // parser state uint8_t state; + uint8_t saved_state; // scratch buffer w/ 16 bytes // used for attribute and values diff --git a/radio/src/storage/yaml/yaml_tree_walker.cpp b/radio/src/storage/yaml/yaml_tree_walker.cpp index d5cfee6e2..9f27dc32c 100644 --- a/radio/src/storage/yaml/yaml_tree_walker.cpp +++ b/radio/src/storage/yaml/yaml_tree_walker.cpp @@ -200,8 +200,7 @@ static bool yaml_output_attr(uint8_t* ptr, uint32_t bit_ofs, const YamlNode* nod YamlTreeWalker::YamlTreeWalker() : stack_level(NODE_STACK_DEPTH), virt_level(0), - anon_union(0), - idx_invalid(false) + anon_union(0) { memset(stack,0,sizeof(stack)); } @@ -211,7 +210,6 @@ void YamlTreeWalker::reset(const YamlNode* node, uint8_t* data) this->data = data; stack_level = NODE_STACK_DEPTH; virt_level = 0; - idx_invalid = false; push(); setNode(node); @@ -225,7 +223,6 @@ bool YamlTreeWalker::push() stack_level--; memset(&(stack[stack_level]), 0, sizeof(State)); - idx_invalid = false; return true; } @@ -237,7 +234,6 @@ bool YamlTreeWalker::pop() memset(&(stack[stack_level]), 0, sizeof(State)); stack_level++; - idx_invalid = false; return true; } @@ -261,10 +257,15 @@ bool YamlTreeWalker::findNode(const char* tag, uint8_t tag_len) { if (virt_level) return false; - + rewind(); const struct YamlNode* attr = getAttr(); + if (isArrayElmt() && attr && attr->type == YDT_IDX) { + setAttrValue((char*)tag, tag_len); + return true; + } + while(attr && attr->type != YDT_NONE) { if ((tag_len == attr->tag_len) @@ -303,11 +304,23 @@ bool YamlTreeWalker::toChild() const struct YamlNode* attr = getAttr(); if (!attr || (attr->type != YDT_ARRAY - && attr->type != YDT_UNION)) { + && attr->type != YDT_UNION + && !isArrayElmt())) { virt_level++; return true; } + bool is_array = false; + if (attr->type == YDT_ARRAY + && attr->u._array.u._a.elmts > 1) { + is_array = true; + } + + const YamlNode* parent_node = getNode(); + if (isArrayElmt() && attr->type == YDT_IDX) { + attr = parent_node; + } + if (!push()) { virt_level++; return false; @@ -317,11 +330,17 @@ bool YamlTreeWalker::toChild() setAttrOfs(getLevelOfs()); attr = getAttr(); + if (!attr) + return false; + if ((attr->type == YDT_UNION) && (attr->tag_len == 0)) { toChild(); anon_union++; } + if (is_array) + setArrayElmt(true); + return true; } @@ -335,8 +354,8 @@ bool YamlTreeWalker::toNextElmt() return false; } - if (idx_invalid) { - idx_invalid = false; + if (isIdxInvalid()) { + setIdxInvalid(false); stack[stack_level].elmts = 0; } @@ -424,7 +443,7 @@ void YamlTreeWalker::toNextAttr() void YamlTreeWalker::setAttrValue(char* buf, uint8_t len) { - if (!buf || !len || idx_invalid) + if (!buf || !len || isIdxInvalid()) return; const YamlNode* attr = getAttr(); @@ -441,10 +460,10 @@ void YamlTreeWalker::setAttrValue(char* buf, uint8_t len) while ((i > getElmts()) && toNextElmt()); if (i > getElmts()) - idx_invalid = true; + setIdxInvalid(true); } else { - yaml_set_attr(data, getBitOffset(), attr, getElmts(), buf, len); + yaml_set_attr(data, getBitOffset(), attr, getParentElmts(), buf, len); //walker.dump_stack(); } } @@ -476,6 +495,10 @@ bool YamlTreeWalker::generate(yaml_writer_func wf, void* opaque) return false; } else { + + if (isParentArrayElmt() && !toParent()) + return false; + // walk to next non-empty element while (toNextElmt()) { if (!isElmtEmpty(data)) { @@ -509,7 +532,7 @@ bool YamlTreeWalker::generate(yaml_writer_func wf, void* opaque) for(int i=2; i < getLevel(); i++) if (!wf(opaque, " ", 3)) return false; - if (!yaml_output_attr(NULL, 0, node, getElmts(), wf, opaque)) + if (!yaml_output_attr(NULL, 0, node, 0, wf, opaque)) return false; // TODO: error handling??? // grab attr idx... @@ -521,7 +544,7 @@ bool YamlTreeWalker::generate(yaml_writer_func wf, void* opaque) for(int i=1; i < getLevel(); i++) if (!wf(opaque, " ", 3)) return false; - if (!yaml_output_attr(data, getBitOffset(), attr, getElmts(), wf, opaque)) + if (!yaml_output_attr(data, getBitOffset(), attr, 0, wf, opaque)) return false; // TODO: error handling??? if (attr->type != YDT_ARRAY @@ -554,7 +577,7 @@ bool YamlTreeWalker::generate(yaml_writer_func wf, void* opaque) for(int i=2; i < getLevel(); i++) if (!wf(opaque, " ", 3)) return false; - if (!yaml_output_attr(NULL, 0, getNode(), getElmts(), wf, opaque)) + if (!yaml_output_attr(NULL, 0, getNode(),0, wf, opaque)) return false; // TODO: error handling??? continue; } @@ -567,30 +590,13 @@ bool YamlTreeWalker::generate(yaml_writer_func wf, void* opaque) continue; } - if (new_elmt) { - - for(int i=2; i < getLevel(); i++) - if (!wf(opaque, " ", 3)) - return false; - - if (!wf(opaque, " - ", 3)) - return false; + // TODO: support for lists (inputs, mixers) + if (attr->type == YDT_IDX) { new_elmt = false; - } - else { for(int i=1; i < getLevel(); i++) if (!wf(opaque, " ", 3)) return false; - } - - if (attr->type == YDT_IDX) { - - if (!wf(opaque, attr->tag, attr->tag_len)) - return false; - - if (!wf(opaque, ": ", 2)) - return false; if (attr->u._cust_idx.write) { if (!attr->u._cust_idx.write(getElmts(),wf,opaque)) @@ -602,11 +608,33 @@ bool YamlTreeWalker::generate(yaml_writer_func wf, void* opaque) return false; } - if (!wf(opaque, "\r\n", 2)) + if (!wf(opaque, ":\r\n", 3)) return false; + + toChild(); //TODO: error checking + } + else { + + // only for lists: + // - arrays have IDX upfront + // - structs are not marked as arrays + if (new_elmt && isArrayElmt()) { + for(int i=2; i < getLevel(); i++) + if (!wf(opaque, " ", 3)) + return false; + + if (!wf(opaque, " -\r\n", 4)) + return false; + } + + new_elmt = false; + for(int i=1; i < getLevel(); i++) + if (!wf(opaque, " ", 3)) + return false; + + if (!yaml_output_attr(data, getBitOffset(), attr, getParentElmts(), wf, opaque)) + return false; // TODO: error handling??? } - else if (!yaml_output_attr(data, getBitOffset(), attr, getElmts(), wf, opaque)) - return false; // TODO: error handling??? toNextAttr(); } diff --git a/radio/src/storage/yaml/yaml_tree_walker.h b/radio/src/storage/yaml/yaml_tree_walker.h index 8747a0124..c8e1f5591 100644 --- a/radio/src/storage/yaml/yaml_tree_walker.h +++ b/radio/src/storage/yaml/yaml_tree_walker.h @@ -27,6 +27,9 @@ struct YamlParserCalls; +#define FLAG_STATE_IDX_INVALID (1 << 0) +#define FLAG_STATE_ARRAY_ELMT (1 << 1) + class YamlTreeWalker { struct State { @@ -34,6 +37,7 @@ class YamlTreeWalker uint32_t bit_ofs; int8_t attr_idx; uint16_t elmts; + uint8_t flags; inline uint32_t getOfs() { return bit_ofs + node->size * elmts; @@ -44,7 +48,6 @@ class YamlTreeWalker uint8_t stack_level; uint8_t virt_level; uint8_t anon_union; - bool idx_invalid; uint8_t* data; @@ -71,6 +74,28 @@ class YamlTreeWalker void incAttr() { stack[stack_level].attr_idx++; } void incElmts() { stack[stack_level].elmts++; } + inline bool isIdxInvalid() { + return stack[stack_level].flags & FLAG_STATE_IDX_INVALID; + } + + inline void setIdxInvalid(bool set) { + if (set) stack[stack_level].flags |= FLAG_STATE_IDX_INVALID; + else stack[stack_level].flags &= ~FLAG_STATE_IDX_INVALID; + } + + inline bool isArrayElmt() { + return stack[stack_level].flags & FLAG_STATE_ARRAY_ELMT; + } + + inline bool isParentArrayElmt() { + return !empty() && stack[stack_level + 1].flags & FLAG_STATE_ARRAY_ELMT; + } + + inline void setArrayElmt(bool set) { + if (set) stack[stack_level].flags |= FLAG_STATE_ARRAY_ELMT; + else stack[stack_level].flags &= ~FLAG_STATE_ARRAY_ELMT; + } + bool empty() { return stack_level == NODE_STACK_DEPTH; } bool full() { return stack_level == 0; } @@ -110,6 +135,10 @@ public: return stack[stack_level].elmts; } + uint16_t getParentElmts() { + return empty() ? 0 : stack[stack_level + 1].elmts; + } + // Increment the cursor until a match is found or the end of // the current collection (node of type YDT_NONE) is reached. // diff --git a/radio/util/generate_yaml.py b/radio/util/generate_yaml.py index cf522e995..b9ab0c064 100644 --- a/radio/util/generate_yaml.py +++ b/radio/util/generate_yaml.py @@ -336,12 +336,12 @@ def parse_field_array(f, node): if f.type != 'string': elmt_decl = et.get_declaration() - use_idx = False + use_idx = True ann = get_annotations(node) if len(ann) > 0: for a in ann: - if a['type'] == 'idx': - use_idx = True + if a['type'] == 'idx' and a['val'] == 'false': + use_idx = False elif a['type'] == 'raw': f.raw = a['val'] @@ -353,6 +353,7 @@ def parse_field_array(f, node): f.var_name = elmt_st.var_name # mark array usage for unions elmt_st.used_in_arrays = True + elmt_st.use_idx = use_idx elif elmt_decl.kind == CursorKind.TYPEDEF_DECL: # it's some typedef #print_error("TYPEDEF {} {}".format(f.name, elmt_decl.spelling)); diff --git a/radio/util/yaml_parser.tmpl b/radio/util/yaml_parser.tmpl index 52216301b..cbbcfbd65 100644 --- a/radio/util/yaml_parser.tmpl +++ b/radio/util/yaml_parser.tmpl @@ -22,7 +22,7 @@ const struct YamlIdStr {{ enum.name }}[] = { static const struct YamlNode {{ struct.name }}_elmts[] = { {% else %} static const struct YamlNode {{ struct.name }}[] = { - {% if struct.used_in_arrays %} + {% if struct.use_idx %} YAML_IDX, {% endif%} {% endif %}