solstice

Compute collected power and efficiencies of a solar plant
git clone git://git.meso-star.com/solstice.git
Log | Files | Refs | README | LICENSE

commit 242b104131405130d71362705afa63676e4f2bd8
parent 8ecd0c97c0aa61634c47d33058276c0869a0ca89
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 17 Jan 2017 15:14:40 +0100

Update the anchor alias input specification

Add the support of the "self" keyword to reference the current entity.

Diffstat:
Msrc/parser/solparser.c | 152+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 137 insertions(+), 15 deletions(-)

diff --git a/src/parser/solparser.c b/src/parser/solparser.c @@ -34,6 +34,16 @@ #include <string.h> #include <yaml.h> +struct target_alias { + struct solparser_pivot_id pivot; + const yaml_node_t* alias; /* Anchor */ +}; + +/* Declare the target_alias array */ +#define DARRAY_NAME tgtalias +#define DARRAY_DATA struct target_alias +#include <rsys/dynamic_array.h> + /* Declare the array of matte materials */ #define DARRAY_NAME matte #define DARRAY_DATA struct solparser_material_matte @@ -160,6 +170,9 @@ struct solparser { struct darray_matte mattes; struct darray_mirror mirrors; + /* Use to deferred the setup of the anchor targeted by a pivot */ + struct darray_tgtalias tgtaliases; + /* Shape data */ struct darray_shape shapes; /* Generic loaded shapes */ struct darray_cuboid cuboids; @@ -244,6 +257,86 @@ log_err va_end(vargs_list); } +static res_T +flush_deferred_target_aliases + (struct solparser* parser, + const yaml_node_t* node, + const struct solparser_entity_id entity_id) +{ + const struct solparser_entity* entity; + struct darray_char alias; + size_t i, n; + size_t prefix_len; + res_T res = RES_OK; + ASSERT(parser); + + darray_char_init(parser->allocator, &alias); + + if(!darray_tgtalias_size_get(&parser->tgtaliases)) + goto exit; /* No deferred target alias */ + + /* Retrieve the entity referenced by the 'self' keyword */ + entity = solparser_get_entity(parser, entity_id); + + /* Copy the entity name */ + prefix_len = strlen(str_cget(&entity->name)); + res = darray_char_resize(&alias, prefix_len); + if(res != RES_OK) { + log_err(parser, node, + "could not reserve the prefix of the targeted alias name.\n"); + goto error; + } + strncpy(darray_char_data_get(&alias), str_cget(&entity->name), prefix_len); + + n = darray_tgtalias_size_get(&parser->tgtaliases); + FOR_EACH(i, 0, n) { + const struct solparser_anchor* anchor; + struct solparser_pivot* pivot; + const struct target_alias* tgt; + size_t ianchor; + size_t len; + + tgt = darray_tgtalias_cdata_get(&parser->tgtaliases) + i; + ASSERT(!strncmp((char*)tgt->alias->data.scalar.value, "self.", 5)); + + /* Copy the anchor alias */ + len = strlen((char*)tgt->alias->data.scalar.value) + - 4/*strlen(self)*/ + 1/*NULL char*/; + res = darray_char_resize(&alias, prefix_len + len); + if(res != RES_OK) { + log_err(parser, node, + "could not reserve the suffix of the targeted alias name.\n"); + goto error; + } + strcpy(darray_char_data_get(&alias) + prefix_len, + (char*)tgt->alias->data.scalar.value+4); + + /* Retrieve the anchor */ + anchor = solparser_find_anchor(parser, darray_char_cdata_get(&alias)); + if(!anchor) { + log_err(parser, tgt->alias, "undefined anchor `%s'.\n", + tgt->alias->data.scalar.value); + res = RES_BAD_ARG; + goto error; + } + + /* Define the targeted anchor of the pivot */ + pivot = darray_pivot_data_get(&parser->pivots) + tgt->pivot.i; + ASSERT(pivot->target_type == SOLPARSER_TARGET_ANCHOR); + ianchor = (size_t)(anchor - darray_anchor_cdata_get(&parser->anchors)); + ASSERT(ianchor < darray_anchor_size_get(&parser->anchors)); + pivot->target.anchor.i = ianchor; + } + + darray_tgtalias_clear(&parser->tgtaliases); + +exit: + darray_char_release(&alias); + return res; +error: + goto exit; +} + /* Clean up loaded data */ static INLINE void parser_clear(struct solparser* parser) @@ -257,6 +350,9 @@ parser_clear(struct solparser* parser) darray_matte_clear(&parser->mattes); darray_mirror_clear(&parser->mirrors); + /* Deferred targeted anchors */ + darray_tgtalias_clear(&parser->tgtaliases); + /* Shapes */ darray_shape_clear(&parser->shapes); darray_cuboid_clear(&parser->cuboids); @@ -304,6 +400,9 @@ parser_release(ref_T* ref) darray_matte_release(&parser->mattes); darray_mirror_release(&parser->mirrors); + /* Deferred targeted anchors */ + darray_tgtalias_release(&parser->tgtaliases); + /* Shapes */ darray_shape_release(&parser->shapes); darray_cuboid_release(&parser->cuboids); @@ -369,18 +468,19 @@ parse_real double u = nextafter(upper_bound, DBL_MAX); int l_excluded = (l == (double) (int) l); int u_excluded = (u == (double) (int) u); - if (l_excluded && u_excluded) + if(l_excluded && u_excluded) { log_err(parser, real, "%g is not in ]%g, %g[.\n", *dst, l, u); - else if (l_excluded) + } else if(l_excluded) { log_err(parser, real, "%g is not in ]%g, %g].\n", *dst, l, upper_bound); - else if (u_excluded) + } else if(u_excluded) { log_err(parser, real, "%g is not in [%g, %g[.\n", *dst, lower_bound, u); - else + } else { log_err(parser, real, "%g is not in [%g, %g].\n", *dst, lower_bound, upper_bound); + } res = RES_BAD_ARG; goto error; } @@ -2403,6 +2503,7 @@ static res_T parse_anchor_alias (struct solparser* parser, const yaml_node_t* alias, + const struct solparser_pivot_id pivot, struct solparser_anchor_id* out_ianchor) { const struct solparser_anchor* anchor = NULL; @@ -2416,17 +2517,28 @@ parse_anchor_alias goto error; } - anchor = solparser_find_anchor(parser, (char*)alias->data.scalar.value); - if(!anchor) { - log_err(parser, alias, "undefined anchor `%s'.\n", - alias->data.scalar.value); - res = RES_BAD_ARG; - goto error; - } + if(!strncmp((char*)alias->data.scalar.value, "self.", 5)) { + struct target_alias tgt; + tgt.pivot = pivot; + tgt.alias = alias; + res = darray_tgtalias_push_back(&parser->tgtaliases, &tgt); + if(res != RES_OK) { + log_err(parser, alias, "could not register the anchor alias.\n"); + goto error; + } + } else { + anchor = solparser_find_anchor(parser, (char*)alias->data.scalar.value); + if(!anchor) { + log_err(parser, alias, "undefined anchor `%s'.\n", + alias->data.scalar.value); + res = RES_BAD_ARG; + goto error; + } - ianchor = anchor - darray_anchor_cdata_get(&parser->anchors); - ASSERT(ianchor >= 0); - ASSERT((size_t)ianchor < darray_anchor_size_get(&parser->anchors)); + ianchor = anchor - darray_anchor_cdata_get(&parser->anchors); + ASSERT(ianchor >= 0); + ASSERT((size_t)ianchor < darray_anchor_size_get(&parser->anchors)); + } exit: out_ianchor->i = (size_t)ianchor; @@ -2446,6 +2558,7 @@ parse_target enum { POLICY }; intptr_t i, n; int mask = 0; /* Register the parsed attributes */ + struct solparser_pivot_id pivot_id; res_T res = RES_OK; ASSERT(doc && target && pivot); @@ -2455,6 +2568,9 @@ parse_target goto error; } + /* Retrieve the pivot id */ + pivot_id.i = (size_t)(pivot - darray_pivot_cdata_get(&parser->pivots)); + n = target->data.mapping.pairs.top - target->data.mapping.pairs.start; FOR_EACH(i, 0, n) { yaml_node_t* key; @@ -2479,7 +2595,7 @@ parse_target if(!strcmp((char*)key->data.scalar.value, "anchor")) { SETUP_MASK(POLICY, "policy"); pivot->target_type = SOLPARSER_TARGET_ANCHOR; - res = parse_anchor_alias(parser, val, &pivot->target.anchor); + res = parse_anchor_alias(parser, val, pivot_id, &pivot->target.anchor); } else if(!strcmp((char*)key->data.scalar.value, "direction")) { SETUP_MASK(POLICY, "policy"); pivot->target_type = SOLPARSER_TARGET_DIRECTION; @@ -2883,6 +2999,9 @@ parse_item res = parse_material(parser, doc, val, &mtl2); } else if(!strcmp((char*)key->data.scalar.value, "entity")) { res = parse_entity(parser, doc, val, &parser->str2entities, &entity); + if(res == RES_OK) { + res = flush_deferred_target_aliases(parser, item, entity); + } } else if(!strcmp((char*)key->data.scalar.value, "template")) { /* The parsing of the template data is deferred to its explicit used in the * definition of an entity. If the parsing of the template becomes a @@ -2933,6 +3052,9 @@ solparser_create darray_matte_init(mem_allocator, &parser->mattes); darray_mirror_init(mem_allocator, &parser->mirrors); + /* Deferred targeted anchors */ + darray_tgtalias_init(mem_allocator, &parser->tgtaliases); + /* Shapes */ darray_shape_init(mem_allocator, &parser->shapes); darray_cuboid_init(mem_allocator, &parser->cuboids);