green-args.c (5174B)
1 /* Copyright (C) 2020-2022, 2024 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "green-args.h" 17 #include "green-default.h" 18 #include "green-types.h" 19 20 #include <rsys/rsys.h> 21 #include <rsys/logger.h> 22 #include <rsys/cstr.h> 23 #include <rsys/str.h> 24 25 #include <getopt.h> 26 27 static char 28 mode_option 29 (const int m) 30 { 31 int found = 0; 32 char res = '?'; 33 if(m & MODE_APPLY_GREEN) { found++; res = 'a'; } 34 if(m & MODE_EXTENTED_RESULTS) { found++; res = 'e'; } 35 if(m & MODE_READ_GREEN) { found++; res = 'g'; } 36 if(m & MODE_HELP) { found++; res = 'h'; } 37 if(m & MODE_HTML_SUMMARY) { found++; res = 's'; } 38 if(m & MODE_THREADS_COUNT) { found++; res = 't'; } 39 if(m & MODE_VERSION) { found++; res = 'v'; } 40 if(m & MODE_VERBOSE) { found++; res = 'V'; } 41 ASSERT(found == 1); 42 return res; 43 } 44 45 void 46 init_args 47 (struct logger* logger, 48 struct mem_allocator* allocator, 49 struct args* args) 50 { 51 ASSERT(logger && allocator && args); 52 args->logger = logger; 53 args->allocator = allocator; 54 /* Set default values */ 55 args->mode = MODE_NULL; 56 args->command_filename = NULL; 57 args->green_filename = NULL; 58 args->info_filename = NULL; 59 args->nthreads = (unsigned)omp_get_num_procs(); 60 args->verbose = GREEN_DEFAULT_VERBOSE_LEVEL; 61 } 62 63 res_T 64 parse_args 65 (const int argc, 66 char** argv, 67 struct args* args) 68 { 69 int opt = 0; 70 const char option_list[] = "a:ehg:s:t:vV:"; 71 res_T res = RES_OK; 72 73 ASSERT(argv && args); 74 75 opterr = 0; /* No default error messages */ 76 while ((opt = getopt(argc, argv, option_list)) != -1) { 77 switch (opt) { 78 79 case '?': /* Unreconised option */ 80 { 81 char* ptr = strchr(option_list, optopt); 82 if(ptr && ptr[1] == ':') { 83 res = RES_BAD_ARG; 84 logger_print(args->logger, LOG_ERROR, 85 "Missing argument for option -%c\n", 86 optopt); 87 } else { 88 logger_print(args->logger, LOG_ERROR, "Invalid option -%c\n", optopt); 89 } 90 goto error; 91 } 92 93 case 'a': 94 args->command_filename = optarg; 95 args->mode |= MODE_APPLY_GREEN; 96 break; 97 98 case 'e': 99 args->mode |= MODE_EXTENTED_RESULTS; 100 break; 101 102 case 'h': 103 args->mode |= MODE_HELP; 104 break; 105 106 case 'g': 107 if(args->green_filename) { 108 res = RES_BAD_ARG; 109 logger_print(args->logger, LOG_ERROR, 110 "Option -%c cannot be used twice.\n", 111 opt); 112 goto error; 113 } 114 args->mode |= MODE_READ_GREEN; 115 args->green_filename = optarg; 116 break; 117 118 case 's': 119 args->info_filename = optarg; 120 args->mode |= MODE_HTML_SUMMARY; 121 break; 122 123 case 't': 124 res = cstr_to_uint(optarg, &args->nthreads); 125 if(res != RES_OK 126 || args->nthreads <= 0) 127 { 128 if(res == RES_OK) res = RES_BAD_ARG; 129 logger_print(args->logger, LOG_ERROR, 130 "Invalid argument for option -%c: %s\n", 131 opt, optarg); 132 goto error; 133 } 134 args->mode |= MODE_THREADS_COUNT; 135 break; 136 137 case 'v': 138 args->mode |= MODE_VERSION; 139 break; 140 141 case 'V': 142 res = cstr_to_int(optarg, &args->verbose); 143 if(res != RES_OK 144 || args->verbose < 0 145 || args->verbose > 3) 146 { 147 if(res == RES_OK) res = RES_BAD_ARG; 148 logger_print(args->logger, LOG_ERROR, 149 "Invalid argument for option -%c: %s\n", 150 opt, optarg); 151 goto error; 152 } 153 args->mode |= MODE_VERBOSE; 154 break; 155 } 156 } 157 158 if(args->mode == MODE_NULL) { 159 res = RES_BAD_ARG; 160 goto error; 161 } 162 163 if(!(args->mode & MODE_READ_GREEN)) { 164 if((args->mode & MODE_HTML_SUMMARY)) { 165 res = RES_BAD_ARG; 166 logger_print(args->logger, LOG_ERROR, 167 "Option -%c can only be used in conjunction with option -%c.\n", 168 mode_option(MODE_HTML_SUMMARY), mode_option(MODE_READ_GREEN)); 169 goto error; 170 } 171 if((args->mode & MODE_APPLY_GREEN)) { 172 res = RES_BAD_ARG; 173 logger_print(args->logger, LOG_ERROR, 174 "Option -%c can only be used in conjunction with option -%c.\n", 175 mode_option(MODE_APPLY_GREEN), mode_option(MODE_READ_GREEN)); 176 goto error; 177 } 178 } 179 if((args->mode & MODE_EXTENTED_RESULTS 180 && !(args->mode & MODE_APPLY_GREEN))) { 181 res = RES_BAD_ARG; 182 logger_print(args->logger, LOG_ERROR, 183 "Option -%c can only be used in conjunction with option -%c.\n", 184 mode_option(MODE_EXTENTED_RESULTS), mode_option(MODE_APPLY_GREEN)); 185 goto error; 186 } 187 188 end: 189 return res; 190 error: 191 logger_print(args->logger, LOG_ERROR, "Use option -h to print help.\n"); 192 goto end; 193 }