stardis

Perform coupled heat transfer calculations
git clone git://git.meso-star.fr/stardis.git
Log | Files | Refs | README | LICENSE

commit 94289c500d182e6311ea8b00ef8c6004846623eb
parent 387be624f2e16dcdd556cfe88355f52978721a07
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 29 Apr 2022 18:26:30 +0200

Enable word expansion in model files

As a consequence, programmed properties now receive argc argv args

Diffstat:
Msrc/stardis-fbound-prog.c | 8++++----
Msrc/stardis-fbound-prog.h | 5+++--
Msrc/stardis-fluid-prog.c | 9++++-----
Msrc/stardis-fluid-prog.h | 5+++--
Msrc/stardis-green-types.h.in | 2++
Msrc/stardis-hbound-prog.c | 8++++----
Msrc/stardis-hbound-prog.h | 5+++--
Msrc/stardis-parsing.c | 790+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/stardis-parsing.h | 13+++++++------
Msrc/stardis-prog-properties.h.in | 8++++++--
Msrc/stardis-program.c | 11+++++++----
Msrc/stardis-program.h | 5+++--
Msrc/stardis-sfconnect-prog.c | 8++++----
Msrc/stardis-sfconnect-prog.h | 5+++--
Msrc/stardis-solid-prog.c | 9++++-----
Msrc/stardis-solid-prog.h | 5+++--
Msrc/stardis-ssconnect-prog.c | 8++++----
Msrc/stardis-ssconnect-prog.h | 5+++--
Msrc/stardis-tbound-prog.c | 8++++----
Msrc/stardis-tbound-prog.h | 5+++--
20 files changed, 505 insertions(+), 417 deletions(-)

diff --git a/src/stardis-fbound-prog.c b/src/stardis-fbound-prog.c @@ -45,7 +45,6 @@ init_f_boundary_prog } str_init(allocator, &(*dst)->name); str_init(allocator, &(*dst)->prog_name); - str_init(allocator, &(*dst)->args); str_initialized = 1; (*dst)->mat_id = UINT_MAX; end: @@ -54,7 +53,6 @@ error: if(str_initialized) { str_release(&(*dst)->name); str_release(&(*dst)->prog_name); - str_release(&(*dst)->args); } if(*dst) MEM_RM(allocator, *dst); goto end; @@ -65,12 +63,14 @@ release_f_boundary_prog (struct f_boundary_prog* bound, struct mem_allocator* allocator) { + size_t i; ASSERT(bound && allocator); str_release(&bound->name); str_release(&bound->prog_name); - str_release(&bound->args); if(bound->prog_data) bound->release(bound->prog_data); + for(i = 0; i < bound->argc; i++) MEM_RM(allocator, bound->argv[i]); + MEM_RM(allocator, bound->argv); /* library_close call is managed at lib_data level */ MEM_RM(allocator, bound); } @@ -86,7 +86,7 @@ str_print_f_boundary_prog "programmed F boundary for SOLID '%s': lib='%s', args=[%s]" " (using medium %u as external medium)", str_cget(&b->name), str_cget(&b->prog_name), - str_cget(&b->args), b->mat_id)); + "TODO", b->mat_id)); end: return res; error: diff --git a/src/stardis-fbound-prog.h b/src/stardis-fbound-prog.h @@ -34,11 +34,12 @@ struct f_boundary_prog { void* prog_data; /* result of the create() call */ struct str name; struct str prog_name; - struct str args; + size_t argc; + char** argv; /* lib handle and function ptrs */ struct program* program; void* (*create) - (const struct stardis_description_create_context*, void*, char*); + (const struct stardis_description_create_context*, void*, size_t, char**); void (*release)(void*); double (*flux)(const struct stardis_interface_fragment*, void*); unsigned mat_id; diff --git a/src/stardis-fluid-prog.c b/src/stardis-fluid-prog.c @@ -147,7 +147,6 @@ init_fluid_prog(struct mem_allocator* allocator, struct fluid_prog** dst) } str_init(allocator, &(*dst)->name); str_init(allocator, &(*dst)->prog_name); - str_init(allocator, &(*dst)->args); str_initialized = 1; (*dst)->desc_id = UINT_MAX; (*dst)->fluid_id = UINT_MAX; @@ -157,7 +156,6 @@ error: if(str_initialized) { str_release(&(*dst)->name); str_release(&(*dst)->prog_name); - str_release(&(*dst)->args); } if(*dst) MEM_RM(allocator, *dst); goto end; @@ -168,16 +166,17 @@ release_fluid_prog (struct fluid_prog* fluid, struct mem_allocator* allocator) { + size_t i; ASSERT(fluid && allocator); str_release(&fluid->name); str_release(&fluid->prog_name); - str_release(&fluid->args); - if(fluid->prog_data && fluid->release) /* can be NULL if external fluid */ { fluid->release(fluid->prog_data); } + for(i = 0; i < fluid->argc; i++) MEM_RM(allocator, fluid->argv[i]); + MEM_RM(allocator, fluid->argv); /* library_close call is managed at lib_data level */ MEM_RM(allocator, fluid); } @@ -189,7 +188,7 @@ str_print_fluid_prog(struct str* str, const struct fluid_prog* f) ASSERT(str && f); ERR(str_append_printf(str, "programmed fluid '%s': lib='%s', args=[%s] (it is medium %u)", - str_cget(&f->name), str_cget(&f->prog_name), str_cget(&f->args), + str_cget(&f->name), str_cget(&f->prog_name), "TODO", f->fluid_id)); end: return res; diff --git a/src/stardis-fluid-prog.h b/src/stardis-fluid-prog.h @@ -32,14 +32,15 @@ struct fluid_prog { void* prog_data; /* result of the create() call */ struct str name; struct str prog_name; - struct str args; + size_t argc; + char** argv; int is_outside; /* the fluid is used for a boundary */ unsigned desc_id; /* id of the boundary; meaningful if is_outside */ unsigned fluid_id; /* lib handle and function ptrs */ struct program* program; void* (*create) - (const struct stardis_description_create_context*, void*, char*); + (const struct stardis_description_create_context*, void*, size_t, char**); void (*release)(void*); double (*rho)(const struct stardis_vertex*, void*); double (*cp)(const struct stardis_vertex*, void*); diff --git a/src/stardis-green-types.h.in b/src/stardis-green-types.h.in @@ -16,6 +16,8 @@ #ifndef SDIS_GREEN_H #define SDIS_GREEN_H +#include <stddef.h> + /* The number of the file format as presented thereafter */ #define GREEN_FILE_FORMAT_VERSION @STARDIS_GREEN_TYPES_VERSION@ diff --git a/src/stardis-hbound-prog.c b/src/stardis-hbound-prog.c @@ -45,7 +45,6 @@ init_h_boundary_prog } str_init(allocator, &(*dst)->name); str_init(allocator, &(*dst)->prog_name); - str_init(allocator, &(*dst)->args); str_initialized = 1; (*dst)->mat_id = UINT_MAX; end: @@ -54,7 +53,6 @@ error: if(str_initialized) { str_release(&(*dst)->name); str_release(&(*dst)->prog_name); - str_release(&(*dst)->args); } if(*dst) MEM_RM(allocator, *dst); goto end; @@ -65,14 +63,16 @@ release_h_boundary_prog (struct h_boundary_prog* bound, struct mem_allocator* allocator) { + size_t i; ASSERT(bound && allocator); str_release(&bound->name); str_release(&bound->prog_name); - str_release(&bound->args); if(bound->prog_data) bound->release(bound->prog_data); if(bound->possible_external_fluid) release_fluid_prog(bound->possible_external_fluid, allocator); + for(i = 0; i < bound->argc; i++) MEM_RM(allocator, bound->argv[i]); + MEM_RM(allocator, bound->argv); /* library_close call is managed at lib_data level */ MEM_RM(allocator, bound); } @@ -90,7 +90,7 @@ str_print_h_boundary_prog "programmed H boundary for %s '%s': lib='%s', args=[%s] " "(using medium %u as external medium)", (desc->type == DESC_BOUND_H_FOR_SOLID_PROG ? "solid" : "fluid"), - str_cget(&b->name), str_cget(&b->prog_name), str_cget(&b->args), + str_cget(&b->name), str_cget(&b->prog_name), "TODO", b->mat_id)); end: return res; diff --git a/src/stardis-hbound-prog.h b/src/stardis-hbound-prog.h @@ -33,11 +33,12 @@ struct h_boundary_prog { void* prog_data; /* result of the create() call */ struct str name; struct str prog_name; - struct str args; + size_t argc; + char** argv; /* lib handle and function ptrs */ struct program* program; void* (*create) - (const struct stardis_description_create_context*, void*, char*); + (const struct stardis_description_create_context*, void*, size_t, char**); void (*release)(void*); double (*ref_temp)(const struct stardis_interface_fragment*, void*); double (*emissivity)(const struct stardis_interface_fragment*, void*); diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c @@ -13,7 +13,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define _POSIX_C_SOURCE 200809L /* strdup */ #include "stardis-parsing.h" #include "stardis-app.h" #include "stardis-prog-properties.h" @@ -37,6 +36,7 @@ #include "stardis-default.h" #include "stardis-green-types.h" +#include <rsys/rsys.h> #include <rsys/cstr.h> #include <rsys/double2.h> #include <rsys/double3.h> @@ -44,6 +44,7 @@ #include <rsys/text_reader.h> #include <rsys/library.h> +#include <wordexp.h> #include <stdlib.h> #include <stdio.h> #include <ctype.h> @@ -52,8 +53,6 @@ #include <strings.h> /* strcasecmp */ #else #define strcasecmp(s1, s2) _stricmp((s1), (s2)) -#define strdup(tok) _strdup(tok) -#define strtok_r(str, delim, save) strtok_s((str), (delim), (save)) #endif /******************************************************************************* @@ -92,9 +91,10 @@ read_sides_and_files (struct stardis* stardis, const int descr_is_intface, /* if 1, don't read side */ const unsigned description_id, - char** tok_ctx) + wordexp_t* pwordexp, + size_t* idx) { - char* tk = NULL; + char* arg = NULL; int file_count = 0; struct sstl* sstl = NULL; struct add_geom_ctx add_geom_ctx; @@ -104,7 +104,7 @@ read_sides_and_files struct str str; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp && idx); darray_uint_init(stardis->allocator, &degenerated); str_init(stardis->allocator, &str); @@ -126,8 +126,9 @@ read_sides_and_files add_geom_ctx.properties[SG3D_BACK] = SG3D_UNSPECIFIED_PROPERTY; add_geom_ctx.properties[SG3D_INTFACE] = description_id; } else { - tk = strtok_r(NULL, " \t", tok_ctx); - if(!tk || 0 == strcasecmp(tk, "PROG_PARAMS")) { + if(pwordexp->we_wordc <= *idx + || 0 == strcasecmp((arg = pwordexp->we_wordv[(*idx)++]), "PROG_PARAMS")) + { if(file_count == 0) { /* At least 1 side */ logger_print(stardis->logger, LOG_ERROR, @@ -138,27 +139,28 @@ read_sides_and_files else break; } add_geom_ctx.properties[SG3D_INTFACE] = SG3D_UNSPECIFIED_PROPERTY; - if(0 == strcasecmp(tk, "FRONT")) { + if(0 == strcasecmp(arg, "FRONT")) { add_geom_ctx.properties[SG3D_FRONT] = description_id; add_geom_ctx.properties[SG3D_BACK] = SG3D_UNSPECIFIED_PROPERTY; } - else if(0 == strcasecmp(tk, "BACK")) { + else if(0 == strcasecmp(arg, "BACK")) { add_geom_ctx.properties[SG3D_FRONT] = SG3D_UNSPECIFIED_PROPERTY; add_geom_ctx.properties[SG3D_BACK] = description_id; } - else if(0 == strcasecmp(tk, "BOTH")) { + else if(0 == strcasecmp(arg, "BOTH")) { add_geom_ctx.properties[SG3D_FRONT] = description_id; add_geom_ctx.properties[SG3D_BACK] = description_id; } else { logger_print(stardis->logger, LOG_ERROR, - "Invalid side specifier: %s\n", tk); + "Invalid side specifier: %s\n", arg); res = RES_BAD_ARG; goto error; } } - tk = strtok_r(NULL, " \t", tok_ctx); - if(!tk || 0 == strcasecmp(tk, "PROG_PARAMS")) { + if(pwordexp->we_wordc <= *idx + || 0 == strcasecmp((arg = pwordexp->we_wordv[(*idx)++]), "PROG_PARAMS")) + { if(!descr_is_intface /* Has read a side specifier */ || !file_count) /* Need at least 1 file name */ { @@ -170,17 +172,17 @@ read_sides_and_files else break; } file_count++; - res = sstl_load(sstl, tk); + res = sstl_load(sstl, arg); if(res == RES_OK) { ERR(sstl_get_desc(sstl, &add_geom_ctx.stl_desc)); ASSERT(add_geom_ctx.stl_desc.vertices_count <= UINT_MAX && add_geom_ctx.stl_desc.triangles_count <= UINT_MAX); logger_print(stardis->logger, LOG_OUTPUT, "Read file '%s': %u triangles found.\n", - tk, (unsigned)add_geom_ctx.stl_desc.triangles_count); + arg, (unsigned)add_geom_ctx.stl_desc.triangles_count); } else { logger_print(stardis->logger, LOG_ERROR, - "Cannot read STL file: '%s'\n", tk); + "Cannot read STL file: '%s'\n", arg); goto error; } @@ -197,7 +199,7 @@ read_sides_and_files ASSERT(c <= ULONG_MAX); logger_print(stardis->logger, LOG_WARNING, "File '%s' included %lu degenerated triangles (removed)\n", - tk, (unsigned long)c); + arg, (unsigned long)c); ERR(str_printf(&str, "Degenerated triangles IDs: %u", ids[0])); FOR_EACH(n, 1, c) { ERR(str_append_printf(&str, ", %u", ids[n])); } logger_print(stardis->logger, LOG_OUTPUT, "%s\n", str_cget(&str)); @@ -206,7 +208,7 @@ read_sides_and_files if(res != RES_OK) { logger_print(stardis->logger, LOG_ERROR, - "Cannot add file content: '%s'\n", tk); + "Cannot add file content: '%s'\n", arg); goto error; } /* Check conflicts */ @@ -217,7 +219,7 @@ read_sides_and_files (stardis->mode & COMPUTE_MODES) && !(stardis->mode & MODE_DUMP_VTK); logger_print(stardis->logger, (is_for_compute ? LOG_ERROR : LOG_WARNING), "Merge conflicts found reading file '%s' (%u triangles).\n", - tk, merge_errors - current_merge_errors); + arg, merge_errors - current_merge_errors); if(is_for_compute) { res = RES_BAD_ARG; goto error; @@ -271,7 +273,7 @@ static res_T description_set_name (struct stardis* stardis, struct str* name, - const char* tk) + const char* arg) { res_T res = RES_OK; double foo; @@ -285,19 +287,19 @@ description_set_name "T_BOUNDARY_FOR_SOLID_PROG", "UNKNOWN" }; const char* reason = NULL; size_t i; - ASSERT(name && tk); + ASSERT(name && arg); /* Use name before uppercasing it */ - ERR(str_set(name, tk)); + ERR(str_set(name, arg)); - if(RES_OK == cstr_to_double(tk, &foo)) { + if(RES_OK == cstr_to_double(arg, &foo)) { /* A number is not a sensible choice for a name! */ res = RES_BAD_ARG; reason = "number"; goto error; } FOR_EACH(i, 0, sizeof(keywords) / sizeof(*keywords)) { - if(0 == strcasecmp(tk, keywords[i])) { + if(0 == strcasecmp(arg, keywords[i])) { /* A keyword is not a sensible choice for a name! */ res = RES_BAD_ARG; reason = "reserved keyword"; @@ -317,7 +319,7 @@ end: error: ASSERT(reason != NULL); logger_print(stardis->logger, LOG_ERROR, "Invalid name (%s): %s\n", - reason, tk); + reason, arg); goto end; } @@ -347,15 +349,16 @@ static res_T process_h (struct stardis* stardis, const enum description_type type, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; size_t sz; struct h_boundary* h_boundary; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.hbound_count++; @@ -366,63 +369,64 @@ process_h h_boundary = desc->d.h_boundary; desc->type = type; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "h boundary name"); - ERR(description_set_name(stardis, &h_boundary->name, tk)); + CHK_ARG(idx, "h boundary name"); + ERR(description_set_name(stardis, &h_boundary->name, arg)); if(find_description_by_name(stardis, &h_boundary->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "ref_temperature"); - res = cstr_to_double(tk, &h_boundary->ref_temperature); + CHK_ARG(idx, "ref_temperature"); + res = cstr_to_double(arg, &h_boundary->ref_temperature); if(res != RES_OK || h_boundary->ref_temperature < 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid reference temperature: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, + "Invalid reference temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } stardis->t_range[0] = MMIN(stardis->t_range[0], h_boundary->ref_temperature); stardis->t_range[1] = MMAX(stardis->t_range[1], h_boundary->ref_temperature); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "emissivity"); - res = cstr_to_double(tk, &h_boundary->emissivity); + CHK_ARG(idx, "emissivity"); + res = cstr_to_double(arg, &h_boundary->emissivity); if(res != RES_OK || h_boundary->emissivity < 0 || h_boundary->emissivity > 1) { - logger_print(stardis->logger, LOG_ERROR, "Invalid emissivity: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid emissivity: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "specular fraction"); - res = cstr_to_double(tk, &h_boundary->specular_fraction); + CHK_ARG(idx, "specular fraction"); + res = cstr_to_double(arg, &h_boundary->specular_fraction); if(res != RES_OK || h_boundary->specular_fraction < 0 || h_boundary->specular_fraction > 1) { logger_print(stardis->logger, LOG_ERROR, - "Invalid specular fraction: %s\n", tk); + "Invalid specular fraction: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "Convection coefficient"); - res = cstr_to_double(tk, &h_boundary->hc); + CHK_ARG(idx, "Convection coefficient"); + res = cstr_to_double(arg, &h_boundary->hc); if(res != RES_OK || h_boundary->hc < 0) { logger_print(stardis->logger, LOG_ERROR, - "Invalid Convection coefficient: %s\n", tk); + "Invalid Convection coefficient: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "temperature"); - res = cstr_to_double(tk, &h_boundary->imposed_temperature); + CHK_ARG(idx, "temperature"); + res = cstr_to_double(arg, &h_boundary->imposed_temperature); if(res != RES_OK || h_boundary->imposed_temperature < 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid temperature: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } @@ -451,7 +455,7 @@ process_h } ASSERT(sz <= UINT_MAX); - ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx)); end: return res; @@ -460,13 +464,46 @@ error: } static res_T -set_stripped_args - (struct str* str, - const char* args) +set_argc_argv + (struct mem_allocator* allocator, + size_t* argc, + char** argv[], + const wordexp_t* pwordexp, + size_t idx) { - const char whitespace[] = " \f\n\r\t\v"; - ASSERT(str && args); - return str_set(str, args + strspn(args, whitespace)); + size_t i, n; + res_T res = RES_OK; + + ASSERT(argc && argv && pwordexp); + *argv = NULL; + + if(pwordexp->we_wordc < idx) { + res = RES_BAD_ARG; + goto error; + } + *argc = pwordexp->we_wordc - idx; + *argv = MEM_CALLOC(allocator, 1 + *argc, sizeof(char *)); + if(*argv == NULL) { + res = RES_MEM_ERR; + goto error; + } + for(i = idx, n = 0; i < pwordexp->we_wordc; i++, n++) { + (*argv)[n] = MEM_CALLOC(allocator, 1, 1 + strlen(pwordexp->we_wordv[i])); + if((*argv)[n] == NULL) { + res = RES_MEM_ERR; + goto error; + } + strcpy((*argv)[n], pwordexp->we_wordv[i]); /* size is adequate */ + } +end: + return res; +error: + if(*argv) { + for(i = 0; i < *argc; i++) + if((*argv)[i]) MEM_RM(allocator, (*argv)[i]); + MEM_RM(allocator, *argv); + } + goto end; } /* utility macros */ @@ -483,8 +520,6 @@ set_stripped_args GET_LIB_SYMBOL_BASE(&((Dest)->Field), (Dest)->program->lib_handle, FunName, 0) #define CREATE_DESC_DATA_BASE(Desc, CreateArgs) \ - /* duplicate args to allow to modify them */ \ - ERR(str_copy(&tmp, &(Desc)->args)); \ (Desc)->prog_data = (Desc)->create(&ctx, CreateArgs); \ if(!(Desc)->prog_data) { \ logger_print(stardis->logger, LOG_ERROR, \ @@ -494,7 +529,8 @@ set_stripped_args } #define CREATE_DESC_DATA(Desc) \ - CREATE_DESC_DATA_BASE(Desc, LIST_ARG2((Desc)->program->prog_data, str_get(&tmp))) + CREATE_DESC_DATA_BASE(Desc, \ + LIST_ARG3((Desc)->program->prog_data, (Desc)->argc, (Desc)->argv)) /* The returned program is NULL if no stardis_create_program function is * defined in the library. */ @@ -504,7 +540,7 @@ get_prog_common struct stardis* stardis, struct program** program, void* (**create) - (const struct stardis_description_create_context*, void*, char*), + (const struct stardis_description_create_context*, void*, size_t, char**), void (**release)(void*)) { res_T res = RES_OK; @@ -545,21 +581,20 @@ error: static res_T process_program (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; size_t sz; struct program* program; const char* lib_name; - struct str tmp; const char* lic; const char* _c_; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); - str_init(stardis->allocator, &tmp); sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; @@ -567,24 +602,24 @@ process_program program = desc->d.program; desc->type = DESC_PROGRAM; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); - ERR(description_set_name(stardis, &program->name, tk)); + CHK_ARG(idx, "program name"); + ERR(description_set_name(stardis, &program->name, arg)); if(find_description_by_name(stardis, &program->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - lib_name = tk; + lib_name = arg; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "library path"); - ERR(str_set(&program->lib_path, tk)); + CHK_ARG(idx, "library path"); + ERR(str_set(&program->lib_path, arg)); /* get the library handler */ - program->lib_handle = library_open(tk); + program->lib_handle = library_open(arg); if(!program->lib_handle) { logger_print(stardis->logger, LOG_ERROR, - "Cannot open library: %s (%s)\n", lib_name, tk); + "Cannot open library: %s (%s)\n", lib_name, arg); res = RES_BAD_ARG; goto error; } @@ -617,7 +652,8 @@ process_program } /* store the end of line as args for custom init */ - ERR(set_stripped_args(&program->args, *tok_ctx)); + ERR(set_argc_argv(stardis->allocator, &program->argc, &program->argv, + pwordexp, idx)); if(program->create) { /* create and init custom data */ struct stardis_program_context ctx; @@ -630,11 +666,14 @@ process_program default: FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); } - CREATE_DESC_DATA_BASE(program, LIST_ARG1(str_get(&tmp))); - } else if(!str_is_empty(&program->args)) { + CREATE_DESC_DATA_BASE(program, LIST_ARG2(program->argc, program->argv)); + } else if(program->argc != 0) { logger_print(stardis->logger, LOG_ERROR, - "Library '%s' has no custom data management functions but has arguments.\n", + "Library '%s' has no custom data management functions but has arguments:\n", lib_name); + for( ; idx < pwordexp->we_wordc; idx++) { + logger_print(stardis->logger, LOG_ERROR, "%s\n", pwordexp->we_wordv[idx]); + } res = RES_BAD_ARG; goto error; } @@ -656,7 +695,6 @@ process_program logger_print(stardis->logger, LOG_OUTPUT, " %s\n", lic); end: - str_release(&tmp); return res; error: goto end; @@ -668,22 +706,21 @@ static res_T process_h_prog (struct stardis* stardis, const enum description_type type, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; - struct str tmp; size_t sz; struct h_boundary_prog* h_boundary_prog; struct stardis_description_create_context ctx; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.fmed_count++; - str_init(stardis->allocator, &tmp); sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; @@ -691,25 +728,26 @@ process_h_prog h_boundary_prog = desc->d.h_boundary_prog; desc->type = type; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed h boundary name"); - ERR(description_set_name(stardis, &h_boundary_prog->name, tk)); + CHK_ARG(idx, "programmed h boundary name"); + ERR(description_set_name(stardis, &h_boundary_prog->name, arg)); if(find_description_by_name(stardis, &h_boundary_prog->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - desc_name = tk; + desc_name = arg; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); - ERR(str_set(&h_boundary_prog->prog_name, tk)); - lib_name = tk; + CHK_ARG(idx, "program name"); + ERR(str_set(&h_boundary_prog->prog_name, arg)); + lib_name = arg; ASSERT(sz <= UINT_MAX); - ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx)); /* store the end of line as args for custom init */ - ERR(set_stripped_args(&h_boundary_prog->args, *tok_ctx)); + ERR(set_argc_argv(stardis->allocator, &h_boundary_prog->argc, + &h_boundary_prog->argv, pwordexp, idx)); /* get the user-defined functions from the library */ ERR(get_prog_common(lib_name, stardis, &h_boundary_prog->program, &h_boundary_prog->create, &h_boundary_prog->release)); @@ -752,7 +790,6 @@ process_h_prog } end: - str_release(&tmp); return res; error: goto end; @@ -762,15 +799,16 @@ error: static res_T process_t (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; size_t sz; struct t_boundary* t_boundary; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.tbound_count++; @@ -783,21 +821,22 @@ process_t ERR(get_dummy_fluid_id(stardis, &t_boundary->mat_id)); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "temperature boundary name"); - ERR(description_set_name(stardis, &t_boundary->name, tk)); + + CHK_ARG(idx, "temperature boundary name"); + ERR(description_set_name(stardis, &t_boundary->name, arg)); if(find_description_by_name(stardis, &t_boundary->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "temperature"); - res = cstr_to_double(tk, &t_boundary->imposed_temperature); + CHK_ARG(idx, "temperature"); + res = cstr_to_double(arg, &t_boundary->imposed_temperature); if(res != RES_OK || t_boundary->imposed_temperature < 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid temperature: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } @@ -805,7 +844,7 @@ process_t stardis->t_range[1] = MMAX(stardis->t_range[1], t_boundary->imposed_temperature); ASSERT(sz <= UINT_MAX); - ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx)); end: return res; @@ -817,22 +856,21 @@ error: static res_T process_t_prog (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; - struct str tmp; size_t sz; struct t_boundary_prog* t_boundary_prog; struct stardis_description_create_context ctx; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.fmed_count++; - str_init(stardis->allocator, &tmp); sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; @@ -842,25 +880,26 @@ process_t_prog ERR(get_dummy_fluid_id(stardis, &t_boundary_prog->mat_id)); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed t boundary name"); - ERR(description_set_name(stardis, &t_boundary_prog->name, tk)); + CHK_ARG(idx, "programmed t boundary name"); + ERR(description_set_name(stardis, &t_boundary_prog->name, arg)); if(find_description_by_name(stardis, &t_boundary_prog->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - desc_name = tk; + desc_name = arg; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); - ERR(str_set(&t_boundary_prog->prog_name, tk)); - lib_name = tk; + CHK_ARG(idx, "program name"); + ERR(str_set(&t_boundary_prog->prog_name, arg)); + lib_name = arg; ASSERT(sz <= UINT_MAX); - ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx)); /* store the end of line as args for custom init */ - ERR(set_stripped_args(&t_boundary_prog->args, *tok_ctx)); + ERR(set_argc_argv(stardis->allocator, &t_boundary_prog->argc, + &t_boundary_prog->argv, pwordexp, idx)); /* get the user-defined functions from the library */ ERR(get_prog_common(lib_name, stardis, &t_boundary_prog->program, &t_boundary_prog->create, &t_boundary_prog->release)); @@ -873,7 +912,6 @@ process_t_prog t_boundary_prog->t_range(t_boundary_prog->prog_data, stardis->t_range); end: - str_release(&tmp); return res; error: goto end; @@ -883,15 +921,16 @@ error: static res_T process_flx (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; size_t sz; struct f_boundary* f_boundary; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.fbound_count++; @@ -904,22 +943,22 @@ process_flx ERR(get_dummy_fluid_id(stardis, &f_boundary->mat_id)); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "flux boundary name"); - ERR(description_set_name(stardis, &f_boundary->name, tk)); + CHK_ARG(idx, "flux boundary name"); + ERR(description_set_name(stardis, &f_boundary->name, arg)); if(find_description_by_name(stardis, &f_boundary->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "flux"); - res = cstr_to_double(tk, &f_boundary->imposed_flux); + CHK_ARG(idx, "flux"); + res = cstr_to_double(arg, &f_boundary->imposed_flux); if(res != RES_OK || f_boundary->imposed_flux == SDIS_FLUX_NONE) { /* Flux can be < 0 but not undefined */ if(res == RES_OK) res = RES_BAD_ARG; - logger_print(stardis->logger, LOG_ERROR, "Invalid flux: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid flux: %s\n", arg); goto end; } if(f_boundary->imposed_flux != 0 && stardis->picard_order > 1) { @@ -932,7 +971,7 @@ process_flx } ASSERT(sz <= UINT_MAX); - ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx)); end: return res; @@ -944,22 +983,21 @@ error: static res_T process_flx_prog (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; - struct str tmp; size_t sz; struct f_boundary_prog* f_boundary_prog; struct stardis_description_create_context ctx; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.fmed_count++; - str_init(stardis->allocator, &tmp); sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; @@ -969,26 +1007,27 @@ process_flx_prog ERR(get_dummy_fluid_id(stardis, &f_boundary_prog->mat_id)); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed t boundary name"); - ERR(description_set_name(stardis, &f_boundary_prog->name, tk)); + CHK_ARG(idx, "programmed t boundary name"); + ERR(description_set_name(stardis, &f_boundary_prog->name, arg)); if(find_description_by_name(stardis, &f_boundary_prog->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); - ERR(str_set(&f_boundary_prog->prog_name, tk)); - desc_name = tk; - desc_name = tk; - lib_name = tk; + CHK_ARG(idx, "program name"); + ERR(str_set(&f_boundary_prog->prog_name, arg)); + desc_name = arg; + desc_name = arg; + lib_name = arg; ASSERT(sz <= UINT_MAX); - ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx)); /* store the end of line as args for custom init */ - ERR(set_stripped_args(&f_boundary_prog->args, *tok_ctx)); + ERR(set_argc_argv(stardis->allocator, &f_boundary_prog->argc, + &f_boundary_prog->argv, pwordexp, idx)); /* get the user-defined functions from the library */ ERR(get_prog_common(lib_name, stardis, &f_boundary_prog->program, &f_boundary_prog->create, &f_boundary_prog->release)); @@ -998,7 +1037,6 @@ process_flx_prog CREATE_DESC_DATA(f_boundary_prog); end: - str_release(&tmp); return res; error: goto end; @@ -1008,15 +1046,16 @@ error: static res_T process_sfc (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; size_t sz; struct solid_fluid_connect* sf_connect; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.sfconnect_count++; @@ -1032,60 +1071,61 @@ process_sfc * we continue the trend to ensure connection ID is OK */ sf_connect->connection_id = allocate_stardis_medium_id(stardis); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid-fluid connection name"); - ERR(description_set_name(stardis, &sf_connect->name, tk)); + CHK_ARG(idx, "solid-fluid connection name"); + ERR(description_set_name(stardis, &sf_connect->name, arg)); if(find_description_by_name(stardis, &sf_connect->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "ref_temperature"); - res = cstr_to_double(tk, &sf_connect->ref_temperature); + CHK_ARG(idx, "ref_temperature"); + res = cstr_to_double(arg, &sf_connect->ref_temperature); if(res != RES_OK || sf_connect->ref_temperature < 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid reference temperature: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, + "Invalid reference temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } stardis->t_range[0] = MMIN(stardis->t_range[0], sf_connect->ref_temperature); stardis->t_range[1] = MMAX(stardis->t_range[1], sf_connect->ref_temperature); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "emissivity"); - res = cstr_to_double(tk, &sf_connect->emissivity); + CHK_ARG(idx, "emissivity"); + res = cstr_to_double(arg, &sf_connect->emissivity); if(res != RES_OK || sf_connect->emissivity < 0 || sf_connect->emissivity > 1) { - logger_print(stardis->logger, LOG_ERROR, "Invalid emissivity: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid emissivity: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "specular fraction"); - res = cstr_to_double(tk, &sf_connect->specular_fraction); + CHK_ARG(idx, "specular fraction"); + res = cstr_to_double(arg, &sf_connect->specular_fraction); if(res != RES_OK || sf_connect->specular_fraction < 0 || sf_connect->specular_fraction > 1) { logger_print(stardis->logger, LOG_ERROR, - "Invalid specular fraction: %s\n", tk); + "Invalid specular fraction: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "Convection coefficient"); - res = cstr_to_double(tk, &sf_connect->hc); + CHK_ARG(idx, "Convection coefficient"); + res = cstr_to_double(arg, &sf_connect->hc); if(res != RES_OK || sf_connect->hc < 0) { logger_print(stardis->logger, LOG_ERROR, - "Invalid Convection coefficient: %s\n", tk); + "Invalid Convection coefficient: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } ASSERT(sz <= UINT_MAX); - ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx)); end: return res; @@ -1097,22 +1137,21 @@ error: static res_T process_sfc_prog (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; - struct str tmp; size_t sz; struct solid_fluid_connect_prog* sf_connect_prog; struct stardis_description_create_context ctx; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.sfconnect_count++; - str_init(stardis->allocator, &tmp); sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; @@ -1120,26 +1159,26 @@ process_sfc_prog sf_connect_prog = desc->d.sf_connect_prog; desc->type = DESC_SOLID_FLUID_CONNECT_PROG; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), - "programmed solid-fluid connection name"); - ERR(description_set_name(stardis, &sf_connect_prog->name, tk)); + CHK_ARG(idx, "programmed solid-fluid connection name"); + ERR(description_set_name(stardis, &sf_connect_prog->name, arg)); if(find_description_by_name(stardis, &sf_connect_prog->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - desc_name = tk; + desc_name = arg; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); - ERR(str_set(&sf_connect_prog->prog_name, tk)); - lib_name = tk; + CHK_ARG(idx, "program name"); + ERR(str_set(&sf_connect_prog->prog_name, arg)); + lib_name = arg; ASSERT(sz <= UINT_MAX); - ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx)); /* store the end of line as args for custom init */ - ERR(set_stripped_args(&sf_connect_prog->args, *tok_ctx)); + ERR(set_argc_argv(stardis->allocator, &sf_connect_prog->argc, + &sf_connect_prog->argv, pwordexp, idx)); /* get the user-defined functions from the library */ ERR(get_prog_common(lib_name, stardis, &sf_connect_prog->program, &sf_connect_prog->create, &sf_connect_prog->release)); @@ -1156,7 +1195,6 @@ process_sfc_prog sf_connect_prog->t_range(sf_connect_prog->prog_data, stardis->t_range); end: - str_release(&tmp); return res; error: goto end; @@ -1166,15 +1204,16 @@ error: static res_T process_ssc (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; size_t sz; struct solid_solid_connect* ss_connect; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.ssconnect_count++; @@ -1190,22 +1229,22 @@ process_ssc * we continue the trend to ensure connection ID is OK */ ss_connect->connection_id = allocate_stardis_medium_id(stardis); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid-solid connection name"); - ERR(description_set_name(stardis, &ss_connect->name, tk)); + CHK_ARG(idx, "solid-solid connection name"); + ERR(description_set_name(stardis, &ss_connect->name, arg)); if(find_description_by_name(stardis, &ss_connect->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "contact resistance"); - res = cstr_to_double(tk, &ss_connect->tcr); + CHK_ARG(idx, "contact resistance"); + res = cstr_to_double(arg, &ss_connect->tcr); if(res != RES_OK || ss_connect->tcr < 0) { logger_print(stardis->logger, LOG_ERROR, - "Invalid contact resistance: %s\n", tk); + "Invalid contact resistance: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } @@ -1216,7 +1255,7 @@ process_ssc } ASSERT(sz <= UINT_MAX); - ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx)); end: return res; @@ -1228,22 +1267,21 @@ error: static res_T process_ssc_prog (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; - struct str tmp; size_t sz; struct solid_solid_connect_prog* ss_connect_prog; struct stardis_description_create_context ctx; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.sfconnect_count++; - str_init(stardis->allocator, &tmp); sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; @@ -1251,33 +1289,34 @@ process_ssc_prog ss_connect_prog = desc->d.ss_connect_prog; desc->type = DESC_SOLID_SOLID_CONNECT_PROG; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), - "programmed solid-solid connection name"); - ERR(description_set_name(stardis, &ss_connect_prog->name, tk)); + CHK_ARG(idx, "programmed solid-solid connection name"); + ERR(description_set_name(stardis, &ss_connect_prog->name, arg)); if(find_description_by_name(stardis, &ss_connect_prog->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - desc_name = tk; + desc_name = arg; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); - ERR(str_set(&ss_connect_prog->prog_name, tk)); - lib_name = tk; + CHK_ARG(idx, "program name"); + ERR(str_set(&ss_connect_prog->prog_name, arg)); + lib_name = arg; ASSERT(sz <= UINT_MAX); - ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx)); /* store the end of line as args for custom init */ - ERR(set_stripped_args(&ss_connect_prog->args, *tok_ctx)); + ERR(set_argc_argv(stardis->allocator, &ss_connect_prog->argc, + &ss_connect_prog->argv, pwordexp, idx)); /* get the user-defined functions from the library */ ERR(get_prog_common(lib_name, stardis, &ss_connect_prog->program, &ss_connect_prog->create, &ss_connect_prog->release)); GET_LIB_SYMBOL(ss_connect_prog, tcr, stardis_thermal_contact_resistance); if(!ss_connect_prog->tcr) { logger_print(stardis->logger, LOG_ERROR, - "Cannot find function 'stardis_thermal_contact_resistance()' in lib %s\n", lib_name); + "Cannot find function 'stardis_thermal_contact_resistance()' in lib %s\n", + lib_name); res = RES_BAD_ARG; goto error; } @@ -1295,17 +1334,18 @@ static res_T read_imposed_temperature (struct stardis* stardis, double* imposed_temperature, - char** tok_ctx) + wordexp_t* pwordexp, + size_t* idx) { - char* tk = NULL; + char* arg = NULL; struct str keep; res_T res = RES_OK; - ASSERT(stardis && imposed_temperature && tok_ctx); + ASSERT(stardis && imposed_temperature && pwordexp); str_init(stardis->allocator, &keep); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "imposed temperature"); - ERR(str_set(&keep, tk)); - if(RES_OK == cstr_to_double(tk, imposed_temperature)) { + CHK_ARG((*idx), "imposed temperature"); + ERR(str_set(&keep, arg)); + if(RES_OK == cstr_to_double(arg, imposed_temperature)) { /* Was a number */ if(*imposed_temperature < 0) { res = RES_BAD_ARG; @@ -1313,7 +1353,7 @@ read_imposed_temperature } } else { /* Could be 'unknown' */ - if(0 == strcasecmp(tk, "UNKNOWN")) { + if(0 == strcasecmp(arg, "UNKNOWN")) { *imposed_temperature = UNKNOWN_MEDIUM_TEMPERATURE; } else { res = RES_BAD_ARG; @@ -1333,17 +1373,15 @@ static res_T read_delta (struct stardis* stardis, double* delta, - char** tok_ctx) + wordexp_t* pwordexp, + size_t* idx) { - char* tk = NULL; - struct str keep; + char* arg = NULL; res_T res = RES_OK; - ASSERT(stardis && delta && tok_ctx); + ASSERT(stardis && delta && pwordexp && idx); - str_init(stardis->allocator, &keep); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "delta"); - ERR(str_set(&keep, tk)); - if(RES_OK == cstr_to_double(tk, delta)) { + CHK_ARG((*idx), "delta"); + if(RES_OK == cstr_to_double(arg, delta)) { /* Was a number */ if(*delta <= 0) { res = RES_BAD_ARG; @@ -1351,7 +1389,7 @@ read_delta } } else { /* Could be 'auto' */ - if(0 == strcasecmp(tk, "AUTO")) { + if(0 == strcasecmp(arg, "AUTO")) { /* Set to DELTA_AUTO until actual value is substituted */ *delta = DELTA_AUTO; } else { @@ -1360,11 +1398,9 @@ read_delta } } end: - str_release(&keep); return res; error: - logger_print(stardis->logger, LOG_ERROR, "Invalid delta: %s\n", - str_cget(&keep)); + logger_print(stardis->logger, LOG_ERROR, "Invalid delta: %s\n", arg); goto end; } @@ -1372,15 +1408,16 @@ error: static res_T process_solid (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; size_t sz; struct solid* solid; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.smed_count++; @@ -1396,56 +1433,56 @@ process_solid ASSERT(sz <= UINT_MAX); solid->desc_id = (unsigned)sz; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid name"); - ERR(description_set_name(stardis, &solid->name, tk)); + CHK_ARG(idx, "solid name"); + ERR(description_set_name(stardis, &solid->name, arg)); if(find_description_by_name(stardis, &solid->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "lambda"); - res = cstr_to_double(tk, &solid->lambda); + CHK_ARG(idx, "lambda"); + res = cstr_to_double(arg, &solid->lambda); if(res != RES_OK || solid->lambda <= 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid lambda: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid lambda: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "rho"); - res = cstr_to_double(tk, &solid->rho); + CHK_ARG(idx, "rho"); + res = cstr_to_double(arg, &solid->rho); if(res != RES_OK || solid->rho <= 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid rho: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid rho: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "cp"); - res = cstr_to_double(tk, &solid->cp); + CHK_ARG(idx, "cp"); + res = cstr_to_double(arg, &solid->cp); if(res != RES_OK || solid->cp <= 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid cp: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid cp: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - ERR(read_delta(stardis, &solid->delta, tok_ctx)); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "Tinit"); - res = cstr_to_double(tk, &solid->tinit); + ERR(read_delta(stardis, &solid->delta, pwordexp, &idx)); + CHK_ARG(idx, "Tinit"); + res = cstr_to_double(arg, &solid->tinit); if(res != RES_OK || solid->tinit < 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid Tinit: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid Tinit: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } stardis->t_range[0] = MMIN(stardis->t_range[0], solid->tinit); stardis->t_range[1] = MMAX(stardis->t_range[1], solid->tinit); ERR(read_imposed_temperature(stardis, &solid->imposed_temperature, - tok_ctx)); + pwordexp, &idx)); if(solid->imposed_temperature >= 0 && solid->imposed_temperature != solid->tinit) { @@ -1459,11 +1496,11 @@ process_solid if(solid->imposed_temperature >= 0) stardis->t_range[0] = MMIN(stardis->t_range[0], solid->imposed_temperature); stardis->t_range[1] = MMAX(stardis->t_range[1], solid->imposed_temperature); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "volumic power"); - res = cstr_to_double(tk, &solid->vpower); + CHK_ARG(idx, "volumic power"); + res = cstr_to_double(arg, &solid->vpower); if(res != RES_OK) { /* VPower can be < 0 */ - logger_print(stardis->logger, LOG_ERROR, "Invalid volumic power: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid volumic power: %s\n", arg); goto end; } if(solid->vpower != 0 && stardis->picard_order > 1) { @@ -1478,7 +1515,7 @@ process_solid /* Actual solid creation is defered until geometry is read to allow * enclosure shape VS delta analysis (and auto delta computation) */ - ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 0, (unsigned)sz, pwordexp, &idx)); end: return res; @@ -1490,22 +1527,21 @@ error: static res_T process_solid_prog (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; - struct str tmp; size_t sz; struct solid_prog* solid_prog; struct stardis_description_create_context ctx; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.fmed_count++; - str_init(stardis->allocator, &tmp); sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; @@ -1516,24 +1552,25 @@ process_solid_prog ASSERT(sz <= UINT_MAX); solid_prog->desc_id = (unsigned)sz; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed solid name"); - ERR(description_set_name(stardis, &solid_prog->name, tk)); + CHK_ARG(idx, "programmed solid name"); + ERR(description_set_name(stardis, &solid_prog->name, arg)); if(find_description_by_name(stardis, &solid_prog->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - desc_name = tk; + desc_name = arg; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); - ERR(str_set(&solid_prog->prog_name, tk)); - lib_name = tk; + CHK_ARG(idx, "program name"); + ERR(str_set(&solid_prog->prog_name, arg)); + lib_name = arg; - ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 0, (unsigned)sz, pwordexp, &idx)); /* store the end of line as args for custom init */ - ERR(set_stripped_args(&solid_prog->args, *tok_ctx)); + ERR(set_argc_argv(stardis->allocator, &solid_prog->argc, &solid_prog->argv, + pwordexp, idx)); /* get the user-defined functions from the library */ ERR(get_prog_common(lib_name, stardis, &solid_prog->program, &solid_prog->create, &solid_prog->release)); @@ -1553,7 +1590,6 @@ process_solid_prog ERR(create_solver_solid_prog(stardis, solid_prog)); end: - str_release(&tmp); return res; error: goto end; @@ -1563,15 +1599,16 @@ error: static res_T process_fluid (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; size_t sz; struct fluid* fluid; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.fmed_count++; @@ -1586,46 +1623,46 @@ process_fluid ASSERT(sz <= UINT_MAX); fluid->desc_id = (unsigned)sz; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "fluid name"); - ERR(description_set_name(stardis, &fluid->name, tk)); + CHK_ARG(idx, "fluid name"); + ERR(description_set_name(stardis, &fluid->name, arg)); if(find_description_by_name(stardis, &fluid->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "rho"); - res = cstr_to_double(tk, &fluid->rho); + CHK_ARG(idx, "rho"); + res = cstr_to_double(arg, &fluid->rho); if(res != RES_OK || fluid->rho <= 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid rho: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid rho: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "cp"); - res = cstr_to_double(tk, &fluid->cp); + CHK_ARG(idx, "cp"); + res = cstr_to_double(arg, &fluid->cp); if(res != RES_OK || fluid->cp <= 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid cp: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid cp: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "Tinit"); - res = cstr_to_double(tk, &fluid->tinit); + CHK_ARG(idx, "Tinit"); + res = cstr_to_double(arg, &fluid->tinit); if(res != RES_OK || fluid->tinit < 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid Tinit: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, "Invalid Tinit: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } stardis->t_range[0] = MMIN(stardis->t_range[0], fluid->tinit); stardis->t_range[1] = MMAX(stardis->t_range[1], fluid->tinit); ERR(read_imposed_temperature(stardis, &fluid->imposed_temperature, - tok_ctx)); + pwordexp, &idx)); if(fluid->imposed_temperature >= 0 && fluid->imposed_temperature != fluid->tinit) { @@ -1642,7 +1679,7 @@ process_fluid ERR(create_solver_fluid(stardis, fluid)); - ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 0, (unsigned)sz, pwordexp, &idx)); end: return res; @@ -1654,22 +1691,21 @@ error: static res_T process_fluid_prog (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; - struct str tmp; size_t sz; struct fluid_prog* fluid_prog; struct stardis_description_create_context ctx; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); stardis->counts.fmed_count++; - str_init(stardis->allocator, &tmp); sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; @@ -1680,24 +1716,25 @@ process_fluid_prog ASSERT(sz <= UINT_MAX); fluid_prog->desc_id = (unsigned)sz; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed fluid name"); - ERR(description_set_name(stardis, &fluid_prog->name, tk)); + CHK_ARG(idx, "programmed fluid name"); + ERR(description_set_name(stardis, &fluid_prog->name, arg)); if(find_description_by_name(stardis, &fluid_prog->name, desc)) { logger_print(stardis->logger, LOG_ERROR, - "Name already used: %s\n", tk); + "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - desc_name = tk; + desc_name = arg; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); - ERR(str_set(&fluid_prog->prog_name, tk)); - lib_name = tk; + CHK_ARG(idx, "program name"); + ERR(str_set(&fluid_prog->prog_name, arg)); + lib_name = arg; - ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx)); + ERR(read_sides_and_files(stardis, 0, (unsigned)sz, pwordexp, &idx)); /* store the end of line as args for custom init */ - ERR(set_stripped_args(&fluid_prog->args, *tok_ctx)); + ERR(set_argc_argv(stardis->allocator, &fluid_prog->argc, &fluid_prog->argv, + pwordexp, idx)); /* get the user-defined functions from the library */ ERR(get_prog_common(lib_name, stardis, &fluid_prog->program, &fluid_prog->create, &fluid_prog->release)); @@ -1714,7 +1751,6 @@ process_fluid_prog ERR(create_solver_fluid_prog(stardis, fluid_prog)); end: - str_release(&tmp); return res; error: goto end; @@ -1724,12 +1760,13 @@ error: static res_T process_scale (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); if(stardis->scale_factor > 0) { logger_print(stardis->logger, LOG_ERROR, @@ -1737,13 +1774,13 @@ process_scale res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "scale factor"); - res = cstr_to_double(tk, &stardis->scale_factor); + CHK_ARG(idx, "scale factor"); + res = cstr_to_double(arg, &stardis->scale_factor); if(res != RES_OK || stardis->scale_factor <= 0) { logger_print(stardis->logger, LOG_ERROR, - "Invalid scale factor: %s\n", tk); + "Invalid scale factor: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } @@ -1758,12 +1795,13 @@ error: static res_T process_radiative (struct stardis* stardis, - char** tok_ctx) + wordexp_t* pwordexp) { - char* tk = NULL; + char* arg = NULL; + size_t idx = 1; res_T res = RES_OK; - ASSERT(stardis && tok_ctx); + ASSERT(stardis && pwordexp); if(stardis->trad_def) { logger_print(stardis->logger, LOG_ERROR, @@ -1771,23 +1809,23 @@ process_radiative res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "Trad"); - res = cstr_to_double(tk, &stardis->trad); + CHK_ARG(idx, "Trad"); + res = cstr_to_double(arg, &stardis->trad); if(res != RES_OK || stardis->trad < 0) { logger_print(stardis->logger, LOG_ERROR, - "Invalid Trad: %s\n", tk); + "Invalid Trad: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "Trad reference"); - res = cstr_to_double(tk, &stardis->trad_ref); + CHK_ARG(idx, "Trad reference"); + res = cstr_to_double(arg, &stardis->trad_ref); if(res != RES_OK || stardis->trad_ref < 0) { logger_print(stardis->logger, LOG_ERROR, - "Invalid Trad reference: %s\n", tk); + "Invalid Trad reference: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } @@ -1826,71 +1864,69 @@ error: static res_T process_model_line (const char* file_name, - char* line, + const char* line, + wordexp_t *pwordexp, struct stardis* stardis) { res_T res = RES_OK; - struct str keep; - char* tk = NULL, * tok_ctx = NULL; + char* arg = NULL; + size_t idx = 0; - ASSERT(file_name && line && stardis); + ASSERT(file_name && line && pwordexp && stardis); - str_init(stardis->allocator, &keep); - ERR(str_set(&keep, line)); - CHK_TOK(strtok_r(line, " \t", &tok_ctx), "model line type"); + CHK_ARG(idx, "model line type"); - if(0 == strcasecmp(tk, "H_BOUNDARY_FOR_SOLID")) - ERR(process_h(stardis, DESC_BOUND_H_FOR_SOLID, &tok_ctx)); - else if(0 == strcasecmp(tk, "H_BOUNDARY_FOR_SOLID_PROG")) - ERR(process_h_prog(stardis, DESC_BOUND_H_FOR_SOLID_PROG, &tok_ctx)); - else if(0 == strcasecmp(tk, "H_BOUNDARY_FOR_FLUID")) - ERR(process_h(stardis, DESC_BOUND_H_FOR_FLUID, &tok_ctx)); - else if(0 == strcasecmp(tk, "H_BOUNDARY_FOR_FLUID_PROG")) - ERR(process_h_prog(stardis, DESC_BOUND_H_FOR_FLUID_PROG, &tok_ctx)); - else if(0 == strcasecmp(tk, "T_BOUNDARY_FOR_SOLID")) - ERR(process_t(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "T_BOUNDARY_FOR_SOLID_PROG")) - ERR(process_t_prog(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "F_BOUNDARY_FOR_SOLID")) - ERR(process_flx(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "F_BOUNDARY_FOR_SOLID_PROG")) - ERR(process_flx_prog(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "SOLID_FLUID_CONNECTION")) - ERR(process_sfc(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "SOLID_FLUID_CONNECTION_PROG")) - ERR(process_sfc_prog(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "SOLID_SOLID_CONNECTION")) - ERR(process_ssc(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "SOLID_SOLID_CONNECTION_PROG")) - ERR(process_ssc_prog(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "SOLID")) - ERR(process_solid(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "SOLID_PROG")) - ERR(process_solid_prog(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "FLUID")) - ERR(process_fluid(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "FLUID_PROG")) - ERR(process_fluid_prog(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "PROGRAM")) - ERR(process_program(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "SCALE")) - ERR(process_scale(stardis, &tok_ctx)); - else if(0 == strcasecmp(tk, "TRAD")) - ERR(process_radiative(stardis, &tok_ctx)); + if(0 == strcasecmp(arg, "H_BOUNDARY_FOR_SOLID")) + ERR(process_h(stardis, DESC_BOUND_H_FOR_SOLID, pwordexp)); + else if(0 == strcasecmp(arg, "H_BOUNDARY_FOR_SOLID_PROG")) + ERR(process_h_prog(stardis, DESC_BOUND_H_FOR_SOLID_PROG, pwordexp)); + else if(0 == strcasecmp(arg, "H_BOUNDARY_FOR_FLUID")) + ERR(process_h(stardis, DESC_BOUND_H_FOR_FLUID, pwordexp)); + else if(0 == strcasecmp(arg, "H_BOUNDARY_FOR_FLUID_PROG")) + ERR(process_h_prog(stardis, DESC_BOUND_H_FOR_FLUID_PROG, pwordexp)); + else if(0 == strcasecmp(arg, "T_BOUNDARY_FOR_SOLID")) + ERR(process_t(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "T_BOUNDARY_FOR_SOLID_PROG")) + ERR(process_t_prog(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "F_BOUNDARY_FOR_SOLID")) + ERR(process_flx(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "F_BOUNDARY_FOR_SOLID_PROG")) + ERR(process_flx_prog(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "SOLID_FLUID_CONNECTION")) + ERR(process_sfc(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "SOLID_FLUID_CONNECTION_PROG")) + ERR(process_sfc_prog(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "SOLID_SOLID_CONNECTION")) + ERR(process_ssc(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "SOLID_SOLID_CONNECTION_PROG")) + ERR(process_ssc_prog(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "SOLID")) + ERR(process_solid(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "SOLID_PROG")) + ERR(process_solid_prog(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "FLUID")) + ERR(process_fluid(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "FLUID_PROG")) + ERR(process_fluid_prog(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "PROGRAM")) + ERR(process_program(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "SCALE")) + ERR(process_scale(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "TRAD")) + ERR(process_radiative(stardis, pwordexp)); else { logger_print(stardis->logger, LOG_ERROR, - "Unknown description type: %s\n", tk); + "Unknown description type: %s\n", arg); res = RES_BAD_ARG; goto error; } end: - str_release(&keep); return res; error: logger_print(stardis->logger, LOG_ERROR, "Invalid description line in model file '%s':\n", file_name); - logger_print(stardis->logger, LOG_ERROR, "%s\n", str_cget(&keep)); + logger_print(stardis->logger, LOG_ERROR, "%s\n", line); goto end; } @@ -1974,26 +2010,61 @@ read_model size_t i; FILE* f = NULL; struct txtrdr* txtrdr = NULL; + wordexp_t pwordexp; ASSERT(model_files && stardis); files = darray_str_cdata_get(model_files); FOR_EACH(i, 0, darray_str_size_get(model_files)) { const char* name = str_cget(files + i); + int fst = 1; f = fopen(name, "r"); if(!f) { logger_print(stardis->logger, LOG_ERROR, - "Cannot open model file '%s'\n", - name); + "Cannot open model file '%s'\n", name); res = RES_IO_ERR; goto error; } txtrdr_stream(stardis->allocator, f, name, '#', &txtrdr); for(;;) { char* line; + int flags = WRDE_NOCMD | WRDE_UNDEF; + if(!fst) flags |= WRDE_REUSE; ERR(txtrdr_read_line(txtrdr)); line = txtrdr_get_line(txtrdr); if(!line) break; - ERR(process_model_line(name, line, stardis)); + switch(wordexp(line, &pwordexp, flags)) { + case 0: /* No error */ + break; + case WRDE_NOSPACE: /* Ran out of memory. */ + res = RES_MEM_ERR; + goto error; + case WRDE_BADCHAR: /* A metachar appears in the wrong place. */ + logger_print(stardis->logger, LOG_ERROR, + "%s: word expansion error: invalid character:\n", name); + goto exp_error; + case WRDE_BADVAL: /* Undefined var reference with WRDE_UNDEF. */ + logger_print(stardis->logger, LOG_ERROR, + "%s: word expansion error: undefined environment variable:\n", name); + goto exp_error; + case WRDE_CMDSUB: /* Command substitution with WRDE_NOCMD. */ + logger_print(stardis->logger, LOG_ERROR, + "%s: word expansion error: command substitution is not enabled:\n", + name); + goto exp_error; + case WRDE_SYNTAX: /* Shell syntax error. */ + logger_print(stardis->logger, LOG_ERROR, + "%s: word expansion error: syntax error:\n", name); + goto exp_error; + default: + FATAL("Unexpected return code.\n"); + } + ERR(process_model_line(name, line, &pwordexp, stardis)); + fst = 0; + continue; +exp_error: + logger_print(stardis->logger, LOG_ERROR, "%s\n", line); + res = RES_BAD_ARG; + goto error; } txtrdr_ref_put(txtrdr); txtrdr = NULL; @@ -2015,6 +2086,7 @@ read_model ASSERT(!f && !txtrdr); exit: + wordfree(&pwordexp); return res; error: if(f) fclose(f); diff --git a/src/stardis-parsing.h b/src/stardis-parsing.h @@ -27,12 +27,13 @@ struct logger; struct stardis; /* Utility macros */ -#define CHK_TOK(x, Name) if((tk = (x)) == NULL) {\ - logger_print(stardis->logger, LOG_ERROR,\ - "Invalid data (missing token '" Name "')\n");\ - res = RES_BAD_ARG;\ - goto error;\ - } (void)0 +#define CHK_ARG(Idx, Name) \ + if(pwordexp->we_wordc <= (Idx)) {\ + logger_print(stardis->logger, LOG_ERROR,\ + "Invalid data (missing token '" Name "')\n");\ + res = RES_BAD_ARG;\ + goto error;\ + } else arg = pwordexp->we_wordv[(Idx)++] /* Same ctx used for both media and interface add (some unused parts) */ struct add_geom_ctx { diff --git a/src/stardis-prog-properties.h.in b/src/stardis-prog-properties.h.in @@ -24,6 +24,8 @@ /* The version of the API described thereafter */ #define STARDIS_PROG_PROPERTIES_VERSION @STARDIS_PROG_PROPERTIES_VERSION@ +#include <stddef.h> + /*****************************************************************************/ /* API types. */ /* The various functions defining programmed descriptions receive arguments */ @@ -84,7 +86,8 @@ struct stardis_description_create_context { extern void* stardis_create_library_data (const struct stardis_program_context* ctx, - char* args); + size_t argc, + char* argv[]); /* Finalize the data created by the successive stardis_create_data calls for * the descriptions created using this library. @@ -122,7 +125,8 @@ extern void* stardis_create_data (const struct stardis_description_create_context *ctx, void* lib_data, - char* args); + size_t argc, + char* argv[]); /* Release the data created by stardis_create_data. * This function is called after the simulation finished. diff --git a/src/stardis-program.c b/src/stardis-program.c @@ -33,7 +33,8 @@ init_program } str_init(allocator, &(*dst)->name); str_init(allocator, &(*dst)->lib_path); - str_init(allocator, &(*dst)->args); + (*dst)->argc = 0; + (*dst)->argv = NULL; str_initialized = 1; end: return res; @@ -41,7 +42,6 @@ error: if(str_initialized) { str_release(&(*dst)->name); str_release(&(*dst)->lib_path); - str_release(&(*dst)->args); } if(*dst) MEM_RM(allocator, *dst); goto end; @@ -52,15 +52,17 @@ release_program (struct program* program, struct mem_allocator* allocator) { + size_t i; ASSERT(program && allocator); str_release(&program->name); str_release(&program->lib_path); - str_release(&program->args); if(program->prog_data) { ASSERT(program->release); program->release(program->prog_data); } library_close(program->lib_handle); + for(i = 0; i < program->argc; i++) MEM_RM(allocator, program->argv[i]); + MEM_RM(allocator, program->argv); MEM_RM(allocator, program); } @@ -70,7 +72,8 @@ str_print_program const struct program* program) { res_T res = RES_OK; - ERR(str_append_printf(str, "Library %s", str_cget(&program->name))); + ERR(str_append_printf(str, "Library %s, args=[%s]", + str_cget(&program->name), "TODO")); end: return res; diff --git a/src/stardis-program.h b/src/stardis-program.h @@ -31,13 +31,14 @@ struct program { void* prog_data; /* result of the create() call */ struct str name; struct str lib_path; - struct str args; + size_t argc; + char** argv; /* lib handle and function ptrs */ void* lib_handle; const char* (*get_copyright_notice)(void*); const char* (*get_license_short)(void*); const char* (*get_license_text)(void*); - void* (*create)(struct stardis_program_context*, char*); + void* (*create)(struct stardis_program_context*, size_t, char**); enum stardis_return_status (*finalize)(void*); void (*release)(void*); }; diff --git a/src/stardis-sfconnect-prog.c b/src/stardis-sfconnect-prog.c @@ -44,7 +44,6 @@ init_sf_connect_prog } str_init(allocator, &(*dst)->name); str_init(allocator, &(*dst)->prog_name); - str_init(allocator, &(*dst)->args); str_initialized = 1; (*dst)->connection_id = UINT_MAX; end: @@ -53,7 +52,6 @@ error: if(str_initialized) { str_release(&(*dst)->name); str_release(&(*dst)->prog_name); - str_release(&(*dst)->args); } if(*dst) MEM_RM(allocator, *dst); goto end; @@ -64,12 +62,14 @@ release_sf_connect_prog (struct solid_fluid_connect_prog* connect, struct mem_allocator* allocator) { + size_t i; ASSERT(connect && allocator); str_release(&connect->name); str_release(&connect->prog_name); - str_release(&connect->args); if(connect->prog_data) connect->release(connect->prog_data); + for(i = 0; i < connect->argc; i++) MEM_RM(allocator, connect->argv[i]); + MEM_RM(allocator, connect->argv); /* library_close call is managed at lib_data level */ MEM_RM(allocator, connect); } @@ -84,7 +84,7 @@ str_print_sf_connect_prog ERR(str_append_printf(str, "programmed Solid-Fluid connection '%s': lib='%s', args=[%s]", str_cget(&connect->name), str_cget(&connect->prog_name), - str_cget(&connect->args))); + "TODO")); end: return res; error: diff --git a/src/stardis-sfconnect-prog.h b/src/stardis-sfconnect-prog.h @@ -32,14 +32,15 @@ struct solid_fluid_connect_prog { void* prog_data; /* result of the create() call */ struct str name; struct str prog_name; - struct str args; + size_t argc; + char** argv; int is_outside; /* the fluid is used for a boundary */ unsigned desc_id; /* id of the boundary; meaningful if is_outside */ unsigned connection_id; /* lib handle and function ptrs */ struct program* program; void* (*create) - (const struct stardis_description_create_context*, void*, char*); + (const struct stardis_description_create_context*, void*, size_t, char**); void (*release)(void*); double (*ref_temp)(const struct stardis_interface_fragment*, void*); double (*emissivity)(const struct stardis_interface_fragment*, void*); diff --git a/src/stardis-solid-prog.c b/src/stardis-solid-prog.c @@ -152,7 +152,6 @@ init_solid_prog(struct mem_allocator* allocator, struct solid_prog** dst) } str_init(allocator, &(*dst)->name); str_init(allocator, &(*dst)->prog_name); - str_init(allocator, &(*dst)->args); str_initialized = 1; (*dst)->desc_id = UINT_MAX; (*dst)->solid_id = UINT_MAX; @@ -162,7 +161,6 @@ error: if(str_initialized) { str_release(&(*dst)->name); str_release(&(*dst)->prog_name); - str_release(&(*dst)->args); } if(*dst) MEM_RM(allocator, *dst); goto end; @@ -173,13 +171,14 @@ release_solid_prog (struct solid_prog* solid, struct mem_allocator* allocator) { + size_t i; ASSERT(solid && allocator); str_release(&solid->name); str_release(&solid->prog_name); - str_release(&solid->args); - if(solid->prog_data) solid->release(solid->prog_data); + for(i = 0; i < solid->argc; i++) MEM_RM(allocator, solid->argv[i]); + MEM_RM(allocator, solid->argv); /* library_close call is managed at lib_data level */ MEM_RM(allocator, solid); } @@ -191,7 +190,7 @@ str_print_solid_prog(struct str* str, const struct solid_prog* f) ASSERT(str && f); ERR(str_append_printf(str, "programmed solid '%s': lib='%s', args=[%s] (it is medium %u)", - str_cget(&f->name), str_cget(&f->prog_name), str_cget(&f->args), + str_cget(&f->name), str_cget(&f->prog_name), "TODO", f->solid_id)); end: return res; diff --git a/src/stardis-solid-prog.h b/src/stardis-solid-prog.h @@ -32,14 +32,15 @@ struct solid_prog { void* prog_data; /* result of the create() call */ struct str name; struct str prog_name; - struct str args; + size_t argc; + char** argv; int is_outside; /* the solid is used for a boundary */ unsigned desc_id; /* id of the boundary; meaningful if is_outside */ unsigned solid_id; /* lib handle and function ptrs */ struct program* program; void* (*create) - (const struct stardis_description_create_context*, void*, char*); + (const struct stardis_description_create_context*, void*, size_t, char**); void (*release)(void*); double (*lambda)(const struct stardis_vertex*, void*); double (*rho)(const struct stardis_vertex*, void*); diff --git a/src/stardis-ssconnect-prog.c b/src/stardis-ssconnect-prog.c @@ -44,7 +44,6 @@ init_ss_connect_prog } str_init(allocator, &(*dst)->name); str_init(allocator, &(*dst)->prog_name); - str_init(allocator, &(*dst)->args); str_initialized = 1; (*dst)->connection_id = UINT_MAX; end: @@ -53,7 +52,6 @@ error: if(str_initialized) { str_release(&(*dst)->name); str_release(&(*dst)->prog_name); - str_release(&(*dst)->args); } (*dst)->connection_id = UINT_MAX; if(*dst) MEM_RM(allocator, *dst); @@ -65,12 +63,14 @@ release_ss_connect_prog (struct solid_solid_connect_prog* connect, struct mem_allocator* allocator) { + size_t i; ASSERT(connect && allocator); str_release(&connect->name); str_release(&connect->prog_name); - str_release(&connect->args); if(connect->prog_data) connect->release(connect->prog_data); + for(i = 0; i < connect->argc; i++) MEM_RM(allocator, connect->argv[i]); + MEM_RM(allocator, connect->argv); /* library_close call is managed at lib_data level */ MEM_RM(allocator, connect); } @@ -85,7 +85,7 @@ str_print_ss_connect_prog ERR(str_append_printf(str, "programmed Solid-Solid connection '%s': lib='%s', args=[%s]", str_cget(&connect->name), str_cget(&connect->prog_name), - str_cget(&connect->args))); + "TODO")); end: return res; error: diff --git a/src/stardis-ssconnect-prog.h b/src/stardis-ssconnect-prog.h @@ -32,11 +32,12 @@ struct solid_solid_connect_prog { void* prog_data; /* result of the create() call */ struct str name; struct str prog_name; - struct str args; + size_t argc; + char** argv; /* lib handle and function ptrs */ struct program* program; void* (*create) - (const struct stardis_description_create_context*, void*, char*); + (const struct stardis_description_create_context*, void*, size_t, char**); void (*release)(void*); double (*tcr)(const struct stardis_interface_fragment*, void*); unsigned connection_id; diff --git a/src/stardis-tbound-prog.c b/src/stardis-tbound-prog.c @@ -44,7 +44,6 @@ init_t_boundary_prog } str_init(allocator, &(*dst)->name); str_init(allocator, &(*dst)->prog_name); - str_init(allocator, &(*dst)->args); str_initialized = 1; (*dst)->mat_id = UINT_MAX; end: @@ -53,7 +52,6 @@ error: if(str_initialized) { str_release(&(*dst)->name); str_release(&(*dst)->prog_name); - str_release(&(*dst)->args); } if(*dst) MEM_RM(allocator, *dst); goto end; @@ -64,12 +62,14 @@ release_t_boundary_prog (struct t_boundary_prog* bound, struct mem_allocator* allocator) { + size_t i; ASSERT(bound && allocator); str_release(&bound->name); str_release(&bound->prog_name); - str_release(&bound->args); if(bound->prog_data) bound->release(bound->prog_data); + for(i = 0; i < bound->argc; i++) MEM_RM(allocator, bound->argv[i]); + MEM_RM(allocator, bound->argv); /* library_close call is managed at lib_data level */ MEM_RM(allocator, bound); } @@ -84,7 +84,7 @@ str_print_t_boundary_prog ERR(str_append_printf(str, "programmed T boundary for solid '%s': lib='%s', args=[%s] " "(using medium %u as external medium)", - str_cget(&b->name), str_cget(&b->prog_name), str_cget(&b->args), + str_cget(&b->name), str_cget(&b->prog_name), "TODO", b->mat_id)); end: return res; diff --git a/src/stardis-tbound-prog.h b/src/stardis-tbound-prog.h @@ -31,11 +31,12 @@ struct t_boundary_prog { void* prog_data; /* result of the create() call */ struct str name; struct str prog_name; - struct str args; + size_t argc; + char** argv; /* lib handle and function ptrs */ struct program* program; void* (*create) - (const struct stardis_description_create_context*, void*, char*); + (const struct stardis_description_create_context*, void*, size_t, char**); void (*release)(void*); double (*temperature)(const struct stardis_interface_fragment*, void*); double* (*t_range)(void*, double trange[2]);