solparser_medium.c (4782B)
1 /* Copyright (C) 2018-2026 |Meso|Star> (contact@meso-star.com) 2 * Copyright (C) 2016-2018 CNRS 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #define _POSIX_C_SOURCE 200112L /* nextafter support */ 18 19 #include "solparser_c.h" 20 #include <math.h> /* nextafter */ 21 22 /******************************************************************************* 23 * Local function 24 ******************************************************************************/ 25 res_T 26 parse_medium 27 (struct solparser* parser, 28 yaml_document_t* doc, 29 yaml_node_t* medium, 30 struct solparser_medium_id* out_imedium) 31 { 32 enum { EXTINCTION, REFRACTIVE_INDEX }; 33 struct solparser_medium* mdm = NULL; 34 size_t* pimedium = NULL; 35 size_t imedium = SIZE_MAX; 36 int mask = 0; /* Register the parsed attributes */ 37 intptr_t i, n; 38 res_T res = RES_OK; 39 ASSERT(doc && medium && out_imedium); 40 41 if(medium->type != YAML_MAPPING_NODE) { 42 log_err(parser, medium, "expect a mapping of medium attributes.\n"); 43 res = RES_BAD_ARG; 44 goto error; 45 } 46 47 /* Check whether or not the YAML medium alias an already created Solstice 48 * medium */ 49 pimedium = htable_yaml2sols_find(&parser->yaml2mediums, &medium); 50 if(pimedium) { 51 imedium = *pimedium; 52 goto exit; 53 } 54 55 /* Allocate the medium */ 56 imedium = darray_medium_size_get(&parser->mediums); 57 res = darray_medium_resize(&parser->mediums, imedium + 1); 58 if(res != RES_OK) { 59 log_err(parser, medium, "could not allocate the medium.\n"); 60 res = RES_BAD_ARG; 61 goto error; 62 } 63 mdm = darray_medium_data_get(&parser->mediums) + imedium; 64 65 n = medium->data.mapping.pairs.top - medium->data.mapping.pairs.start; 66 FOR_EACH(i, 0, n) { 67 yaml_node_t* key; 68 yaml_node_t* val; 69 70 key = yaml_document_get_node(doc, medium->data.mapping.pairs.start[i].key); 71 val = yaml_document_get_node(doc, medium->data.mapping.pairs.start[i].value); 72 if(key->type != YAML_SCALAR_NODE) { 73 log_err(parser, key, "expect a medium parameter.\n"); 74 res = RES_BAD_ARG; 75 goto error; 76 } 77 #define SETUP_MASK(Flag, Name) { \ 78 if(mask & BIT(Flag)) { \ 79 log_err(parser, key,"the "Name" of the medium is already defined.\n");\ 80 res = RES_BAD_ARG; \ 81 goto error; \ 82 } \ 83 mask |= BIT(Flag); \ 84 } (void)0 85 if(!strcmp((char*)key->data.scalar.value, "extinction")) { 86 SETUP_MASK(EXTINCTION, "extinction"); 87 res = parse_mtl_data(parser, doc, val, 0, DBL_MAX, &mdm->extinction); 88 } else if(!strcmp((char*)key->data.scalar.value, "refractive_index")) { 89 SETUP_MASK(REFRACTIVE_INDEX, "refractive_index"); 90 res = parse_mtl_data 91 (parser, doc, val, nextafter(0, 1), DBL_MAX, &mdm->refractive_index); 92 } else { 93 log_err(parser, key, "unknown medium parameter `%s'.\n", 94 key->data.scalar.value); 95 res = RES_BAD_ARG; 96 goto error; 97 } 98 if(res != RES_OK) { 99 log_node(parser, key); 100 goto error; 101 } 102 #undef SETUP_MASK 103 } 104 105 #define CHECK_PARAM(Flag, Name) \ 106 if(!(mask & BIT(Flag))) { \ 107 log_err(parser, medium, "the "Name" of the medium is missing.\n"); \ 108 res = RES_BAD_ARG; \ 109 goto error; \ 110 } (void)0 111 CHECK_PARAM(EXTINCTION, "absorption"); 112 CHECK_PARAM(REFRACTIVE_INDEX, "refractive_index"); 113 #undef CHECK_PARAM 114 115 /* Cache the medium */ 116 res = htable_yaml2sols_set(&parser->yaml2mediums, &medium, &imedium); 117 if(res != RES_OK) { 118 log_err(parser, medium, "could not register the medium.\n"); 119 goto error; 120 } 121 122 exit: 123 out_imedium->i = imedium; 124 return res; 125 error: 126 if(imedium) { 127 darray_medium_pop_back(&parser->mediums); 128 imedium = SIZE_MAX; 129 } 130 goto exit; 131 } 132