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 973f9ba27092bdfbc363e172e9d6e7897c31951c
parent 2cf24cf9764cd74f440e40523252f4455bb82eaf
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 16 Dec 2016 10:55:22 +0100

Parse the '-r' (rendering) CLI option

Diffstat:
Msrc/solstice_args.c | 195+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/solstice_args.h | 16+++++++++++++++-
2 files changed, 205 insertions(+), 6 deletions(-)

diff --git a/src/solstice_args.c b/src/solstice_args.c @@ -18,13 +18,17 @@ #include "solstice_args.h" #include <rsys/cstr.h> +#include <rsys/double3.h> #ifdef COMPILER_CL #include <getopt.h> + #define strtok_r strtok_s #else #include <unistd.h> #endif +#include <string.h> + /******************************************************************************* * Helper functions ******************************************************************************/ @@ -39,19 +43,197 @@ print_help(const char* program) } static res_T -parse_rendering(const char* str, struct solstice_args* args) +parse_fov(const char* str, double* out_fov) +{ + double fov; + res_T res = RES_OK; + ASSERT(str && out_fov); + + res = cstr_to_double(str, &fov); + if(res != RES_OK) { + fprintf(stderr, "Invalid field of view `%s'.\n", str); + return RES_BAD_ARG; + } + + if(fov < 30 || fov > 120) { + fprintf(stderr, "The field of view %g is not in [30, 120].\n", fov); + return RES_BAD_ARG; + } + *out_fov = MDEG2RAD(fov); + return RES_OK; +} + + +static res_T +parse_double3(const char* str, double dbl3[3]) +{ + char buf[64]; + char* tk; + char* ctx; + res_T res = RES_OK; + ASSERT(str && dbl3); + + if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) { + fprintf(stderr, + "Could not duplicate the string `%s'.\n", str); + return RES_MEM_ERR; + } + strncpy(buf, str, sizeof(buf)); + + tk = strtok_r(buf, ",", &ctx); + res = cstr_to_double(tk, dbl3+0); + if(res != RES_OK) return res; + + tk = strtok_r(NULL, ",", &ctx); + res = cstr_to_double(tk, dbl3+1); + if(res != RES_OK) return res; + + tk = strtok_r(NULL, "", &ctx); + res = cstr_to_double(tk, dbl3+2); + if(res != RES_OK) return res; + + return RES_OK; +} + +static res_T +parse_image_definition + (const char* str, + unsigned long* width, + unsigned long* height) +{ + char buf[64]; + char* tk; + char* ctx; + res_T res = RES_OK; + ASSERT(str && width && height); + + if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) { + fprintf(stderr, + "Could not duplicate the image definition string `%s'.\n", str); + return RES_MEM_ERR; + } + strncpy(buf, str, sizeof(buf)); + + tk = strtok_r(buf, "x", &ctx); + res = cstr_to_ulong(tk, width); + if(res != RES_OK) { + fprintf(stderr, "Invalid image width `%s'\n", tk); + return res; + } + + tk = strtok_r(NULL, "", &ctx); + res = cstr_to_ulong(tk, height); + if(res != RES_OK) { + fprintf(stderr, "Invalid image height `%s'\n", tk); + return res; + } + + return res; +} + +static res_T +parse_rendering_option(const char* str, struct solstice_args* args) { + char buf[128]; + char* key; + char* val; + char* ctx; + res_T res; + ASSERT(str && args); + + if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) { + fprintf(stderr, + "Could not duplicate the rendering option string `%s'\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + key = strtok_r(buf, "=", &ctx); + val = strtok_r(NULL, "", &ctx); + + if(!strcmp(key, "fov")) { + res = parse_fov(val, &args->camera.fov_x); + if(res != RES_OK) goto error; + } else if(!strcmp(key, "img")) { + res = parse_image_definition(val, &args->img.width, &args->img.height); + if(res != RES_OK) goto error; + } else if(!strcmp(key, "pos")) { + res = parse_double3(val, args->camera.pos); + if(res != RES_OK) { + fprintf(stderr, "Invalid camera position `%s'.\n", val); + goto error; + } + } else if(!strcmp(key, "tgt")) { + res = parse_double3(val, args->camera.tgt); + if(res != RES_OK) { + fprintf(stderr, "Invalid camera target `%s'.\n", val); + goto error; + } + } else if(!strcmp(key, "up")) { + res = parse_double3(val, args->camera.up); + if(res != RES_OK) { + fprintf(stderr, "Invalid camera up vector `%s'.\n", val); + goto error; + } + } else { + fprintf(stderr, "Invalid rendering option `%s'.\n", val); + res = RES_BAD_ARG; + goto error; + } + args->rendering = 1; + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_rendering_options(const char* str, struct solstice_args* args) +{ + char buf[512]; + char* tk; + char* ctx; + res_T res = RES_OK; ASSERT(args); (void)str, (void)args; - /* TODO */ - return RES_OK; + + /* Setup default values of the rendering parameters */ + d3(args->camera.pos, 0, 0, 0); + d3(args->camera.tgt, 0, 0, -1); + d3(args->camera.up, 0, 1, 0); + args->camera.fov_x = MDEG2RAD(70); + args->img.width = 800; + args->img.height = 600; + + if(!str) goto exit; + + if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) { + fprintf(stderr, + "Could not duplicate the rendering options string `%s'.\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + tk = strtok_r(buf, ":", &ctx); + do { + res = parse_rendering_option(tk, args); + tk = strtok_r(NULL, ":", &ctx); + } while(tk); + +exit: + return res; +error: + goto exit; } /******************************************************************************* * Local function ******************************************************************************/ res_T -solstice_args_init(struct solstice_args* args, const int argc, char** argv) +solstice_args_init(struct solstice_args* args, const int argc, char** argv) { int opt; res_T res = RES_OK; @@ -59,6 +241,7 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv) *args = SOLSTICE_ARGS_NULL; + optind = 1; while((opt = getopt(argc, argv, "hn:o:qr:")) != -1) { switch(opt) { case 'h': @@ -71,7 +254,7 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv) break; case 'o': args->output_filename = optarg; break; case 'q': args->quiet = 1; break; - case 'r': res = parse_rendering(optarg, args); break; + case 'r': res = parse_rendering_options(optarg, args); break; default: res = RES_BAD_ARG; break; } if(res != RES_OK) { @@ -82,7 +265,9 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv) goto error; } } + exit: + optind = 1; return res; error: solstice_args_release(args); diff --git a/src/solstice_args.h b/src/solstice_args.h @@ -21,10 +21,24 @@ struct solstice_args { const char* output_filename; unsigned long nrealisations; /* #realisations */ + + struct { + double pos[3]; + double tgt[3]; + double up[3]; + double fov_x; + } camera; + + struct { + unsigned long width; + unsigned long height; + } img; + + int rendering; int quiet; }; -#define SOLSTICE_ARGS_NULL__ {NULL, 0, 0} +#define SOLSTICE_ARGS_NULL__ {0} static const struct solstice_args SOLSTICE_ARGS_NULL = SOLSTICE_ARGS_NULL__; extern LOCAL_SYM res_T