sgs_args.c (5920B)
1 /* Copyright (C) 2021-2023 Centre National de la Recherche Scientifique 2 * Copyright (C) 2021-2023 INSA Lyon 3 * Copyright (C) 2021-2023 Institut Mines Télécom Albi-Carmaux 4 * Copyright (C) 2021-2023 |Méso|Star> (contact@meso-star.com) 5 * Copyright (C) 2021-2023 Institut Pascal 6 * Copyright (C) 2021-2023 PhotonLyX (info@photonlyx.com) 7 * Copyright (C) 2021-2023 Université de Lorraine 8 * Copyright (C) 2021-2023 Université Paul Sabatier 9 * Copyright (C) 2021-2023 Université Toulouse - Jean Jaurès 10 * 11 * This program is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation, either version 3 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 23 24 #define _POSIX_C_SOURCE 200112L /* strtok_r support */ 25 26 #include "sgs.h" 27 #include "sgs_args.h" 28 #include "sgs_log.h" 29 30 #include <rsys/cstr.h> 31 32 #include <getopt.h> 33 #include <string.h> 34 35 /******************************************************************************* 36 * Helper functions 37 ******************************************************************************/ 38 static void 39 print_help(void) 40 { 41 printf("Usage: sgs [option] ...\n"); 42 printf("Calculate geometric sensitivity.\n"); 43 printf("\n"); 44 45 printf( 46 " -b <box-params:...>\n" 47 " define an axis aligned bounding box\n" 48 " Available box parameters are:\n"); 49 printf( 50 " default\n" 51 " use default settings.\n"); 52 printf( 53 " low=x,y,z\n" 54 " define the lower bound of the box\n" 55 " (default: %g,%g,%g).\n", 56 SGS_GEOMETRY_BOX_ARGS_DEFAULT.lower[0], 57 SGS_GEOMETRY_BOX_ARGS_DEFAULT.lower[1], 58 SGS_GEOMETRY_BOX_ARGS_DEFAULT.lower[2]); 59 printf( 60 " upp=x,y,z\n" 61 " define the upper bound of the box\n" 62 " (default: %g,%g,%g).\n", 63 SGS_GEOMETRY_BOX_ARGS_DEFAULT.upper[0], 64 SGS_GEOMETRY_BOX_ARGS_DEFAULT.upper[1], 65 SGS_GEOMETRY_BOX_ARGS_DEFAULT.upper[2]); 66 67 printf( 68 " pi=t\n" 69 " translation of the top face\n" 70 " (default: %g).\n", 71 SGS_GEOMETRY_BOX_ARGS_DEFAULT.pi); 72 printf( 73 " -d write geometry to stdout\n" 74 " (VTK file format).\n"); 75 printf( 76 " -h display this help and exit.\n"); 77 printf( 78 " -n nrealisations\n" 79 " number of realisations (default: %li).\n", 80 SGS_ARGS_DEFAULT.nrealisations); 81 printf( 82 " -t nthreads hint on the number of threads to use.\n" 83 " Default assumes as many threads as CPU cores.\n"); 84 printf("\n"); 85 86 sgs_fprint_license(stdout); 87 } 88 89 static res_T 90 parse_box_parameters(const char* str, void* ptr) 91 { 92 char buf[128]; 93 struct sgs_geometry_box_args* box = ptr; 94 char* key; 95 char* val; 96 char* ctx; 97 size_t len; 98 res_T res = RES_OK; 99 ASSERT(ptr && str); 100 101 if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { 102 fprintf(stderr, SGS_LOG_ERROR_PREFIX 103 "Could not duplicate the box option string `%s'.\n", str); 104 res = RES_MEM_ERR; 105 goto error; 106 } 107 strncpy(buf, str, sizeof(buf)); 108 109 key = strtok_r(buf, "=", &ctx); 110 val = strtok_r(NULL, "", &ctx); 111 112 if(!strcmp(key, "default")) { 113 *box = SGS_GEOMETRY_BOX_ARGS_DEFAULT; 114 } else if(!strcmp(key, "low")) { 115 res = cstr_to_list_double(val, ',', box->lower, &len, 3); 116 if(res == RES_OK && len != 3) res = RES_BAD_ARG; 117 } else if(!strcmp(key, "upp")) { 118 res = cstr_to_list_double(val, ',', box->upper, &len, 3); 119 if(res == RES_OK && len != 3) res = RES_BAD_ARG; 120 } else if(!strcmp(key, "pi")) { 121 res = cstr_to_double(val, &box->pi); 122 } else { 123 fprintf(stderr, SGS_LOG_ERROR_PREFIX 124 "Invalid box parameter `%s'.\n", key); 125 res = RES_BAD_ARG; 126 goto error; 127 } 128 if(res != RES_OK) { 129 fprintf(stderr, SGS_LOG_ERROR_PREFIX 130 "Error parsing the value of the `%s' box parameter: %s -- %s.\n", 131 key, val, res_to_cstr(res)); 132 goto error; 133 } 134 135 exit: 136 return res; 137 error: 138 goto exit; 139 } 140 141 /******************************************************************************* 142 * sgs_args API 143 ******************************************************************************/ 144 res_T 145 sgs_args_init(struct sgs_args* args, int argc, char** argv) 146 { 147 int opt; 148 res_T res = RES_OK; 149 ASSERT(args && argc && argv); 150 151 *args = SGS_ARGS_DEFAULT; 152 153 while((opt = getopt(argc, argv, "b:dhn:t:")) != -1) { 154 switch(opt) { 155 case 'b': 156 args->geom = SGS_GEOMETRY_BOX_ARGS_DEFAULT; 157 res = cstr_parse_list 158 (optarg, ':', parse_box_parameters, &args->geom); 159 break; 160 case 'd': args->dump_geometry = 1; break; 161 case 'h': 162 print_help(); 163 sgs_args_release(args); 164 args->quit = 1; 165 break; 166 case 'n': 167 res = cstr_to_long(optarg, &args->nrealisations); 168 if(res == RES_OK && args->nrealisations <= 0) res = RES_BAD_ARG; 169 break; 170 case 't': 171 res = cstr_to_uint(optarg, &args->nthreads); 172 if(res == RES_OK && !args->nthreads) res = RES_BAD_ARG; 173 break; 174 default: res = RES_BAD_ARG; break; 175 } 176 if(res != RES_OK) { 177 if(optarg) { 178 fprintf(stderr, SGS_LOG_ERROR_PREFIX 179 "%s: invalid option argument '%s' -- '%c'\n", 180 argv[0], optarg, opt); 181 } 182 goto error; 183 } 184 } 185 exit: 186 return res; 187 error: 188 sgs_args_release(args); 189 goto exit; 190 } 191 192 void 193 sgs_args_release(struct sgs_args* args) 194 { 195 ASSERT(args); 196 *args = SGS_ARGS_DEFAULT; 197 }