Line | Branch | Exec | Source |
---|---|---|---|
1 | /*********************************************************************************/ | ||
2 | /* Copyright 2009-2024 Barcelona Supercomputing Center */ | ||
3 | /* */ | ||
4 | /* This file is part of the DLB library. */ | ||
5 | /* */ | ||
6 | /* DLB is free software: you can redistribute it and/or modify */ | ||
7 | /* it under the terms of the GNU Lesser General Public License as published by */ | ||
8 | /* the Free Software Foundation, either version 3 of the License, or */ | ||
9 | /* (at your option) any later version. */ | ||
10 | /* */ | ||
11 | /* DLB is distributed in the hope that it will be useful, */ | ||
12 | /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ | ||
13 | /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ | ||
14 | /* GNU Lesser General Public License for more details. */ | ||
15 | /* */ | ||
16 | /* You should have received a copy of the GNU Lesser General Public License */ | ||
17 | /* along with DLB. If not, see <https://www.gnu.org/licenses/>. */ | ||
18 | /*********************************************************************************/ | ||
19 | |||
20 | #include "support/types.h" | ||
21 | #include "support/debug.h" | ||
22 | #include "apis/dlb_errors.h" | ||
23 | |||
24 | #include <limits.h> | ||
25 | #include <stdlib.h> | ||
26 | #include <string.h> | ||
27 | #include <stdio.h> | ||
28 | #include <errno.h> | ||
29 | |||
30 | #define LINE_BREAK "\n " | ||
31 | |||
32 | 2645 | int parse_bool(const char *str, bool *value) { | |
33 |
2/2✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 5 times.
|
2645 | if (strcasecmp(str, "1")==0 || |
34 |
2/2✓ Branch 0 taken 2081 times.
✓ Branch 1 taken 559 times.
|
2640 | strcasecmp(str, "yes")==0 || |
35 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2080 times.
|
2081 | strcasecmp(str, "true")==0) { |
36 | 565 | *value = true; | |
37 |
2/2✓ Branch 0 taken 2074 times.
✓ Branch 1 taken 6 times.
|
2080 | } else if (strcasecmp(str, "0")==0 || |
38 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2069 times.
|
2074 | strcasecmp(str, "no")==0 || |
39 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
|
5 | strcasecmp(str, "false")==0) { |
40 | 2078 | *value = false; | |
41 | } else { | ||
42 | 2 | return DLB_ERR_NOENT; | |
43 | } | ||
44 | 2643 | return DLB_SUCCESS; | |
45 | } | ||
46 | |||
47 | 3 | bool equivalent_bool(const char *str1, const char *str2) { | |
48 | 3 | bool b1 = false; | |
49 | 3 | bool b2 = true; | |
50 | 3 | int err1 = parse_bool(str1, &b1); | |
51 | 3 | int err2 = parse_bool(str2, &b2); | |
52 |
4/6✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2 times.
|
3 | return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && b1 == b2; |
53 | } | ||
54 | |||
55 | 16 | int parse_negated_bool(const char *str, bool *value) { | |
56 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
|
16 | if (strcasecmp(str, "1")==0 || |
57 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 4 times.
|
14 | strcasecmp(str, "yes")==0 || |
58 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
|
10 | strcasecmp(str, "true")==0) { |
59 | 7 | *value = false; | |
60 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2 times.
|
9 | } else if (strcasecmp(str, "0")==0 || |
61 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
|
7 | strcasecmp(str, "no")==0 || |
62 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
|
5 | strcasecmp(str, "false")==0) { |
63 | 7 | *value = true; | |
64 | } else { | ||
65 | 2 | return DLB_ERR_NOENT; | |
66 | } | ||
67 | 14 | return DLB_SUCCESS; | |
68 | } | ||
69 | |||
70 | 2 | bool equivalent_negated_bool(const char *str1, const char *str2) { | |
71 | 2 | bool b1 = false; | |
72 | 2 | bool b2 = true; | |
73 | 2 | int err1 = parse_negated_bool(str1, &b1); | |
74 | 2 | int err2 = parse_negated_bool(str2, &b2); | |
75 |
4/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
|
2 | return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && b1 == b2; |
76 | } | ||
77 | |||
78 | 962 | int parse_int(const char *str, int *value) { | |
79 | char *endptr; | ||
80 | 962 | long val = strtol(str, &endptr, 0); | |
81 |
4/4✓ Branch 0 taken 789 times.
✓ Branch 1 taken 173 times.
✓ Branch 2 taken 787 times.
✓ Branch 3 taken 2 times.
|
962 | if ((val == 0 && endptr == str) |
82 |
2/6✓ Branch 0 taken 960 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 960 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
960 | || ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE)) { |
83 | 2 | debug_warning("Error parsing integer. str: %s, strlen: %lu, val: %ld, " | |
84 | "errno: %d, strptr: %p, endptr: %p", str, strlen(str), val, | ||
85 | errno, str, endptr); | ||
86 | 2 | return DLB_ERR_NOENT; | |
87 | } | ||
88 | 960 | *value = (int)val; | |
89 | 960 | return DLB_SUCCESS; | |
90 | } | ||
91 | |||
92 | 2 | bool equivalent_int(const char *str1, const char *str2) { | |
93 | 2 | int i1 = 0; | |
94 | 2 | int i2 = 1; | |
95 | 2 | int err1 = parse_int(str1, &i1); | |
96 | 2 | int err2 = parse_int(str2, &i2); | |
97 |
4/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
|
2 | return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && i1 == i2; |
98 | } | ||
99 | |||
100 | |||
101 | /* verbose_opts_t */ | ||
102 | static const verbose_opts_t verbose_opts_values[] = | ||
103 | {VB_CLEAR, VB_ALL, VB_API, VB_MICROLB, VB_SHMEM, VB_MPI_API, VB_MPI_INT, VB_STATS, | ||
104 | VB_DROM, VB_ASYNC, VB_OMPT, VB_AFFINITY, VB_BARRIER, VB_TALP, VB_INSTR}; | ||
105 | static const char* const verbose_opts_choices[] = | ||
106 | {"no", "all", "api", "microlb", "shmem", "mpi_api", "mpi_intercept", "stats", "drom", | ||
107 | "async", "ompt", "affinity", "barrier", "talp", "instrument"}; | ||
108 | static const char verbose_opts_choices_str[] = | ||
109 | "no:all:api:microlb:shmem:mpi_api:mpi_intercept:stats:"LINE_BREAK | ||
110 | "drom:async:ompt:affinity:barrier:talp:instrument"; | ||
111 | enum { verbose_opts_nelems = sizeof(verbose_opts_values) / sizeof(verbose_opts_values[0]) }; | ||
112 | |||
113 | 217 | int parse_verbose_opts(const char *str, verbose_opts_t *value) { | |
114 | /* particular case: '--verbose/--verbose=yes' enables all verbose options */ | ||
115 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 214 times.
|
217 | if (strcmp(str, "yes") == 0) { |
116 | 3 | *value = VB_ALL; | |
117 | 3 | return DLB_SUCCESS; | |
118 | } | ||
119 | |||
120 | 214 | *value = VB_CLEAR; | |
121 | |||
122 | /* tokenize multiple options separated by ':' */ | ||
123 | 214 | char *end_token = NULL; | |
124 | 214 | size_t len = strlen(str) + 1; | |
125 | 214 | char *str_copy = malloc(sizeof(char)*len); | |
126 | 214 | strcpy(str_copy, str); | |
127 | 214 | char *token = strtok_r(str_copy, ":", &end_token); | |
128 |
2/2✓ Branch 0 taken 225 times.
✓ Branch 1 taken 214 times.
|
439 | while (token) { |
129 | int i; | ||
130 |
2/2✓ Branch 0 taken 451 times.
✓ Branch 1 taken 2 times.
|
453 | for (i=0; i<verbose_opts_nelems; ++i) { |
131 |
2/2✓ Branch 0 taken 223 times.
✓ Branch 1 taken 228 times.
|
451 | if (strcmp(token, verbose_opts_choices[i]) == 0) { |
132 | 223 | *value |= verbose_opts_values[i]; | |
133 | 223 | break; | |
134 | } | ||
135 | } | ||
136 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 223 times.
|
225 | if (i == verbose_opts_nelems) { |
137 | 2 | warning("Unknown --verbose option: %s", token); | |
138 | } | ||
139 | 225 | token = strtok_r(NULL, ":", &end_token); | |
140 | } | ||
141 | 214 | free(str_copy); | |
142 | |||
143 | 214 | return DLB_SUCCESS; | |
144 | } | ||
145 | |||
146 | 7 | const char* verbose_opts_tostr(verbose_opts_t value) { | |
147 | /* particular cases */ | ||
148 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
|
7 | if (value == VB_CLEAR) { |
149 | 5 | return "no"; | |
150 | } | ||
151 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if (value == VB_ALL) { |
152 | 1 | return "all"; | |
153 | } | ||
154 | |||
155 | static char str[sizeof(verbose_opts_choices_str)] = ""; | ||
156 | 1 | char *p = str; | |
157 | int i; | ||
158 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
|
14 | for (i=2; i<verbose_opts_nelems; ++i) { |
159 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11 times.
|
13 | if (value & verbose_opts_values[i]) { |
160 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if (p!=str) { |
161 | 1 | *p = ':'; | |
162 | 1 | ++p; | |
163 | 1 | *p = '\0'; | |
164 | } | ||
165 | 2 | p += sprintf(p, "%s", verbose_opts_choices[i]); | |
166 | } | ||
167 | } | ||
168 | 1 | return str; | |
169 | } | ||
170 | |||
171 | 4 | const char* get_verbose_opts_choices(void) { | |
172 | 4 | return verbose_opts_choices_str; | |
173 | } | ||
174 | |||
175 | 3 | bool equivalent_verbose_opts(const char *str1, const char *str2) { | |
176 | verbose_opts_t value1, value2; | ||
177 | 3 | parse_verbose_opts(str1, &value1); | |
178 | 3 | parse_verbose_opts(str2, &value2); | |
179 | 3 | return value1 == value2; | |
180 | } | ||
181 | |||
182 | |||
183 | /* verbose_fmt_t */ | ||
184 | static const verbose_fmt_t verbose_fmt_values[] = | ||
185 | {VBF_NODE, VBF_MPINODE, VBF_MPIRANK, VBF_SPID, VBF_THREAD, VBF_TSTAMP}; | ||
186 | static const char* const verbose_fmt_choices[] = | ||
187 | {"node", "mpinode", "mpirank", "spid", "thread", "timestamp"}; | ||
188 | static const char verbose_fmt_choices_str[] = | ||
189 | "node:mpinode:mpirank:spid:thread:timestamp"; | ||
190 | enum { verbose_fmt_nelems = sizeof(verbose_fmt_values) / sizeof(verbose_fmt_values[0]) }; | ||
191 | |||
192 | 167 | int parse_verbose_fmt(const char *str, verbose_fmt_t *value) { | |
193 | 167 | *value = VBF_CLEAR; | |
194 | |||
195 | /* tokenize multiple options separated by ':' */ | ||
196 | 167 | char *end_token = NULL; | |
197 | 167 | size_t len = strlen(str) + 1; | |
198 | 167 | char *str_copy = malloc(sizeof(char)*len); | |
199 | 167 | strcpy(str_copy, str); | |
200 | 167 | char *token = strtok_r(str_copy, ":", &end_token); | |
201 |
2/2✓ Branch 0 taken 329 times.
✓ Branch 1 taken 167 times.
|
496 | while (token) { |
202 | int i; | ||
203 |
2/2✓ Branch 0 taken 841 times.
✓ Branch 1 taken 3 times.
|
844 | for (i=0; i<verbose_fmt_nelems; ++i) { |
204 |
2/2✓ Branch 0 taken 326 times.
✓ Branch 1 taken 515 times.
|
841 | if (strcmp(token, verbose_fmt_choices[i]) == 0) { |
205 | 326 | *value |= verbose_fmt_values[i]; | |
206 | 326 | break; | |
207 | } | ||
208 | } | ||
209 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 326 times.
|
329 | if (i == verbose_fmt_nelems) { |
210 | 3 | warning("Unknown --verbose-format option: %s", token); | |
211 | } | ||
212 | 329 | token = strtok_r(NULL, ":", &end_token); | |
213 | } | ||
214 | 167 | free(str_copy); | |
215 | |||
216 | 167 | return DLB_SUCCESS; | |
217 | } | ||
218 | |||
219 | 8 | const char* verbose_fmt_tostr(verbose_fmt_t value) { | |
220 | static char str[sizeof(verbose_fmt_choices_str)] = ""; | ||
221 | 8 | char *p = str; | |
222 | int i; | ||
223 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 8 times.
|
56 | for (i=0; i<verbose_fmt_nelems; ++i) { |
224 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 36 times.
|
48 | if (value & verbose_fmt_values[i]) { |
225 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 7 times.
|
12 | if (p!=str) { |
226 | 5 | *p = ':'; | |
227 | 5 | ++p; | |
228 | 5 | *p = '\0'; | |
229 | } | ||
230 | 12 | p += sprintf(p, "%s", verbose_fmt_choices[i]); | |
231 | } | ||
232 | } | ||
233 | 8 | return str; | |
234 | } | ||
235 | |||
236 | 4 | const char* get_verbose_fmt_choices(void) { | |
237 | 4 | return verbose_fmt_choices_str; | |
238 | } | ||
239 | |||
240 | 3 | bool equivalent_verbose_fmt(const char *str1, const char *str2) { | |
241 | verbose_fmt_t value1, value2; | ||
242 | 3 | parse_verbose_fmt(str1, &value1); | |
243 | 3 | parse_verbose_fmt(str2, &value2); | |
244 | 3 | return value1 == value2; | |
245 | } | ||
246 | |||
247 | |||
248 | /* instrument_items_t */ | ||
249 | static const instrument_items_t instrument_items_values[] = | ||
250 | {INST_NONE, INST_ALL, INST_MPI, INST_LEWI, INST_DROM, INST_TALP, INST_BARR, INST_OMPT, INST_CPUS, INST_CBCK}; | ||
251 | static const char* const instrument_items_choices[] = | ||
252 | {"none", "all", "mpi", "lewi", "drom", "talp", "barrier", "ompt", "cpus", "callbacks"}; | ||
253 | static const char instrument_items_choices_str[] = | ||
254 | "none:all:mpi:lewi:drom:talp:barrier:ompt:cpus:callbacks"; | ||
255 | enum { instrument_items_nelems = sizeof(instrument_items_values) / sizeof(instrument_items_values[0]) }; | ||
256 | |||
257 | 168 | int parse_instrument_items(const char *str, instrument_items_t *value) { | |
258 | /* particular case: '--instrument/--instrument=yes' enables all instrument items */ | ||
259 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 166 times.
|
168 | if (strcmp(str, "yes") == 0) { |
260 | 2 | *value = INST_ALL; | |
261 | 2 | return DLB_SUCCESS; | |
262 | } | ||
263 | |||
264 | /* particular case: '--no-instrument/--instrument=no' disables all instrument items */ | ||
265 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 166 times.
|
166 | if (strcmp(str, "no") == 0) { |
266 | ✗ | *value = INST_NONE; | |
267 | ✗ | return DLB_SUCCESS; | |
268 | } | ||
269 | |||
270 | 166 | *value = INST_NONE; | |
271 | |||
272 | /* tokenize multiple options separated by ':' */ | ||
273 | 166 | char *end_token = NULL; | |
274 | 166 | size_t len = strlen(str) + 1; | |
275 | 166 | char *str_copy = malloc(sizeof(char)*len); | |
276 | 166 | strcpy(str_copy, str); | |
277 | 166 | char *token = strtok_r(str_copy, ":", &end_token); | |
278 |
2/2✓ Branch 0 taken 176 times.
✓ Branch 1 taken 166 times.
|
342 | while (token) { |
279 | int i; | ||
280 |
2/2✓ Branch 0 taken 429 times.
✓ Branch 1 taken 4 times.
|
433 | for (i=0; i<instrument_items_nelems; ++i) { |
281 |
2/2✓ Branch 0 taken 172 times.
✓ Branch 1 taken 257 times.
|
429 | if (strcmp(token, instrument_items_choices[i]) == 0) { |
282 | 172 | *value |= instrument_items_values[i]; | |
283 | 172 | break; | |
284 | } | ||
285 | } | ||
286 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 172 times.
|
176 | if (i == instrument_items_nelems) { |
287 | 4 | warning("Unknown --instrument option: %s", token); | |
288 | } | ||
289 | 176 | token = strtok_r(NULL, ":", &end_token); | |
290 | } | ||
291 | 166 | free(str_copy); | |
292 | |||
293 | 166 | return DLB_SUCCESS; | |
294 | } | ||
295 | |||
296 | 7 | const char* instrument_items_tostr(instrument_items_t value) { | |
297 | // particular cases | ||
298 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
|
7 | if (value == INST_NONE) { |
299 | 1 | return "none"; | |
300 | } | ||
301 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
|
6 | if (value == INST_ALL) { |
302 | 5 | return "all"; | |
303 | } | ||
304 | |||
305 | static char str[sizeof(instrument_items_choices_str)] = ""; | ||
306 | 1 | char *p = str; | |
307 | int i; | ||
308 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
|
9 | for (i=2; i<instrument_items_nelems; ++i) { |
309 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
|
8 | if (value & instrument_items_values[i]) { |
310 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if (p!=str) { |
311 | 1 | *p = ':'; | |
312 | 1 | ++p; | |
313 | 1 | *p = '\0'; | |
314 | } | ||
315 | 2 | p += sprintf(p, "%s", instrument_items_choices[i]); | |
316 | } | ||
317 | } | ||
318 | 1 | return str; | |
319 | } | ||
320 | |||
321 | 4 | const char* get_instrument_items_choices(void) { | |
322 | 4 | return instrument_items_choices_str; | |
323 | } | ||
324 | |||
325 | 3 | bool equivalent_instrument_items(const char *str1, const char *str2) { | |
326 | instrument_items_t value1, value2; | ||
327 | 3 | parse_instrument_items(str1, &value1); | |
328 | 3 | parse_instrument_items(str2, &value2); | |
329 | 3 | return value1 == value2; | |
330 | } | ||
331 | |||
332 | |||
333 | /* debug_opts_t */ | ||
334 | static const debug_opts_t debug_opts_values[] = | ||
335 | {DBG_RETURNSTOLEN, DBG_WERROR, DBG_LPOSTMORTEM, DBG_WARNMPI}; | ||
336 | static const char* const debug_opts_choices[] = | ||
337 | {"return-stolen", "werror", "lend-post-mortem", "warn-mpi-version"}; | ||
338 | static const char debug_opts_choices_str[] = | ||
339 | "return-stolen:werror:lend-post-mortem:warn-mpi-version"; | ||
340 | enum { debug_opts_nelems = sizeof(debug_opts_values) / sizeof(debug_opts_values[0]) }; | ||
341 | |||
342 | 157 | int parse_debug_opts(const char *str, debug_opts_t *value) { | |
343 | 157 | *value = DBG_CLEAR; | |
344 | int i; | ||
345 |
2/2✓ Branch 0 taken 628 times.
✓ Branch 1 taken 157 times.
|
785 | for (i=0; i<debug_opts_nelems; ++i) { |
346 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 625 times.
|
628 | if (strstr(str, debug_opts_choices[i]) != NULL) { |
347 | 3 | *value |= debug_opts_values[i]; | |
348 | } | ||
349 | } | ||
350 | 157 | return DLB_SUCCESS; | |
351 | } | ||
352 | |||
353 | 1 | const char* debug_opts_tostr(debug_opts_t value) { | |
354 | static char str[sizeof(debug_opts_choices_str)] = ""; | ||
355 | 1 | char *p = str; | |
356 | int i; | ||
357 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
|
5 | for (i=0; i<debug_opts_nelems; ++i) { |
358 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (value & debug_opts_values[i]) { |
359 | ✗ | if (p!=str) { | |
360 | ✗ | *p = ':'; | |
361 | ✗ | ++p; | |
362 | ✗ | *p = '\0'; | |
363 | } | ||
364 | ✗ | p += sprintf(p, "%s", debug_opts_choices[i]); | |
365 | } | ||
366 | } | ||
367 | 1 | return str; | |
368 | } | ||
369 | |||
370 | 1 | const char* get_debug_opts_choices(void) { | |
371 | 1 | return debug_opts_choices_str; | |
372 | } | ||
373 | |||
374 | ✗ | bool equivalent_debug_opts(const char *str1, const char *str2) { | |
375 | debug_opts_t value1, value2; | ||
376 | ✗ | parse_debug_opts(str1, &value1); | |
377 | ✗ | parse_debug_opts(str2, &value2); | |
378 | ✗ | return value1 == value2; | |
379 | } | ||
380 | |||
381 | |||
382 | /* lewi_affinity_t */ | ||
383 | static const lewi_affinity_t lewi_affinity_values[] = | ||
384 | {LEWI_AFFINITY_AUTO, LEWI_AFFINITY_NONE, LEWI_AFFINITY_MASK, | ||
385 | LEWI_AFFINITY_NEARBY_FIRST, LEWI_AFFINITY_NEARBY_ONLY, LEWI_AFFINITY_SPREAD_IFEMPTY}; | ||
386 | static const char* const lewi_affinity_choices[] = | ||
387 | {"auto", "none", "mask", "nearby-first", "nearby-only", "spread-ifempty"}; | ||
388 | static const char lewi_affinity_choices_str[] = | ||
389 | "auto, none, mask, nearby-first,"LINE_BREAK | ||
390 | "nearby-only, spread-ifempty"; | ||
391 | enum { lewi_affinity_nelems = sizeof(lewi_affinity_values) / sizeof(lewi_affinity_values[0]) }; | ||
392 | |||
393 | 214 | int parse_lewi_affinity(const char *str, lewi_affinity_t *value) { | |
394 | |||
395 |
2/2✓ Branch 0 taken 262 times.
✓ Branch 1 taken 4 times.
|
266 | for (int i = 0; i < lewi_affinity_nelems; ++i) { |
396 |
2/2✓ Branch 0 taken 210 times.
✓ Branch 1 taken 52 times.
|
262 | if (strcasecmp(str, lewi_affinity_choices[i]) == 0) { |
397 | 210 | *value = lewi_affinity_values[i]; | |
398 | 210 | return DLB_SUCCESS; | |
399 | } | ||
400 | } | ||
401 | |||
402 | /* Support deprecated values */ | ||
403 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (strcasecmp(str, "any") == 0) { |
404 | 2 | *value = LEWI_AFFINITY_MASK; | |
405 | 2 | return DLB_SUCCESS; | |
406 | } | ||
407 | |||
408 | 2 | return DLB_ERR_NOENT; | |
409 | } | ||
410 | |||
411 | 4 | const char* lewi_affinity_tostr(lewi_affinity_t value) { | |
412 | int i; | ||
413 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | for (i=0; i<lewi_affinity_nelems; ++i) { |
414 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (lewi_affinity_values[i] == value) { |
415 | 4 | return lewi_affinity_choices[i]; | |
416 | } | ||
417 | } | ||
418 | ✗ | return "unknown"; | |
419 | } | ||
420 | |||
421 | 4 | const char* get_lewi_affinity_choices(void) { | |
422 | 4 | return lewi_affinity_choices_str; | |
423 | } | ||
424 | |||
425 | 2 | bool equivalent_lewi_affinity(const char *str1, const char *str2) { | |
426 | 2 | lewi_affinity_t value1 = LEWI_AFFINITY_NONE; | |
427 | 2 | lewi_affinity_t value2 = LEWI_AFFINITY_MASK; | |
428 | 2 | int err1 = parse_lewi_affinity(str1, &value1); | |
429 | 2 | int err2 = parse_lewi_affinity(str2, &value2); | |
430 |
4/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
|
2 | return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2; |
431 | } | ||
432 | |||
433 | |||
434 | /* talp_summary_t */ | ||
435 | static const talp_summary_t talp_summary_values[] = | ||
436 | {SUMMARY_NONE, SUMMARY_ALL, SUMMARY_POP_METRICS, SUMMARY_POP_RAW, SUMMARY_NODE, | ||
437 | SUMMARY_PROCESS}; | ||
438 | static const char* const talp_summary_choices[] = | ||
439 | {"none", "all", "pop-metrics", "pop-raw", "node", "process"}; | ||
440 | static const char talp_summary_choices_str[] = | ||
441 | "none:all:pop-metrics:process"; | ||
442 | enum { talp_summary_nelems = sizeof(talp_summary_values) / sizeof(talp_summary_values[0]) }; | ||
443 | |||
444 | 167 | int parse_talp_summary(const char *str, talp_summary_t *value) { | |
445 | /* particular case: '--talp-summary/--talp-summary=yes' enables only POP metrics */ | ||
446 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 166 times.
|
167 | if (strcmp(str, "yes") == 0) { |
447 | 1 | *value = SUMMARY_POP_METRICS; | |
448 | 1 | return DLB_SUCCESS; | |
449 | } | ||
450 | |||
451 | /* particular case: '--no-talp-summary/--talp-summary=no' disables all summaries */ | ||
452 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 166 times.
|
166 | if (strcmp(str, "no") == 0) { |
453 | ✗ | *value = SUMMARY_NONE; | |
454 | ✗ | return DLB_SUCCESS; | |
455 | } | ||
456 | |||
457 | 166 | *value = SUMMARY_NONE; | |
458 | |||
459 | /* tokenize multiple options separated by ':' */ | ||
460 | 166 | char *end_token = NULL; | |
461 | 166 | size_t len = strlen(str) + 1; | |
462 | 166 | char *str_copy = malloc(sizeof(char)*len); | |
463 | 166 | strcpy(str_copy, str); | |
464 | 166 | char *token = strtok_r(str_copy, ":", &end_token); | |
465 |
2/2✓ Branch 0 taken 168 times.
✓ Branch 1 taken 166 times.
|
334 | while (token) { |
466 | int i; | ||
467 |
2/2✓ Branch 0 taken 524 times.
✓ Branch 1 taken 4 times.
|
528 | for (i=0; i<talp_summary_nelems; ++i) { |
468 |
2/2✓ Branch 0 taken 164 times.
✓ Branch 1 taken 360 times.
|
524 | if (strcmp(token, talp_summary_choices[i]) == 0) { |
469 | 164 | *value |= talp_summary_values[i]; | |
470 | 164 | break; | |
471 | } | ||
472 | |||
473 | /* Support deprecated values */ | ||
474 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 360 times.
|
360 | if (strcmp(token, "app") == 0) { |
475 | ✗ | *value |= SUMMARY_POP_METRICS; | |
476 | ✗ | break; | |
477 | } | ||
478 | } | ||
479 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 164 times.
|
168 | if (i == talp_summary_nelems) { |
480 | 4 | warning("Unknown --talp-summary option: %s", token); | |
481 | } | ||
482 | 168 | token = strtok_r(NULL, ":", &end_token); | |
483 | } | ||
484 | 166 | free(str_copy); | |
485 | |||
486 | /* Deprecation warnings: */ | ||
487 | |||
488 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 163 times.
|
166 | if (*value & SUMMARY_POP_RAW) { |
489 | 3 | warning("Deprecated: --talp-summary=pop-raw is deprecated. Use pop-metrics instead."); | |
490 | } | ||
491 | |||
492 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 164 times.
|
166 | if (*value & SUMMARY_NODE) { |
493 | 2 | warning("Deprecated: --talp-summary=node is deprecated. Use process instead."); | |
494 | } | ||
495 | |||
496 | 166 | return DLB_SUCCESS; | |
497 | } | ||
498 | |||
499 | 7 | const char* talp_summary_tostr(talp_summary_t value) { | |
500 | // particular cases | ||
501 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
|
7 | if (value == SUMMARY_NONE) { |
502 | 1 | return "none"; | |
503 | } | ||
504 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
|
6 | if (value == SUMMARY_ALL) { |
505 | 1 | return "all"; | |
506 | } | ||
507 | |||
508 | static char str[sizeof(talp_summary_choices_str)] = ""; | ||
509 | 5 | char *p = str; | |
510 | int i; | ||
511 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 5 times.
|
25 | for (i=2; i<talp_summary_nelems; ++i) { |
512 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
|
20 | if (value & talp_summary_values[i]) { |
513 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | if (p!=str) { |
514 | ✗ | *p = ':'; | |
515 | ✗ | ++p; | |
516 | ✗ | *p = '\0'; | |
517 | } | ||
518 | 5 | p += sprintf(p, "%s", talp_summary_choices[i]); | |
519 | } | ||
520 | } | ||
521 | 5 | return str; | |
522 | } | ||
523 | |||
524 | 4 | const char* get_talp_summary_choices(void) { | |
525 | 4 | return talp_summary_choices_str; | |
526 | } | ||
527 | |||
528 | 3 | bool equivalent_talp_summary(const char *str1, const char *str2) { | |
529 | talp_summary_t value1, value2; | ||
530 | 3 | parse_talp_summary(str1, &value1); | |
531 | 3 | parse_talp_summary(str2, &value2); | |
532 | 3 | return value1 == value2; | |
533 | } | ||
534 | |||
535 | |||
536 | /* talp_model_t */ | ||
537 | static const talp_model_t talp_model_values[] = {TALP_MODEL_HYBRID_V1, TALP_MODEL_HYBRID_V2}; | ||
538 | static const char* const talp_model_choices[] = {"hybrid-v1", "hybrid-v2"}; | ||
539 | static const char talp_model_choices_str[] = "hybrid-v1, hybrid-v2"; | ||
540 | enum { talp_model_nelems = sizeof(talp_model_values) / sizeof(talp_model_values[0]) }; | ||
541 | |||
542 | 163 | int parse_talp_model(const char *str, talp_model_t *value) { | |
543 | int i; | ||
544 |
2/2✓ Branch 0 taken 322 times.
✓ Branch 1 taken 1 times.
|
323 | for (i=0; i<talp_model_nelems; ++i) { |
545 |
2/2✓ Branch 0 taken 162 times.
✓ Branch 1 taken 160 times.
|
322 | if (strcasecmp(str, talp_model_choices[i]) == 0) { |
546 | 162 | *value = talp_model_values[i]; | |
547 | 162 | return DLB_SUCCESS; | |
548 | } | ||
549 | } | ||
550 | 1 | return DLB_ERR_NOENT; | |
551 | } | ||
552 | |||
553 | 2 | const char* talp_model_tostr(talp_model_t value) { | |
554 | int i; | ||
555 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | for (i=0; i<talp_model_nelems; ++i) { |
556 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (talp_model_values[i] == value) { |
557 | 2 | return talp_model_choices[i]; | |
558 | } | ||
559 | } | ||
560 | ✗ | return "unknown"; | |
561 | } | ||
562 | |||
563 | 1 | const char* get_talp_model_choices(void) { | |
564 | 1 | return talp_model_choices_str; | |
565 | } | ||
566 | |||
567 | 2 | bool equivalent_talp_model(const char *str1, const char *str2) { | |
568 | 2 | talp_model_t value1 = TALP_MODEL_HYBRID_V1; | |
569 | 2 | talp_model_t value2 = TALP_MODEL_HYBRID_V2; | |
570 | 2 | int err1 = parse_talp_model(str1, &value1); | |
571 | 2 | int err2 = parse_talp_model(str2, &value2); | |
572 |
4/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
|
2 | return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2; |
573 | } | ||
574 | |||
575 | |||
576 | /* policy_t: most of this stuff is depcrecated, only policy_tostr is still used */ | ||
577 | static const policy_t policy_values[] = {POLICY_NONE, POLICY_LEWI, POLICY_LEWI_ASYNC, POLICY_LEWI_MASK}; | ||
578 | static const char* const policy_choices[] = {"no", "LeWI", "LeWI_async", "LeWI_mask"}; | ||
579 | static const char policy_choices_str[] = "no, LeWI, LeWI_async, LeWI_mask"; | ||
580 | enum { policy_nelems = sizeof(policy_values) / sizeof(policy_values[0]) }; | ||
581 | |||
582 | 9 | int parse_policy(const char *str, policy_t *value) { | |
583 | int i; | ||
584 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 2 times.
|
27 | for (i=0; i<policy_nelems; ++i) { |
585 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 18 times.
|
25 | if (strcasecmp(str, policy_choices[i]) == 0) { |
586 | 7 | *value = policy_values[i]; | |
587 | 7 | return DLB_SUCCESS; | |
588 | } | ||
589 | } | ||
590 | 2 | return DLB_ERR_NOENT; | |
591 | } | ||
592 | |||
593 | 50 | const char* policy_tostr(policy_t value) { | |
594 | int i; | ||
595 |
2/2✓ Branch 0 taken 134 times.
✓ Branch 1 taken 1 times.
|
135 | for (i=0; i<policy_nelems; ++i) { |
596 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 85 times.
|
134 | if (policy_values[i] == value) { |
597 | 49 | return policy_choices[i]; | |
598 | } | ||
599 | } | ||
600 | 1 | return "error"; | |
601 | } | ||
602 | |||
603 | ✗ | const char* get_policy_choices(void) { | |
604 | ✗ | return policy_choices_str; | |
605 | } | ||
606 | |||
607 | 2 | bool equivalent_policy(const char *str1, const char *str2) { | |
608 | 2 | policy_t value1 = POLICY_NONE; | |
609 | 2 | policy_t value2 = POLICY_LEWI; | |
610 | 2 | int err1 = parse_policy(str1, &value1); | |
611 | 2 | int err2 = parse_policy(str2, &value2); | |
612 |
4/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
|
2 | return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2; |
613 | } | ||
614 | |||
615 | /* interaction_mode_t */ | ||
616 | static const interaction_mode_t mode_values[] = {MODE_POLLING, MODE_ASYNC}; | ||
617 | static const char* const mode_choices[] = {"polling", "async"}; | ||
618 | static const char mode_choices_str[] = "polling, async"; | ||
619 | enum { mode_nelems = sizeof(mode_values) / sizeof(mode_values[0]) }; | ||
620 | |||
621 | 164 | int parse_mode(const char *str, interaction_mode_t *value) { | |
622 | int i; | ||
623 |
2/2✓ Branch 0 taken 178 times.
✓ Branch 1 taken 2 times.
|
180 | for (i=0; i<mode_nelems; ++i) { |
624 |
2/2✓ Branch 0 taken 162 times.
✓ Branch 1 taken 16 times.
|
178 | if (strcasecmp(str, mode_choices[i]) == 0) { |
625 | 162 | *value = mode_values[i]; | |
626 | 162 | return DLB_SUCCESS; | |
627 | } | ||
628 | } | ||
629 | 2 | return DLB_ERR_NOENT; | |
630 | } | ||
631 | |||
632 | 6 | const char* mode_tostr(interaction_mode_t value) { | |
633 | int i; | ||
634 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | for (i=0; i<mode_nelems; ++i) { |
635 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | if (mode_values[i] == value) { |
636 | 6 | return mode_choices[i]; | |
637 | } | ||
638 | } | ||
639 | ✗ | return "unknown"; | |
640 | } | ||
641 | |||
642 | 4 | const char* get_mode_choices(void) { | |
643 | 4 | return mode_choices_str; | |
644 | } | ||
645 | |||
646 | 2 | bool equivalent_mode(const char *str1, const char *str2) { | |
647 | 2 | interaction_mode_t value1 = MODE_POLLING; | |
648 | 2 | interaction_mode_t value2 = MODE_ASYNC; | |
649 | 2 | int err1 = parse_mode(str1, &value1); | |
650 | 2 | int err2 = parse_mode(str2, &value2); | |
651 |
4/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
|
2 | return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2; |
652 | } | ||
653 | |||
654 | /* mpi_set_t */ | ||
655 | static const mpi_set_t mpiset_values[] = {MPISET_NONE, MPISET_ALL, MPISET_BARRIER, MPISET_COLLECTIVES}; | ||
656 | static const char* const mpiset_choices[] = {"none", "all", "barrier", "collectives"}; | ||
657 | static const char mpiset_choices_str[] = "none, all, barrier, collectives"; | ||
658 | enum { mpiset_nelems = sizeof(mpiset_values) / sizeof(mpiset_values[0]) }; | ||
659 | |||
660 | 209 | int parse_mpiset(const char *str, mpi_set_t *value) { | |
661 | int i; | ||
662 |
2/2✓ Branch 0 taken 424 times.
✓ Branch 1 taken 1 times.
|
425 | for (i=0; i<mpiset_nelems; ++i) { |
663 |
2/2✓ Branch 0 taken 208 times.
✓ Branch 1 taken 216 times.
|
424 | if (strcasecmp(str, mpiset_choices[i]) == 0) { |
664 | 208 | *value = mpiset_values[i]; | |
665 | 208 | return DLB_SUCCESS; | |
666 | } | ||
667 | } | ||
668 | 1 | return DLB_ERR_NOENT; | |
669 | } | ||
670 | |||
671 | 6 | const char* mpiset_tostr(mpi_set_t value) { | |
672 | int i; | ||
673 |
1/2✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
|
13 | for (i=0; i<mpiset_nelems; ++i) { |
674 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 7 times.
|
13 | if (mpiset_values[i] == value) { |
675 | 6 | return mpiset_choices[i]; | |
676 | } | ||
677 | } | ||
678 | ✗ | return "unknown"; | |
679 | } | ||
680 | |||
681 | 4 | const char* get_mpiset_choices(void) { | |
682 | 4 | return mpiset_choices_str; | |
683 | } | ||
684 | |||
685 | 2 | bool equivalent_mpiset(const char *str1, const char *str2) { | |
686 | 2 | mpi_set_t value1 = MPISET_NONE; | |
687 | 2 | mpi_set_t value2 = MPISET_ALL; | |
688 | 2 | int err1 = parse_mpiset(str1, &value1); | |
689 | 2 | int err2 = parse_mpiset(str2, &value2); | |
690 |
4/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
|
2 | return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2; |
691 | } | ||
692 | |||
693 | /* omptool_opts_t */ | ||
694 | static const omptool_opts_t omptool_opts_values[] = | ||
695 | {OMPTOOL_OPTS_NONE, OMPTOOL_OPTS_BORROW, OMPTOOL_OPTS_LEND}; | ||
696 | static const char* const omptool_opts_choices[] = {"none", "borrow", "lend"}; | ||
697 | static const char omptool_opts_choices_str[] = "none, {borrow:lend}"; | ||
698 | enum { omptool_opts_nelems = sizeof(omptool_opts_values) / sizeof(omptool_opts_values[0]) }; | ||
699 | |||
700 | 210 | int parse_omptool_opts(const char *str, omptool_opts_t *value) { | |
701 | |||
702 | 210 | *value = OMPTOOL_OPTS_NONE; | |
703 | |||
704 | /* tokenize multiple options separated by ':' */ | ||
705 | 210 | char *end_token = NULL; | |
706 | 210 | size_t len = strlen(str) + 1; | |
707 | 210 | char *str_copy = malloc(sizeof(char)*len); | |
708 | 210 | strcpy(str_copy, str); | |
709 | 210 | char *token = strtok_r(str_copy, ":", &end_token); | |
710 |
2/2✓ Branch 0 taken 214 times.
✓ Branch 1 taken 210 times.
|
424 | while (token) { |
711 | int i; | ||
712 |
2/2✓ Branch 0 taken 435 times.
✓ Branch 1 taken 1 times.
|
436 | for (i=0; i<omptool_opts_nelems; ++i) { |
713 |
2/2✓ Branch 0 taken 213 times.
✓ Branch 1 taken 222 times.
|
435 | if (strcmp(token, omptool_opts_choices[i]) == 0) { |
714 | 213 | *value |= omptool_opts_values[i]; | |
715 | 213 | break; | |
716 | } | ||
717 | } | ||
718 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 213 times.
|
214 | if (i == omptool_opts_nelems) { |
719 | 1 | warning("Unknown --lewi-ompt option: %s", token); | |
720 | } | ||
721 | 214 | token = strtok_r(NULL, ":", &end_token); | |
722 | } | ||
723 | 210 | free(str_copy); | |
724 | |||
725 | 210 | return DLB_SUCCESS; | |
726 | } | ||
727 | |||
728 | 5 | const char* omptool_opts_tostr(omptool_opts_t value) { | |
729 | static char str[sizeof(omptool_opts_choices_str)] = ""; | ||
730 | 5 | char *p = str; | |
731 | int i; | ||
732 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
|
20 | for (i=0; i<omptool_opts_nelems; ++i) { |
733 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 10 times.
|
15 | if (value & omptool_opts_values[i]) { |
734 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | if (p!=str) { |
735 | ✗ | *p = ':'; | |
736 | ✗ | ++p; | |
737 | ✗ | *p = '\0'; | |
738 | } | ||
739 | 5 | p += sprintf(p, "%s", omptool_opts_choices[i]); | |
740 | } | ||
741 | } | ||
742 | 5 | return str; | |
743 | } | ||
744 | |||
745 | 4 | const char* get_omptool_opts_choices(void) { | |
746 | 4 | return omptool_opts_choices_str; | |
747 | } | ||
748 | |||
749 | 3 | bool equivalent_omptool_opts(const char *str1, const char *str2) { | |
750 | omptool_opts_t value1, value2; | ||
751 | 3 | parse_omptool_opts(str1, &value1); | |
752 | 3 | parse_omptool_opts(str2, &value2); | |
753 | 3 | return value1 == value2; | |
754 | } | ||
755 | |||
756 | /* omptm_version_t */ | ||
757 | static const omptm_version_t omptm_version_values[] = {OMPTM_NONE, OMPTM_OMP5, | ||
758 | OMPTM_FREE_AGENTS, OMPTM_ROLE_SHIFT}; | ||
759 | static const char* const omptm_version_choices[] = {"none", "omp5", "free-agents", "role-shift"}; | ||
760 | static const char omptm_version_choices_str[] = "none, omp5, free-agents, role-shift"; | ||
761 | enum { omptm_version_nelems = sizeof(omptm_version_values) / sizeof(omptm_version_values[0]) }; | ||
762 | |||
763 | 161 | int parse_omptm_version(const char *str, omptm_version_t *value) { | |
764 | int i; | ||
765 |
2/2✓ Branch 0 taken 174 times.
✓ Branch 1 taken 1 times.
|
175 | for (i=0; i<omptm_version_nelems; ++i) { |
766 |
2/2✓ Branch 0 taken 160 times.
✓ Branch 1 taken 14 times.
|
174 | if (strcasecmp(str, omptm_version_choices[i]) == 0) { |
767 | 160 | *value = omptm_version_values[i]; | |
768 | 160 | return DLB_SUCCESS; | |
769 | } | ||
770 | } | ||
771 | 1 | return DLB_ERR_NOENT; | |
772 | } | ||
773 | |||
774 | 4 | const char* omptm_version_tostr(omptm_version_t value) { | |
775 | int i; | ||
776 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | for (i=0; i<omptm_version_nelems; ++i) { |
777 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (omptm_version_values[i] == value) { |
778 | 4 | return omptm_version_choices[i]; | |
779 | } | ||
780 | } | ||
781 | ✗ | return "unknown"; | |
782 | } | ||
783 | |||
784 | 4 | const char* get_omptm_version_choices(void) { | |
785 | 4 | return omptm_version_choices_str; | |
786 | } | ||
787 | |||
788 | 2 | bool equivalent_omptm_version_opts(const char *str1, const char *str2) { | |
789 | 2 | omptm_version_t value1 = OMPTM_OMP5; | |
790 | 2 | omptm_version_t value2 = OMPTM_FREE_AGENTS; | |
791 | 2 | int err1 = parse_omptm_version(str1, &value1); | |
792 | 2 | int err2 = parse_omptm_version(str2, &value2); | |
793 |
4/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
|
2 | return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2; |
794 | } | ||
795 | |||
796 |