This source file includes following definitions.
- pmix_mca_base_var_enum_bool_get_count
- pmix_mca_base_var_enum_bool_get_value
- pmix_mca_base_var_enum_bool_vfs
- pmix_mca_base_var_enum_bool_sfv
- pmix_mca_base_var_enum_bool_dump
- pmix_mca_base_var_enum_verbose_vfs
- pmix_mca_base_var_enum_verbose_sfv
- pmix_mca_base_var_enum_verbose_dump
- pmix_mca_base_var_enum_create
- pmix_mca_base_var_enum_create_flag
- enum_dump
- enum_get_count
- enum_get_value
- enum_value_from_string
- enum_string_from_value
- pmix_mca_base_var_enum_constructor
- pmix_mca_base_var_enum_destructor
- enum_get_value_flag
- enum_value_from_string_flag
- enum_string_from_value_flag
- enum_dump_flag
- pmix_mca_base_var_enum_flag_constructor
- pmix_mca_base_var_enum_flag_destructor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <src/include/pmix_config.h>
25
26 #include "src/mca/base/pmix_mca_base_var_enum.h"
27 #include "src/mca/base/base.h"
28 #include "src/util/argv.h"
29 #include "src/util/error.h"
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <errno.h>
34
35 static void pmix_mca_base_var_enum_constructor (pmix_mca_base_var_enum_t *enumerator);
36 static void pmix_mca_base_var_enum_destructor (pmix_mca_base_var_enum_t *enumerator);
37 PMIX_CLASS_INSTANCE(pmix_mca_base_var_enum_t, pmix_object_t, pmix_mca_base_var_enum_constructor,
38 pmix_mca_base_var_enum_destructor);
39
40 static void pmix_mca_base_var_enum_flag_constructor (pmix_mca_base_var_enum_flag_t *enumerator);
41 static void pmix_mca_base_var_enum_flag_destructor (pmix_mca_base_var_enum_flag_t *enumerator);
42 PMIX_CLASS_INSTANCE(pmix_mca_base_var_enum_flag_t, pmix_object_t, pmix_mca_base_var_enum_flag_constructor,
43 pmix_mca_base_var_enum_flag_destructor);
44
45 static int enum_dump (pmix_mca_base_var_enum_t *self, char **out);
46 static int enum_get_count (pmix_mca_base_var_enum_t *self, int *count);
47 static int enum_get_value (pmix_mca_base_var_enum_t *self, int index, int *value, const char **string_value);
48
49 static int pmix_mca_base_var_enum_bool_get_count (pmix_mca_base_var_enum_t *enumerator, int *count)
50 {
51 *count = 2;
52 return PMIX_SUCCESS;
53 }
54
55 static int pmix_mca_base_var_enum_bool_get_value (pmix_mca_base_var_enum_t *self, int index,
56 int *value, const char **string_value)
57 {
58 if (1 < index) {
59 return PMIX_ERR_VALUE_OUT_OF_BOUNDS;
60 }
61
62 *value = index ? 1 : 0;
63 *string_value = index ? "true" : "false";
64
65 return PMIX_SUCCESS;
66 }
67
68 static int pmix_mca_base_var_enum_bool_vfs (pmix_mca_base_var_enum_t *self, const char *string_value,
69 int *value)
70 {
71 char *tmp;
72 int v;
73
74
75 string_value += strspn (string_value, " \t\n\v\f\r");
76
77 v = strtol (string_value, &tmp, 10);
78 if (*tmp != '\0') {
79 if (0 == strcmp (string_value, "true") || 0 == strcmp (string_value, "t") ||
80 0 == strcmp (string_value, "enabled") || 0 == strcmp (string_value, "yes")) {
81 v = 1;
82 } else if (0 == strcmp (string_value, "false") || 0 == strcmp (string_value, "f") ||
83 0 == strcmp (string_value, "disabled") || 0 == strcmp (string_value, "no")) {
84 v = 0;
85 } else {
86 return PMIX_ERR_VALUE_OUT_OF_BOUNDS;
87 }
88 }
89
90 *value = !!v;
91
92 return PMIX_SUCCESS;
93 }
94
95 static int pmix_mca_base_var_enum_bool_sfv (pmix_mca_base_var_enum_t *self, const int value,
96 char **string_value)
97 {
98 if (string_value) {
99 *string_value = strdup (value ? "true" : "false");
100 }
101
102 return PMIX_SUCCESS;
103 }
104
105 static int pmix_mca_base_var_enum_bool_dump (pmix_mca_base_var_enum_t *self, char **out)
106 {
107 *out = strdup ("0: f|false|disabled|no, 1: t|true|enabled|yes");
108 return *out ? PMIX_SUCCESS : PMIX_ERR_OUT_OF_RESOURCE;
109 }
110
111 pmix_mca_base_var_enum_t pmix_mca_base_var_enum_bool = {
112 .super = PMIX_OBJ_STATIC_INIT(pmix_object_t),
113 .enum_is_static = true,
114 .enum_name = "boolean",
115 .get_count = pmix_mca_base_var_enum_bool_get_count,
116 .get_value = pmix_mca_base_var_enum_bool_get_value,
117 .value_from_string = pmix_mca_base_var_enum_bool_vfs,
118 .string_from_value = pmix_mca_base_var_enum_bool_sfv,
119 .dump = pmix_mca_base_var_enum_bool_dump
120 };
121
122
123 static pmix_mca_base_var_enum_value_t verbose_values[] = {
124 {PMIX_MCA_BASE_VERBOSE_NONE, "none"},
125 {PMIX_MCA_BASE_VERBOSE_ERROR, "error"},
126 {PMIX_MCA_BASE_VERBOSE_COMPONENT, "component"},
127 {PMIX_MCA_BASE_VERBOSE_WARN, "warn"},
128 {PMIX_MCA_BASE_VERBOSE_INFO, "info"},
129 {PMIX_MCA_BASE_VERBOSE_TRACE, "trace"},
130 {PMIX_MCA_BASE_VERBOSE_DEBUG, "debug"},
131 {PMIX_MCA_BASE_VERBOSE_MAX, "max"},
132 {-1, NULL}
133 };
134
135 static int pmix_mca_base_var_enum_verbose_vfs (pmix_mca_base_var_enum_t *self, const char *string_value,
136 int *value)
137 {
138 char *tmp;
139 int v;
140
141
142 string_value += strspn (string_value, " \t\n\v\f\r");
143
144 v = strtol (string_value, &tmp, 10);
145 if (*tmp != '\0') {
146 for (int i = 0 ; verbose_values[i].string ; ++i) {
147 if (0 == strcmp (verbose_values[i].string, string_value)) {
148 *value = verbose_values[i].value;
149 return PMIX_SUCCESS;
150 }
151 }
152
153 return PMIX_ERR_NOT_FOUND;
154 } else if (v < PMIX_MCA_BASE_VERBOSE_NONE) {
155 v = PMIX_MCA_BASE_VERBOSE_NONE;
156 } else if (v > PMIX_MCA_BASE_VERBOSE_MAX) {
157 v = PMIX_MCA_BASE_VERBOSE_MAX;
158 }
159
160 *value = v;
161
162 return PMIX_SUCCESS;
163 }
164
165 static int pmix_mca_base_var_enum_verbose_sfv (pmix_mca_base_var_enum_t *self, const int value,
166 char **string_value)
167 {
168 int ret;
169
170 if (value < 0 || value > 100) {
171 return PMIX_ERR_VALUE_OUT_OF_BOUNDS;
172 }
173
174 for (int i = 0 ; verbose_values[i].string ; ++i) {
175 if (verbose_values[i].value == value) {
176 *string_value = strdup (verbose_values[i].string);
177 return PMIX_SUCCESS;
178 }
179 }
180
181 if (string_value) {
182 ret = asprintf (string_value, "%d", value);
183 if (0 > ret) {
184 return PMIX_ERR_OUT_OF_RESOURCE;
185 }
186 }
187
188 return PMIX_SUCCESS;
189 }
190
191 static int pmix_mca_base_var_enum_verbose_dump (pmix_mca_base_var_enum_t *self, char **out)
192 {
193 char *tmp;
194 int ret;
195
196 ret = enum_dump (self, out);
197 if (PMIX_SUCCESS != ret) {
198 return ret;
199 }
200
201 ret = asprintf (&tmp, "%s, 0 - 100", *out);
202 free (*out);
203 if (0 > ret) {
204 *out = NULL;
205 return PMIX_ERR_OUT_OF_RESOURCE;
206 }
207
208 *out = tmp;
209
210 return PMIX_SUCCESS;
211 }
212
213 pmix_mca_base_var_enum_t pmix_mca_base_var_enum_verbose = {
214 .super = PMIX_OBJ_STATIC_INIT(pmix_object_t),
215 .enum_is_static = true,
216 .enum_name = "verbosity",
217 .get_count = enum_get_count,
218 .get_value = enum_get_value,
219 .value_from_string = pmix_mca_base_var_enum_verbose_vfs,
220 .string_from_value = pmix_mca_base_var_enum_verbose_sfv,
221 .dump = pmix_mca_base_var_enum_verbose_dump,
222 .enum_value_count = 8,
223 .enum_values = verbose_values,
224 };
225
226
227 int pmix_mca_base_var_enum_create (const char *name, const pmix_mca_base_var_enum_value_t *values, pmix_mca_base_var_enum_t **enumerator)
228 {
229 pmix_mca_base_var_enum_t *new_enum;
230 int i;
231
232 *enumerator = NULL;
233
234 new_enum = PMIX_NEW(pmix_mca_base_var_enum_t);
235 if (NULL == new_enum) {
236 return PMIX_ERR_OUT_OF_RESOURCE;
237 }
238
239 new_enum->enum_name = strdup (name);
240 if (NULL == new_enum->enum_name) {
241 return PMIX_ERR_OUT_OF_RESOURCE;
242 }
243
244 for (i = 0 ; values[i].string ; ++i);
245 new_enum->enum_value_count = i;
246
247
248 new_enum->enum_values = calloc (new_enum->enum_value_count + 1, sizeof (*new_enum->enum_values));
249 if (NULL == new_enum->enum_values) {
250 PMIX_RELEASE(new_enum);
251 return PMIX_ERR_OUT_OF_RESOURCE;
252 }
253
254 for (i = 0 ; i < new_enum->enum_value_count ; ++i) {
255 new_enum->enum_values[i].value = values[i].value;
256 new_enum->enum_values[i].string = strdup (values[i].string);
257 }
258
259 *enumerator = new_enum;
260
261 return PMIX_SUCCESS;
262 }
263
264 int pmix_mca_base_var_enum_create_flag (const char *name, const pmix_mca_base_var_enum_value_flag_t *flags, pmix_mca_base_var_enum_flag_t **enumerator)
265 {
266 pmix_mca_base_var_enum_flag_t *new_enum;
267 int i;
268
269 *enumerator = NULL;
270
271 new_enum = PMIX_NEW(pmix_mca_base_var_enum_flag_t);
272 if (NULL == new_enum) {
273 return PMIX_ERR_OUT_OF_RESOURCE;
274 }
275
276 new_enum->super.enum_name = strdup (name);
277 if (NULL == new_enum->super.enum_name) {
278 return PMIX_ERR_OUT_OF_RESOURCE;
279 }
280
281 for (i = 0 ; flags[i].string ; ++i);
282 new_enum->super.enum_value_count = i;
283
284
285 new_enum->enum_flags = calloc (new_enum->super.enum_value_count + 1, sizeof (*new_enum->enum_flags));
286 if (NULL == new_enum->enum_flags) {
287 PMIX_RELEASE(new_enum);
288 return PMIX_ERR_OUT_OF_RESOURCE;
289 }
290
291 int all_flags = 0;
292 for (i = 0 ; i < new_enum->super.enum_value_count ; ++i) {
293 new_enum->enum_flags[i].flag = flags[i].flag;
294 new_enum->enum_flags[i].string = strdup (flags[i].string);
295 new_enum->enum_flags[i].conflicting_flag = flags[i].conflicting_flag;
296
297
298 assert (!(flags[i].flag & (flags[i].flag - 1)));
299 assert (!(flags[i].flag & flags[i].conflicting_flag));
300 assert (!(all_flags & flags[i].flag));
301 assert (flags[i].flag);
302 all_flags |= flags[i].flag;
303 }
304
305 *enumerator = new_enum;
306
307 return PMIX_SUCCESS;
308 }
309
310 static int enum_dump (pmix_mca_base_var_enum_t *self, char **out)
311 {
312 int i;
313 char *tmp;
314 int ret;
315
316 *out = NULL;
317
318 if (NULL == self) {
319 return PMIX_ERROR;
320 }
321
322 tmp = NULL;
323 for (i = 0; i < self->enum_value_count && self->enum_values[i].string ; ++i) {
324 ret = asprintf (out, "%s%s%d:\"%s\"", tmp ? tmp : "", tmp ? ", " : "", self->enum_values[i].value,
325 self->enum_values[i].string);
326 if (tmp) free (tmp);
327 if (0 > ret) {
328 return PMIX_ERR_OUT_OF_RESOURCE;
329 }
330 tmp = *out;
331 }
332
333 return PMIX_SUCCESS;
334 }
335
336 static int enum_get_count (pmix_mca_base_var_enum_t *self, int *count)
337 {
338 *count = self->enum_value_count;
339 return PMIX_SUCCESS;
340 }
341
342 static int enum_get_value (pmix_mca_base_var_enum_t *self, int index, int *value, const char **string_value)
343 {
344 int count, ret;
345
346 ret = self->get_count(self, &count);
347 if (PMIX_SUCCESS != ret) {
348 return ret;
349 }
350
351 if (index >= count) {
352 return PMIX_ERR_VALUE_OUT_OF_BOUNDS;
353 }
354
355 if (value) {
356 *value = self->enum_values[index].value;
357 }
358
359 if (string_value) {
360 *string_value = strdup (self->enum_values[index].string);
361 }
362
363 return PMIX_SUCCESS;
364 }
365
366 static int enum_value_from_string(pmix_mca_base_var_enum_t *self, const char *string_value, int *value_out) {
367 int value, count, ret, i;
368 bool is_int;
369 char *tmp;
370
371 ret = self->get_count(self, &count);
372 if (PMIX_SUCCESS != ret) {
373 return ret;
374 }
375
376 value = strtol(string_value, &tmp, 0);
377
378
379 is_int = tmp[0] == '\0';
380
381 for (i = 0 ; i < count ; ++i) {
382 if ((is_int && value == self->enum_values[i].value) ||
383 0 == strcasecmp (string_value, self->enum_values[i].string)) {
384 break;
385 }
386 }
387
388 if (i == count) {
389 return PMIX_ERR_VALUE_OUT_OF_BOUNDS;
390 }
391
392 *value_out = self->enum_values[i].value;
393
394 return PMIX_SUCCESS;
395 }
396
397 static int enum_string_from_value(pmix_mca_base_var_enum_t *self, const int value, char **string_value) {
398 int count, ret, i;
399
400 ret = self->get_count(self, &count);
401 if (PMIX_SUCCESS != ret) {
402 return ret;
403 }
404
405 for (i = 0 ; i < count ; ++i) {
406 if (value == self->enum_values[i].value) {
407 break;
408 }
409 }
410
411 if (i == count) {
412 return PMIX_ERR_VALUE_OUT_OF_BOUNDS;
413 }
414
415 if (string_value) {
416 *string_value = strdup (self->enum_values[i].string);
417 }
418
419 return PMIX_SUCCESS;
420 }
421
422 static void pmix_mca_base_var_enum_constructor (pmix_mca_base_var_enum_t *enumerator)
423 {
424 memset ((char *) enumerator + sizeof (enumerator->super), 0 , sizeof(*enumerator) - sizeof(enumerator->super));
425
426 enumerator->get_value = enum_get_value;
427 enumerator->get_count = enum_get_count;
428 enumerator->value_from_string = enum_value_from_string;
429 enumerator->string_from_value = enum_string_from_value;
430 enumerator->dump = enum_dump;
431 enumerator->enum_is_static = false;
432 }
433
434 static void pmix_mca_base_var_enum_destructor (pmix_mca_base_var_enum_t *enumerator)
435 {
436 if (enumerator->enum_name) {
437 free (enumerator->enum_name);
438 }
439
440
441 if (enumerator->enum_values) {
442 for (int i = 0 ; i < enumerator->enum_value_count ; ++i) {
443 free ((void *) enumerator->enum_values[i].string);
444 }
445 free (enumerator->enum_values);
446 }
447 }
448
449 static int enum_get_value_flag (pmix_mca_base_var_enum_t *self, int index, int *value, const char **string_value)
450 {
451 pmix_mca_base_var_enum_flag_t *flag_enum = (pmix_mca_base_var_enum_flag_t *) self;
452 int count, ret;
453
454 ret = self->get_count(self, &count);
455 if (PMIX_SUCCESS != ret) {
456 return ret;
457 }
458
459 if (index >= count) {
460 return PMIX_ERR_VALUE_OUT_OF_BOUNDS;
461 }
462
463 if (value) {
464 *value = flag_enum->enum_flags[index].flag;
465 }
466
467 if (string_value) {
468 *string_value = strdup (flag_enum->enum_flags[index].string);
469 }
470
471 return PMIX_SUCCESS;
472 }
473
474 static int enum_value_from_string_flag (pmix_mca_base_var_enum_t *self, const char *string_value, int *value_out) {
475 pmix_mca_base_var_enum_flag_t *flag_enum = (pmix_mca_base_var_enum_flag_t *) self;
476 int value, count, ret, flag;
477 char **flags;
478 bool is_int;
479 char *tmp;
480
481 ret = self->get_count(self, &count);
482 if (PMIX_SUCCESS != ret) {
483 return ret;
484 }
485
486 flags = pmix_argv_split (string_value, ',');
487 if (NULL == flags) {
488 return PMIX_ERR_BAD_PARAM;
489 }
490
491 flag = 0;
492
493 for (int i = 0 ; flags[i] ; ++i) {
494 value = strtol (flags[i], &tmp, 0);
495 is_int = tmp[0] == '\0';
496
497 bool found = false, conflict = false;
498 for (int j = 0 ; j < count ; ++j) {
499 if ((is_int && (value == flag_enum->enum_flags[i].flag)) ||
500 0 == strcasecmp (flags[i], flag_enum->enum_flags[i].string)) {
501 found = true;
502
503 if (flag & flag_enum->enum_flags[i].conflicting_flag) {
504 conflict = true;
505 } else {
506 flag |= flag_enum->enum_flags[i].flag;
507 }
508
509 break;
510 }
511 }
512
513 if (!found || conflict) {
514 pmix_argv_free (flags);
515 return !found ? PMIX_ERR_VALUE_OUT_OF_BOUNDS : PMIX_ERR_BAD_PARAM;
516 }
517 }
518
519 pmix_argv_free (flags);
520 *value_out = flag;
521
522 return PMIX_SUCCESS;
523 }
524
525 static int enum_string_from_value_flag (pmix_mca_base_var_enum_t *self, const int value, char **string_value) {
526 pmix_mca_base_var_enum_flag_t *flag_enum = (pmix_mca_base_var_enum_flag_t *) self;
527 int count, ret, current;
528 char *out = NULL, *tmp;
529
530 ret = self->get_count(self, &count);
531 if (PMIX_SUCCESS != ret) {
532 return ret;
533 }
534
535 current = value;
536 for (int i = 0 ; i < count ; ++i) {
537 if (!(flag_enum->enum_flags[i].flag & current)) {
538 continue;
539 }
540
541 tmp = out;
542
543 ret = asprintf (&out, "%s%s%s", tmp ? tmp : "", tmp ? "," : "", flag_enum->enum_flags[i].string);
544 free (tmp);
545
546 if (0 > ret) {
547 return PMIX_ERR_OUT_OF_RESOURCE;
548 }
549
550 if (value & flag_enum->enum_flags[i].conflicting_flag) {
551 free (out);
552 return PMIX_ERR_BAD_PARAM;
553 }
554
555 current &= ~flag_enum->enum_flags[i].flag;
556 }
557
558 if (current) {
559 free (out);
560 return PMIX_ERR_VALUE_OUT_OF_BOUNDS;
561 }
562
563 if (string_value) {
564 *string_value = out ? out : strdup ("");
565 } else {
566 free (out);
567 }
568
569 return PMIX_SUCCESS;
570 }
571
572 static int enum_dump_flag (pmix_mca_base_var_enum_t *self, char **out)
573 {
574 pmix_mca_base_var_enum_flag_t *flag_enum = (pmix_mca_base_var_enum_flag_t *) self;
575 char *tmp;
576 int ret;
577
578 *out = NULL;
579
580 if (NULL == self) {
581 return PMIX_ERROR;
582 }
583
584 *out = strdup ("Comma-delimited list of: ");
585 if (NULL == *out) {
586 return PMIX_ERR_OUT_OF_RESOURCE;
587 }
588
589 for (int i = 0; i < self->enum_value_count ; ++i) {
590 tmp = *out;
591
592 ret = asprintf (out, "%s%s0x%x:\"%s\"", tmp, i ? ", " : " ", flag_enum->enum_flags[i].flag,
593 flag_enum->enum_flags[i].string);
594 free (tmp);
595 if (0 > ret) {
596 return PMIX_ERR_OUT_OF_RESOURCE;
597 }
598 }
599
600 return PMIX_SUCCESS;
601 }
602
603 static void pmix_mca_base_var_enum_flag_constructor (pmix_mca_base_var_enum_flag_t *enumerator)
604 {
605 enumerator->enum_flags = NULL;
606 enumerator->super.get_value = enum_get_value_flag;
607 enumerator->super.get_count = enum_get_count;
608 enumerator->super.value_from_string = enum_value_from_string_flag;
609 enumerator->super.string_from_value = enum_string_from_value_flag;
610 enumerator->super.dump = enum_dump_flag;
611 enumerator->super.enum_is_static = false;
612 }
613
614 static void pmix_mca_base_var_enum_flag_destructor (pmix_mca_base_var_enum_flag_t *enumerator)
615 {
616
617 if (enumerator->enum_flags) {
618 for (int i = 0 ; i < enumerator->super.enum_value_count ; ++i) {
619 free ((void *) enumerator->enum_flags[i].string);
620 }
621 free (enumerator->enum_flags);
622 }
623 }