This source file includes following definitions.
- pmix_mca_base_var_source_file
- pmix_mca_base_var_generate_full_name4
- compare_strings
- append_filename_to_list
- pmix_mca_base_var_init
- process_env_list
- pmix_mca_base_var_process_env_list
- pmix_mca_base_var_process_env_list_from_file
- resolve_relative_paths
- pmix_mca_base_var_cache_files
- pmix_mca_base_var_get_value
- var_set_string
- int_from_string
- var_set_from_string
- pmix_mca_base_var_set_value
- pmix_mca_base_var_deregister
- var_get
- pmix_mca_base_var_env_name
- var_find_by_name
- var_find
- pmix_mca_base_var_find
- pmix_mca_base_var_find_by_name
- pmix_mca_base_var_set_flag
- pmix_mca_base_var_get
- pmix_mca_base_var_build_env
- pmix_mca_base_var_finalize
- fixup_files
- read_files
- register_variable
- pmix_mca_base_var_register
- pmix_mca_base_component_var_register
- pmix_mca_base_framework_var_register
- pmix_mca_base_var_register_synonym
- var_get_env
- var_set_from_env
- var_set_from_file
- var_set_initial
- var_constructor
- var_destructor
- fv_constructor
- fv_destructor
- source_name
- var_value_string
- pmix_mca_base_var_check_exclusive
- pmix_mca_base_var_get_count
- pmix_mca_base_var_dump
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include <src/include/pmix_config.h>
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34 #ifdef HAVE_SYS_PARAM_H
35 #include <sys/param.h>
36 #endif
37 #include <errno.h>
38
39 #include "src/include/pmix_stdint.h"
40 #include "src/mca/pinstalldirs/pinstalldirs.h"
41 #include "src/util/os_path.h"
42 #include "src/util/path.h"
43 #include "src/util/show_help.h"
44 #include "src/util/printf.h"
45 #include "src/util/argv.h"
46 #include "src/util/error.h"
47 #include "src/mca/mca.h"
48 #include "src/mca/base/pmix_mca_base_vari.h"
49 #include "pmix_common.h"
50 #include "src/util/output.h"
51 #include "src/util/pmix_environ.h"
52
53
54
55
56 static pmix_pointer_array_t pmix_mca_base_vars;
57 static const char *mca_prefix = "PMIX_MCA_";
58 static char *home = NULL;
59 static char *cwd = NULL;
60 bool pmix_mca_base_var_initialized = false;
61 static char * force_agg_path = NULL;
62 static char *pmix_mca_base_var_files = NULL;
63 static char *pmix_mca_base_envar_files = NULL;
64 static char **pmix_mca_base_var_file_list = NULL;
65 static char *pmix_mca_base_var_override_file = NULL;
66 static char *pmix_mca_base_var_file_prefix = NULL;
67 static char *pmix_mca_base_envar_file_prefix = NULL;
68 static char *pmix_mca_base_param_file_path = NULL;
69 static char *pmix_mca_base_env_list = NULL;
70 #define PMIX_MCA_BASE_ENV_LIST_SEP_DEFAULT ";"
71 static char *pmix_mca_base_env_list_sep = PMIX_MCA_BASE_ENV_LIST_SEP_DEFAULT;
72 static char *pmix_mca_base_env_list_internal = NULL;
73 static bool pmix_mca_base_var_suppress_override_warning = false;
74 static pmix_list_t pmix_mca_base_var_file_values;
75 static pmix_list_t pmix_mca_base_envar_file_values;
76 static pmix_list_t pmix_mca_base_var_override_values;
77
78 static int pmix_mca_base_var_count = 0;
79
80 static pmix_hash_table_t pmix_mca_base_var_index_hash;
81
82 const char *pmix_var_type_names[] = {
83 "int",
84 "unsigned_int",
85 "unsigned_long",
86 "unsigned_long_long",
87 "size_t",
88 "string",
89 "version_string",
90 "bool",
91 "double"
92 };
93
94 const size_t pmix_var_type_sizes[] = {
95 sizeof (int),
96 sizeof (unsigned),
97 sizeof (unsigned long),
98 sizeof (unsigned long long),
99 sizeof (size_t),
100 sizeof (char),
101 sizeof (char),
102 sizeof (bool),
103 sizeof (double)
104 };
105
106 const char *pmix_var_source_names[] = {
107 "default",
108 "command line",
109 "environment",
110 "file",
111 "set",
112 "override"
113 };
114
115
116 static const char *info_lvl_strings[] = {
117 "user/basic",
118 "user/detail",
119 "user/all",
120 "tuner/basic",
121 "tuner/detail",
122 "tuner/all",
123 "dev/basic",
124 "dev/detail",
125 "dev/all"
126 };
127
128
129
130
131 static int fixup_files(char **file_list, char * path, bool rel_path_search, char sep);
132 static int read_files (char *file_list, pmix_list_t *file_values, char sep);
133 static int var_set_initial (pmix_mca_base_var_t *var, pmix_mca_base_var_t *original);
134 static int var_get (int vari, pmix_mca_base_var_t **var_out, bool original);
135 static int var_value_string (pmix_mca_base_var_t *var, char **value_string);
136
137
138
139
140 static void var_constructor (pmix_mca_base_var_t *p);
141 static void var_destructor (pmix_mca_base_var_t *p);
142 PMIX_CLASS_INSTANCE(pmix_mca_base_var_t, pmix_object_t,
143 var_constructor, var_destructor);
144
145 static void fv_constructor (pmix_mca_base_var_file_value_t *p);
146 static void fv_destructor (pmix_mca_base_var_file_value_t *p);
147 PMIX_CLASS_INSTANCE(pmix_mca_base_var_file_value_t, pmix_list_item_t,
148 fv_constructor, fv_destructor);
149
150 static const char *pmix_mca_base_var_source_file (const pmix_mca_base_var_t *var)
151 {
152 pmix_mca_base_var_file_value_t *fv = (pmix_mca_base_var_file_value_t *) var->mbv_file_value;
153
154 if (NULL != var->mbv_source_file) {
155 return var->mbv_source_file;
156 }
157
158 if (fv) {
159 return fv->mbvfv_file;
160 }
161
162 return NULL;
163 }
164
165
166
167
168 int pmix_mca_base_var_generate_full_name4 (const char *project, const char *framework, const char *component,
169 const char *variable, char **full_name)
170 {
171 const char * const names[] = {project, framework, component, variable};
172 char *name, *tmp;
173 size_t i, len;
174
175 *full_name = NULL;
176
177 for (i = 0, len = 0 ; i < 4 ; ++i) {
178 if (NULL != names[i]) {
179
180 len += strlen (names[i]) + 1;
181 }
182 }
183
184 name = calloc (1, len);
185 if (NULL == name) {
186 return PMIX_ERR_OUT_OF_RESOURCE;
187 }
188
189 for (i = 0, tmp = name ; i < 4 ; ++i) {
190 if (NULL != names[i]) {
191 if (name != tmp) {
192 *tmp++ = '_';
193 }
194 strncat (name, names[i], len - (size_t)(uintptr_t)(tmp - name));
195 tmp += strlen (names[i]);
196 }
197 }
198
199 *full_name = name;
200 return PMIX_SUCCESS;
201 }
202
203 static int compare_strings (const char *str1, const char *str2) {
204 if ((NULL != str1 && 0 == strcmp (str1, "*")) ||
205 (NULL == str1 && NULL == str2)) {
206 return 0;
207 }
208
209 if (NULL != str1 && NULL != str2) {
210 return strcmp (str1, str2);
211 }
212
213 return 1;
214 }
215
216
217
218
219
220 static char *append_filename_to_list(const char *filename)
221 {
222 int i, count;
223
224 (void) pmix_argv_append_unique_nosize(&pmix_mca_base_var_file_list, filename);
225
226 count = pmix_argv_count(pmix_mca_base_var_file_list);
227
228 for (i = count - 1; i >= 0; --i) {
229 if (0 == strcmp (pmix_mca_base_var_file_list[i], filename)) {
230 return pmix_mca_base_var_file_list[i];
231 }
232 }
233
234
235 return NULL;
236 }
237
238
239
240
241 int pmix_mca_base_var_init(void)
242 {
243 int ret;
244 char *name = NULL;
245
246 if (!pmix_mca_base_var_initialized) {
247
248
249 PMIX_CONSTRUCT(&pmix_mca_base_vars, pmix_pointer_array_t);
250
251 ret = pmix_pointer_array_init (&pmix_mca_base_vars, 128, 16384, 128);
252 if (PMIX_SUCCESS != ret) {
253 return ret;
254 }
255
256 pmix_mca_base_var_count = 0;
257
258
259
260 PMIX_CONSTRUCT(&pmix_mca_base_var_file_values, pmix_list_t);
261 PMIX_CONSTRUCT(&pmix_mca_base_envar_file_values, pmix_list_t);
262 PMIX_CONSTRUCT(&pmix_mca_base_var_override_values, pmix_list_t);
263 PMIX_CONSTRUCT(&pmix_mca_base_var_index_hash, pmix_hash_table_t);
264
265 ret = pmix_hash_table_init (&pmix_mca_base_var_index_hash, 1024);
266 if (PMIX_SUCCESS != ret) {
267 return ret;
268 }
269
270 ret = pmix_mca_base_var_group_init ();
271 if (PMIX_SUCCESS != ret) {
272 return ret;
273 }
274
275
276
277 pmix_mca_base_var_initialized = true;
278
279 pmix_mca_base_var_cache_files(false);
280
281
282 (void)pmix_mca_base_var_register ("pmix", "mca", "base", "env_list",
283 "Set SHELL env variables",
284 PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_3,
285 PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_env_list);
286
287 pmix_mca_base_env_list_sep = PMIX_MCA_BASE_ENV_LIST_SEP_DEFAULT;
288 (void)pmix_mca_base_var_register ("pmix", "mca", "base", "env_list_delimiter",
289 "Set SHELL env variables delimiter. Default: semicolon ';'",
290 PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_3,
291 PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_env_list_sep);
292
293
294
295
296
297
298 if (NULL != pmix_mca_base_env_list) {
299 (void) pmix_mca_base_var_env_name ("pmix_mca_base_env_list", &name);
300 if (NULL != name) {
301 pmix_setenv(name, pmix_mca_base_env_list, false, &environ);
302 free(name);
303 }
304 }
305
306
307
308
309
310 (void)pmix_mca_base_var_register ("pmix", "mca", "base", "env_list_internal",
311 "Store SHELL env variables from amca conf file",
312 PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, PMIX_MCA_BASE_VAR_FLAG_INTERNAL, PMIX_INFO_LVL_3,
313 PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_env_list_internal);
314 }
315
316 return PMIX_SUCCESS;
317 }
318
319 static void process_env_list(char *env_list, char ***argv, char sep)
320 {
321 char** tokens;
322 char *ptr, *value;
323
324 tokens = pmix_argv_split(env_list, (int)sep);
325 if (NULL == tokens) {
326 return;
327 }
328
329 for (int i = 0 ; NULL != tokens[i] ; ++i) {
330 if (NULL == (ptr = strchr(tokens[i], '='))) {
331 value = getenv(tokens[i]);
332 if (NULL == value) {
333 pmix_show_help("help-pmix-mca-var.txt", "incorrect-env-list-param",
334 true, tokens[i], env_list);
335 break;
336 }
337
338
339 value = strdup (value);
340 if (NULL == value) {
341
342 break;
343 }
344
345 if (NULL != (ptr = strchr(value, '='))) {
346 *ptr = '\0';
347 pmix_setenv(value, ptr + 1, true, argv);
348 } else {
349 pmix_setenv(tokens[i], value, true, argv);
350 }
351
352 free (value);
353 } else {
354 *ptr = '\0';
355 pmix_setenv(tokens[i], ptr + 1, true, argv);
356
357 }
358 }
359
360 pmix_argv_free(tokens);
361 }
362
363 int pmix_mca_base_var_process_env_list(char ***argv)
364 {
365 char sep;
366 sep = ';';
367 if (NULL != pmix_mca_base_env_list_sep) {
368 if (1 == strlen(pmix_mca_base_env_list_sep)) {
369 sep = pmix_mca_base_env_list_sep[0];
370 } else {
371 pmix_show_help("help-pmix-mca-var.txt", "incorrect-env-list-sep",
372 true, pmix_mca_base_env_list_sep);
373 return PMIX_SUCCESS;
374 }
375 }
376 if (NULL != pmix_mca_base_env_list) {
377 process_env_list(pmix_mca_base_env_list, argv, sep);
378 }
379
380 return PMIX_SUCCESS;
381 }
382
383 int pmix_mca_base_var_process_env_list_from_file(char ***argv)
384 {
385 if (NULL != pmix_mca_base_env_list_internal) {
386 process_env_list(pmix_mca_base_env_list_internal, argv, ';');
387 }
388 return PMIX_SUCCESS;
389 }
390
391 static void resolve_relative_paths(char **file_prefix, char *file_path, bool rel_path_search, char **files, char sep)
392 {
393 char *tmp_str;
394
395
396
397
398 if( PMIX_SUCCESS != fixup_files(file_prefix, file_path, rel_path_search, sep) ) {
399 #if 0
400
401 abort();
402 #else
403 ;
404 #endif
405 }
406 else {
407
408 if (0 > asprintf(&tmp_str, "%s%c%s", *file_prefix, sep, *files)) {
409 pmix_output(0, "OUT OF MEM");
410 free(*files);
411 free(tmp_str);
412 *files = NULL;
413 return;
414 }
415 free (*files);
416 *files = tmp_str;
417 }
418 }
419
420 int pmix_mca_base_var_cache_files(bool rel_path_search)
421 {
422 char *tmp;
423 int ret;
424
425
426 home = (char*)pmix_home_directory();
427
428 if(NULL == cwd) {
429 cwd = (char *) malloc(sizeof(char) * MAXPATHLEN);
430 if( NULL == (cwd = getcwd(cwd, MAXPATHLEN) )) {
431 pmix_output(0, "Error: Unable to get the current working directory\n");
432 cwd = strdup(".");
433 }
434 }
435
436 #if PMIX_WANT_HOME_CONFIG_FILES
437 ret = asprintf(&pmix_mca_base_var_files, "%s"PMIX_PATH_SEP".pmix" PMIX_PATH_SEP
438 "mca-params.conf%c%s" PMIX_PATH_SEP "pmix-mca-params.conf",
439 home, ',', pmix_pinstall_dirs.sysconfdir);
440 #else
441 ret = asprintf(&pmix_mca_base_var_files, "%s" PMIX_PATH_SEP "pmix-mca-params.conf",
442 pmix_pinstall_dirs.sysconfdir);
443 #endif
444 if (0 > ret) {
445 return PMIX_ERR_OUT_OF_RESOURCE;
446 }
447
448
449
450 tmp = pmix_mca_base_var_files;
451 ret = pmix_mca_base_var_register ("pmix", "mca", "base", "param_files", "Path for MCA "
452 "configuration files containing variable values",
453 PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_2,
454 PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_var_files);
455 free (tmp);
456 if (PMIX_SUCCESS != ret) {
457 return ret;
458 }
459
460 pmix_mca_base_envar_files = strdup(pmix_mca_base_var_files);
461
462 (void) pmix_mca_base_var_register_synonym (ret, "pmix", "mca", NULL, "param_files",
463 PMIX_MCA_BASE_VAR_SYN_FLAG_DEPRECATED);
464
465 ret = asprintf(&pmix_mca_base_var_override_file, "%s" PMIX_PATH_SEP "pmix-mca-params-override.conf",
466 pmix_pinstall_dirs.sysconfdir);
467 if (0 > ret) {
468 return PMIX_ERR_OUT_OF_RESOURCE;
469 }
470
471 tmp = pmix_mca_base_var_override_file;
472 ret = pmix_mca_base_var_register ("pmix", "mca", "base", "override_param_file",
473 "Variables set in this file will override any value set in"
474 "the environment or another configuration file",
475 PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY,
476 PMIX_INFO_LVL_2, PMIX_MCA_BASE_VAR_SCOPE_CONSTANT,
477 &pmix_mca_base_var_override_file);
478 free (tmp);
479 if (0 > ret) {
480 return ret;
481 }
482
483
484 if (0 == strcmp (pmix_mca_base_var_files, "none")) {
485 return PMIX_SUCCESS;
486 }
487
488 pmix_mca_base_var_suppress_override_warning = false;
489 ret = pmix_mca_base_var_register ("pmix", "mca", "base", "suppress_override_warning",
490 "Suppress warnings when attempting to set an overridden value (default: false)",
491 PMIX_MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0, PMIX_INFO_LVL_2,
492 PMIX_MCA_BASE_VAR_SCOPE_LOCAL, &pmix_mca_base_var_suppress_override_warning);
493 if (0 > ret) {
494 return ret;
495 }
496
497
498
499
500
501 pmix_mca_base_var_file_prefix = NULL;
502 ret = pmix_mca_base_var_register ("pmix", "mca", "base", "param_file_prefix",
503 "Aggregate MCA parameter file sets",
504 PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_3,
505 PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_var_file_prefix);
506 if (0 > ret) {
507 return ret;
508 }
509
510 pmix_mca_base_envar_file_prefix = NULL;
511 ret = pmix_mca_base_var_register ("pmix", "mca", "base", "envar_file_prefix",
512 "Aggregate MCA parameter file set for env variables",
513 PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_3,
514 PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_envar_file_prefix);
515 if (0 > ret) {
516 return ret;
517 }
518
519 ret = asprintf(&pmix_mca_base_param_file_path, "%s" PMIX_PATH_SEP "amca-param-sets%c%s",
520 pmix_pinstall_dirs.pmixdatadir, PMIX_ENV_SEP, cwd);
521 if (0 > ret) {
522 return PMIX_ERR_OUT_OF_RESOURCE;
523 }
524
525 tmp = pmix_mca_base_param_file_path;
526 ret = pmix_mca_base_var_register ("pmix", "mca", "base", "param_file_path",
527 "Aggregate MCA parameter Search path",
528 PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_3,
529 PMIX_MCA_BASE_VAR_SCOPE_READONLY, &pmix_mca_base_param_file_path);
530 free (tmp);
531 if (0 > ret) {
532 return ret;
533 }
534
535 force_agg_path = NULL;
536 ret = pmix_mca_base_var_register ("pmix", "mca", "base", "param_file_path_force",
537 "Forced Aggregate MCA parameter Search path",
538 PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, PMIX_INFO_LVL_3,
539 PMIX_MCA_BASE_VAR_SCOPE_READONLY, &force_agg_path);
540 if (0 > ret) {
541 return ret;
542 }
543
544 if (NULL != force_agg_path) {
545 if (NULL != pmix_mca_base_param_file_path) {
546 char *tmp_str = pmix_mca_base_param_file_path;
547
548 ret = asprintf(&pmix_mca_base_param_file_path, "%s%c%s", force_agg_path, PMIX_ENV_SEP, tmp_str);
549 free(tmp_str);
550 if (0 > ret) {
551 return PMIX_ERR_OUT_OF_RESOURCE;
552 }
553 } else {
554 pmix_mca_base_param_file_path = strdup(force_agg_path);
555 }
556 }
557
558 if (NULL != pmix_mca_base_var_file_prefix) {
559 resolve_relative_paths(&pmix_mca_base_var_file_prefix, pmix_mca_base_param_file_path, rel_path_search, &pmix_mca_base_var_files, PMIX_ENV_SEP);
560 }
561 read_files (pmix_mca_base_var_files, &pmix_mca_base_var_file_values, ',');
562
563 if (NULL != pmix_mca_base_envar_file_prefix) {
564 resolve_relative_paths(&pmix_mca_base_envar_file_prefix, pmix_mca_base_param_file_path, rel_path_search, &pmix_mca_base_envar_files, ',');
565 }
566 read_files (pmix_mca_base_envar_files, &pmix_mca_base_envar_file_values, ',');
567
568 if (0 == access(pmix_mca_base_var_override_file, F_OK)) {
569 read_files (pmix_mca_base_var_override_file, &pmix_mca_base_var_override_values, PMIX_ENV_SEP);
570 }
571
572 return PMIX_SUCCESS;
573 }
574
575
576
577
578 int pmix_mca_base_var_get_value (int vari, void *value,
579 pmix_mca_base_var_source_t *source,
580 const char **source_file)
581 {
582 pmix_mca_base_var_t *var;
583 void **tmp = (void **) value;
584 int ret;
585
586 ret = var_get (vari, &var, true);
587 if (PMIX_SUCCESS != ret) {
588 return ret;
589 }
590
591 if (!PMIX_VAR_IS_VALID(var[0])) {
592 return PMIX_ERR_NOT_FOUND;
593 }
594
595 if (NULL != value) {
596
597
598 *tmp = var->mbv_storage;
599 }
600
601 if (NULL != source) {
602 *source = var->mbv_source;
603 }
604
605 if (NULL != source_file) {
606 *source_file = pmix_mca_base_var_source_file (var);
607 }
608
609 return PMIX_SUCCESS;
610 }
611
612 static int var_set_string (pmix_mca_base_var_t *var, char *value)
613 {
614 char *tmp;
615 int ret;
616
617 if (NULL != var->mbv_storage->stringval) {
618 free (var->mbv_storage->stringval);
619 }
620
621 var->mbv_storage->stringval = NULL;
622
623 if (NULL == value || 0 == strlen (value)) {
624 return PMIX_SUCCESS;
625 }
626
627
628
629
630 if (0 == strncmp (value, "~/", 2)) {
631 if (NULL != home) {
632 ret = asprintf (&value, "%s/%s", home, value + 2);
633 if (0 > ret) {
634 return PMIX_ERROR;
635 }
636 } else {
637 value = strdup (value + 2);
638 }
639 } else {
640 value = strdup (value);
641 }
642
643 if (NULL == value) {
644 return PMIX_ERR_OUT_OF_RESOURCE;
645 }
646
647 while (NULL != (tmp = strstr (value, ":~/"))) {
648 tmp[0] = '\0';
649 tmp += 3;
650
651 ret = asprintf (&tmp, "%s:%s%s%s", value,
652 home ? home : "", home ? "/" : "", tmp);
653
654 free (value);
655
656 if (0 > ret) {
657 return PMIX_ERR_OUT_OF_RESOURCE;
658 }
659
660 value = tmp;
661 }
662
663 var->mbv_storage->stringval = value;
664
665 return PMIX_SUCCESS;
666 }
667
668 static int int_from_string(const char *src, pmix_mca_base_var_enum_t *enumerator, uint64_t *value_out)
669 {
670 uint64_t value;
671 bool is_int;
672 char *tmp;
673
674 if (NULL == src || 0 == strlen (src)) {
675 if (NULL == enumerator) {
676 *value_out = 0;
677 }
678
679 return PMIX_SUCCESS;
680 }
681
682 if (enumerator) {
683 int int_val, ret;
684 ret = enumerator->value_from_string(enumerator, src, &int_val);
685 if (PMIX_SUCCESS != ret) {
686 return ret;
687 }
688 *value_out = (uint64_t) int_val;
689
690 return PMIX_SUCCESS;
691 }
692
693
694 value = strtoull (src, &tmp, 0);
695 if (tmp[0] == '\0') {
696 is_int = true;
697 } else {
698 is_int = false;
699 }
700
701 if (!is_int && tmp != src) {
702 switch (tmp[0]) {
703 case 'G':
704 case 'g':
705 value <<= 30;
706 break;
707 case 'M':
708 case 'm':
709 value <<= 20;
710 break;
711 case 'K':
712 case 'k':
713 value <<= 10;
714 break;
715 default:
716 break;
717 }
718 }
719
720 *value_out = value;
721
722 return PMIX_SUCCESS;
723 }
724
725 static int var_set_from_string (pmix_mca_base_var_t *var, char *src)
726 {
727 pmix_mca_base_var_storage_t *dst = var->mbv_storage;
728 uint64_t int_value = 0;
729 int ret;
730
731 switch (var->mbv_type) {
732 case PMIX_MCA_BASE_VAR_TYPE_INT:
733 case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT:
734 case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG:
735 case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG:
736 case PMIX_MCA_BASE_VAR_TYPE_BOOL:
737 case PMIX_MCA_BASE_VAR_TYPE_SIZE_T:
738 ret = int_from_string(src, var->mbv_enumerator, &int_value);
739 if (PMIX_ERR_VALUE_OUT_OF_BOUNDS == ret ||
740 (PMIX_MCA_BASE_VAR_TYPE_INT == var->mbv_type && ((int) int_value != (int64_t) int_value)) ||
741 (PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT == var->mbv_type && ((unsigned int) int_value != int_value))) {
742 if (var->mbv_enumerator) {
743 char *valid_values;
744 (void) var->mbv_enumerator->dump(var->mbv_enumerator, &valid_values);
745 pmix_show_help("help-pmix-mca-var.txt", "invalid-value-enum",
746 true, var->mbv_full_name, src, valid_values);
747 free(valid_values);
748 } else {
749 pmix_show_help("help-pmix-mca-var.txt", "invalid-value",
750 true, var->mbv_full_name, src);
751 }
752
753 return PMIX_ERR_VALUE_OUT_OF_BOUNDS;
754 }
755
756 if (PMIX_MCA_BASE_VAR_TYPE_INT == var->mbv_type ||
757 PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT == var->mbv_type) {
758 int *castme = (int*) var->mbv_storage;
759 *castme = int_value;
760 } else if (PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG == var->mbv_type) {
761 unsigned long *castme = (unsigned long*) var->mbv_storage;
762 *castme = (unsigned long) int_value;
763 } else if (PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG == var->mbv_type) {
764 unsigned long long *castme = (unsigned long long*) var->mbv_storage;
765 *castme = (unsigned long long) int_value;
766 } else if (PMIX_MCA_BASE_VAR_TYPE_SIZE_T == var->mbv_type) {
767 size_t *castme = (size_t*) var->mbv_storage;
768 *castme = (size_t) int_value;
769 } else if (PMIX_MCA_BASE_VAR_TYPE_BOOL == var->mbv_type) {
770 bool *castme = (bool*) var->mbv_storage;
771 *castme = !!int_value;
772 }
773
774 return ret;
775 case PMIX_MCA_BASE_VAR_TYPE_DOUBLE:
776 dst->lfval = strtod (src, NULL);
777 break;
778 case PMIX_MCA_BASE_VAR_TYPE_STRING:
779 case PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING:
780 var_set_string (var, src);
781 break;
782 case PMIX_MCA_BASE_VAR_TYPE_MAX:
783 return PMIX_ERROR;
784 }
785
786 return PMIX_SUCCESS;
787 }
788
789
790
791
792 int pmix_mca_base_var_set_value (int vari, const void *value, size_t size, pmix_mca_base_var_source_t source,
793 const char *source_file)
794 {
795 pmix_mca_base_var_t *var;
796 int ret;
797
798 ret = var_get (vari, &var, true);
799 if (PMIX_SUCCESS != ret) {
800 return ret;
801 }
802
803 if (!PMIX_VAR_IS_VALID(var[0])) {
804 return PMIX_ERR_BAD_PARAM;
805 }
806
807 if (!PMIX_VAR_IS_SETTABLE(var[0])) {
808 return PMIX_ERR_PERM;
809 }
810
811 if (NULL != var->mbv_enumerator) {
812
813 ret = var->mbv_enumerator->string_from_value(var->mbv_enumerator,
814 ((int *) value)[0], NULL);
815 if (PMIX_SUCCESS != ret) {
816 return ret;
817 }
818 }
819
820 if (PMIX_MCA_BASE_VAR_TYPE_STRING != var->mbv_type && PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING != var->mbv_type) {
821 memmove (var->mbv_storage, value, pmix_var_type_sizes[var->mbv_type]);
822 } else {
823 var_set_string (var, (char *) value);
824 }
825
826 var->mbv_source = source;
827
828 if (PMIX_MCA_BASE_VAR_SOURCE_FILE == source && NULL != source_file) {
829 var->mbv_file_value = NULL;
830 var->mbv_source_file = append_filename_to_list(source_file);
831 }
832
833 return PMIX_SUCCESS;
834 }
835
836
837
838
839 int pmix_mca_base_var_deregister(int vari)
840 {
841 pmix_mca_base_var_t *var;
842 int ret;
843
844 ret = var_get (vari, &var, false);
845 if (PMIX_SUCCESS != ret) {
846 return ret;
847 }
848
849 if (!PMIX_VAR_IS_VALID(var[0])) {
850 return PMIX_ERR_BAD_PARAM;
851 }
852
853
854
855 var->mbv_flags &= ~PMIX_MCA_BASE_VAR_FLAG_VALID;
856
857
858 if (PMIX_MCA_BASE_VAR_FLAG_SYNONYM & var->mbv_flags) {
859 return PMIX_SUCCESS;
860 }
861
862
863 if ((PMIX_MCA_BASE_VAR_TYPE_STRING == var->mbv_type || PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type) &&
864 var->mbv_storage->stringval) {
865 free (var->mbv_storage->stringval);
866 var->mbv_storage->stringval = NULL;
867 } else if (var->mbv_enumerator && !var->mbv_enumerator->enum_is_static) {
868 PMIX_RELEASE(var->mbv_enumerator);
869 }
870
871 var->mbv_enumerator = NULL;
872
873 var->mbv_storage = NULL;
874
875 return PMIX_SUCCESS;
876 }
877
878 static int var_get (int vari, pmix_mca_base_var_t **var_out, bool original)
879 {
880 pmix_mca_base_var_t *var;
881
882 if (var_out) {
883 *var_out = NULL;
884 }
885
886
887 if (!pmix_mca_base_var_initialized) {
888 return PMIX_ERROR;
889 }
890
891 if (vari < 0) {
892 return PMIX_ERR_BAD_PARAM;
893 }
894
895 var = pmix_pointer_array_get_item (&pmix_mca_base_vars, vari);
896 if (NULL == var) {
897 return PMIX_ERR_BAD_PARAM;
898 }
899
900 if (PMIX_VAR_IS_SYNONYM(var[0]) && original) {
901 return var_get(var->mbv_synonym_for, var_out, false);
902 }
903
904 if (var_out) {
905 *var_out = var;
906 }
907
908 return PMIX_SUCCESS;
909 }
910
911 int pmix_mca_base_var_env_name(const char *param_name,
912 char **env_name)
913 {
914 int ret;
915
916 assert (NULL != env_name);
917
918 ret = asprintf(env_name, "%s%s", mca_prefix, param_name);
919 if (0 > ret) {
920 return PMIX_ERR_OUT_OF_RESOURCE;
921 }
922
923 return PMIX_SUCCESS;
924 }
925
926
927
928
929 static int var_find_by_name (const char *full_name, int *vari, bool invalidok)
930 {
931 pmix_mca_base_var_t *var = NULL;
932 void *tmp;
933 int rc;
934
935 rc = pmix_hash_table_get_value_ptr (&pmix_mca_base_var_index_hash, full_name, strlen (full_name),
936 &tmp);
937 if (PMIX_SUCCESS != rc) {
938 return rc;
939 }
940
941 (void) var_get ((int)(uintptr_t) tmp, &var, false);
942
943 if (invalidok || (var && PMIX_VAR_IS_VALID(var[0]))) {
944 *vari = (int)(uintptr_t) tmp;
945 return PMIX_SUCCESS;
946 }
947
948 return PMIX_ERR_NOT_FOUND;
949 }
950
951 static int var_find (const char *project_name, const char *framework_name,
952 const char *component_name, const char *variable_name,
953 bool invalidok)
954 {
955 char *full_name;
956 int ret, vari;
957
958 ret = pmix_mca_base_var_generate_full_name4 (NULL, framework_name, component_name,
959 variable_name, &full_name);
960 if (PMIX_SUCCESS != ret) {
961 return PMIX_ERROR;
962 }
963
964 ret = var_find_by_name(full_name, &vari, invalidok);
965
966
967
968 free (full_name);
969
970 if (PMIX_SUCCESS != ret) {
971 return ret;
972 }
973
974 return vari;
975 }
976
977
978
979
980 int pmix_mca_base_var_find (const char *project_name, const char *framework_name,
981 const char *component_name, const char *variable_name)
982 {
983 return var_find (project_name, framework_name, component_name, variable_name, false);
984 }
985
986
987
988
989 int pmix_mca_base_var_find_by_name (const char *full_name, int *vari)
990 {
991 return var_find_by_name (full_name, vari, false);
992 }
993
994 int pmix_mca_base_var_set_flag (int vari, pmix_mca_base_var_flag_t flag, bool set)
995 {
996 pmix_mca_base_var_t *var;
997 int ret;
998
999 ret = var_get (vari, &var, true);
1000 if (PMIX_SUCCESS != ret || PMIX_VAR_IS_SYNONYM(var[0])) {
1001 return PMIX_ERR_BAD_PARAM;
1002 }
1003
1004 var->mbv_flags = (var->mbv_flags & ~flag) | (set ? flag : 0);
1005
1006
1007 return PMIX_SUCCESS;
1008 }
1009
1010
1011
1012
1013 int pmix_mca_base_var_get (int vari, const pmix_mca_base_var_t **var)
1014 {
1015 int ret;
1016 ret = var_get (vari, (pmix_mca_base_var_t **) var, false);
1017
1018 if (PMIX_SUCCESS != ret) {
1019 return ret;
1020 }
1021
1022 if (!PMIX_VAR_IS_VALID(*(var[0]))) {
1023 return PMIX_ERR_NOT_FOUND;
1024 }
1025
1026 return PMIX_SUCCESS;
1027 }
1028
1029
1030
1031
1032 int pmix_mca_base_var_build_env(char ***env, int *num_env, bool internal)
1033 {
1034 pmix_mca_base_var_t *var;
1035 size_t i, len;
1036 int ret=0;
1037
1038
1039
1040 if (!pmix_mca_base_var_initialized) {
1041 return PMIX_ERROR;
1042 }
1043
1044
1045
1046 len = pmix_pointer_array_get_size(&pmix_mca_base_vars);
1047 for (i = 0; i < len; ++i) {
1048 char *value_string;
1049 char *str = NULL;
1050
1051 var = pmix_pointer_array_get_item (&pmix_mca_base_vars, i);
1052 if (NULL == var) {
1053 continue;
1054 }
1055
1056
1057
1058 if (PMIX_MCA_BASE_VAR_SOURCE_DEFAULT == var->mbv_source ||
1059 (!internal && PMIX_VAR_IS_INTERNAL(var[0]))) {
1060 continue;
1061 }
1062
1063 if ((PMIX_MCA_BASE_VAR_TYPE_STRING == var->mbv_type || PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type) &&
1064 NULL == var->mbv_storage->stringval) {
1065 continue;
1066 }
1067
1068 ret = var_value_string (var, &value_string);
1069 if (PMIX_SUCCESS != ret) {
1070 goto cleanup;
1071 }
1072
1073 ret = asprintf (&str, "%s%s=%s", mca_prefix, var->mbv_full_name,
1074 value_string);
1075 free (value_string);
1076 if (0 > ret) {
1077 goto cleanup;
1078 }
1079
1080 pmix_argv_append(num_env, env, str);
1081 free(str);
1082
1083 ret = PMIX_SUCCESS;
1084 switch (var->mbv_source) {
1085 case PMIX_MCA_BASE_VAR_SOURCE_FILE:
1086 case PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE:
1087 ret = asprintf (&str, "%sSOURCE_%s=FILE:%s", mca_prefix, var->mbv_full_name,
1088 pmix_mca_base_var_source_file (var));
1089 break;
1090 case PMIX_MCA_BASE_VAR_SOURCE_COMMAND_LINE:
1091 ret = asprintf (&str, "%sSOURCE_%s=COMMAND_LINE", mca_prefix, var->mbv_full_name);
1092 break;
1093 case PMIX_MCA_BASE_VAR_SOURCE_ENV:
1094 case PMIX_MCA_BASE_VAR_SOURCE_SET:
1095 case PMIX_MCA_BASE_VAR_SOURCE_DEFAULT:
1096 str = NULL;
1097 break;
1098 case PMIX_MCA_BASE_VAR_SOURCE_MAX:
1099 goto cleanup;
1100 }
1101
1102 if (NULL != str) {
1103 pmix_argv_append(num_env, env, str);
1104 free(str);
1105 }
1106 }
1107 if (ret < 0) {
1108 ret = PMIX_ERR_OUT_OF_RESOURCE;
1109 }
1110
1111
1112 return ret;
1113
1114
1115
1116 cleanup:
1117 if (*num_env > 0) {
1118 pmix_argv_free(*env);
1119 *num_env = 0;
1120 *env = NULL;
1121 }
1122 return PMIX_ERR_NOT_FOUND;
1123 }
1124
1125
1126
1127
1128
1129 int pmix_mca_base_var_finalize(void)
1130 {
1131 pmix_object_t *pmixect;
1132 pmix_list_item_t *item;
1133 int size, i;
1134
1135 if (pmix_mca_base_var_initialized) {
1136 size = pmix_pointer_array_get_size(&pmix_mca_base_vars);
1137 for (i = 0 ; i < size ; ++i) {
1138 pmixect = pmix_pointer_array_get_item (&pmix_mca_base_vars, i);
1139 if (NULL != pmixect) {
1140 PMIX_RELEASE(pmixect);
1141 }
1142 }
1143 PMIX_DESTRUCT(&pmix_mca_base_vars);
1144
1145 while (NULL !=
1146 (item = pmix_list_remove_first(&pmix_mca_base_var_file_values))) {
1147 PMIX_RELEASE(item);
1148 }
1149 PMIX_DESTRUCT(&pmix_mca_base_var_file_values);
1150
1151 while (NULL !=
1152 (item = pmix_list_remove_first(&pmix_mca_base_envar_file_values))) {
1153 PMIX_RELEASE(item);
1154 }
1155 PMIX_DESTRUCT(&pmix_mca_base_envar_file_values);
1156
1157 while (NULL !=
1158 (item = pmix_list_remove_first(&pmix_mca_base_var_override_values))) {
1159 PMIX_RELEASE(item);
1160 }
1161 PMIX_DESTRUCT(&pmix_mca_base_var_override_values);
1162
1163 if( NULL != cwd ) {
1164 free(cwd);
1165 cwd = NULL;
1166 }
1167
1168 pmix_mca_base_var_initialized = false;
1169 pmix_mca_base_var_count = 0;
1170
1171 if (NULL != pmix_mca_base_var_file_list) {
1172 pmix_argv_free(pmix_mca_base_var_file_list);
1173 }
1174 pmix_mca_base_var_file_list = NULL;
1175
1176 (void) pmix_mca_base_var_group_finalize ();
1177
1178 PMIX_DESTRUCT(&pmix_mca_base_var_index_hash);
1179
1180 free (pmix_mca_base_envar_files);
1181 pmix_mca_base_envar_files = NULL;
1182 }
1183
1184
1185
1186 return PMIX_SUCCESS;
1187 }
1188
1189
1190
1191 static int fixup_files(char **file_list, char * path, bool rel_path_search, char sep) {
1192 int exit_status = PMIX_SUCCESS;
1193 char **files = NULL;
1194 char **search_path = NULL;
1195 char * tmp_file = NULL;
1196 char **argv = NULL;
1197 char *rel_path;
1198 int mode = R_OK;
1199 int count, i, argc = 0;
1200
1201 search_path = pmix_argv_split(path, PMIX_ENV_SEP);
1202 files = pmix_argv_split(*file_list, sep);
1203 count = pmix_argv_count(files);
1204
1205 rel_path = force_agg_path ? force_agg_path : cwd;
1206
1207
1208 for (i = 0 ; i < count; ++i) {
1209 char *msg_path = path;
1210 if (pmix_path_is_absolute(files[i])) {
1211
1212 tmp_file = pmix_path_access(files[i], NULL, mode);
1213 } else if (!rel_path_search && NULL != strchr(files[i], PMIX_PATH_SEP[0])) {
1214
1215
1216
1217
1218
1219
1220 msg_path = rel_path;
1221 tmp_file = pmix_path_access(files[i], rel_path, mode);
1222 } else {
1223
1224
1225
1226
1227
1228 tmp_file = pmix_path_find (files[i], search_path, mode, NULL);
1229 }
1230
1231 if (NULL == tmp_file) {
1232 pmix_show_help("help-pmix-mca-var.txt", "missing-param-file",
1233 true, getpid(), files[i], msg_path);
1234 exit_status = PMIX_ERROR;
1235 break;
1236 }
1237
1238 pmix_argv_append(&argc, &argv, tmp_file);
1239
1240 free(tmp_file);
1241 tmp_file = NULL;
1242 }
1243
1244 if (PMIX_SUCCESS == exit_status) {
1245 free(*file_list);
1246 *file_list = pmix_argv_join(argv, sep);
1247 }
1248
1249 if( NULL != files ) {
1250 pmix_argv_free(files);
1251 files = NULL;
1252 }
1253
1254 if( NULL != argv ) {
1255 pmix_argv_free(argv);
1256 argv = NULL;
1257 }
1258
1259 if( NULL != search_path ) {
1260 pmix_argv_free(search_path);
1261 search_path = NULL;
1262 }
1263
1264 return exit_status;
1265 }
1266
1267 static int read_files(char *file_list, pmix_list_t *file_values, char sep)
1268 {
1269 char **tmp = pmix_argv_split(file_list, sep);
1270 int i, count;
1271
1272 if (!tmp) {
1273 return PMIX_ERR_OUT_OF_RESOURCE;
1274 }
1275
1276 count = pmix_argv_count(tmp);
1277
1278
1279
1280
1281
1282 for (i = count - 1; i >= 0; --i) {
1283 char *file_name = append_filename_to_list (tmp[i]);
1284 pmix_mca_base_parse_paramfile(file_name, file_values);
1285 }
1286
1287 pmix_argv_free (tmp);
1288
1289 pmix_mca_base_internal_env_store();
1290
1291 return PMIX_SUCCESS;
1292 }
1293
1294
1295 static int register_variable (const char *project_name, const char *framework_name,
1296 const char *component_name, const char *variable_name,
1297 const char *description, pmix_mca_base_var_type_t type,
1298 pmix_mca_base_var_enum_t *enumerator, int bind,
1299 pmix_mca_base_var_flag_t flags, pmix_mca_base_var_info_lvl_t info_lvl,
1300 pmix_mca_base_var_scope_t scope, int synonym_for,
1301 void *storage)
1302 {
1303 int ret, var_index, group_index, tmp;
1304 pmix_mca_base_var_group_t *group;
1305 pmix_mca_base_var_t *var, *original = NULL;
1306
1307
1308 assert (((flags & PMIX_MCA_BASE_VAR_FLAG_SYNONYM) || NULL != storage) && type >= 0 && type < PMIX_MCA_BASE_VAR_TYPE_MAX);
1309
1310 #if PMIX_ENABLE_DEBUG
1311
1312 uintptr_t align = 0;
1313 switch (type) {
1314 case PMIX_MCA_BASE_VAR_TYPE_INT:
1315 align = PMIX_ALIGNMENT_INT;
1316 break;
1317 case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT:
1318 align = PMIX_ALIGNMENT_INT;
1319 break;
1320 case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG:
1321 align = PMIX_ALIGNMENT_LONG;
1322 break;
1323 case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG:
1324 align = PMIX_ALIGNMENT_LONG_LONG;
1325 break;
1326 case PMIX_MCA_BASE_VAR_TYPE_SIZE_T:
1327 align = PMIX_ALIGNMENT_SIZE_T;
1328 break;
1329 case PMIX_MCA_BASE_VAR_TYPE_BOOL:
1330 align = PMIX_ALIGNMENT_BOOL;
1331 break;
1332 case PMIX_MCA_BASE_VAR_TYPE_DOUBLE:
1333 align = PMIX_ALIGNMENT_DOUBLE;
1334 break;
1335 case PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING:
1336 case PMIX_MCA_BASE_VAR_TYPE_STRING:
1337 default:
1338 align = 0;
1339 break;
1340 }
1341
1342 if (0 != align) {
1343 assert(((uintptr_t) storage) % align == 0);
1344 }
1345
1346
1347
1348 if (flags & PMIX_MCA_BASE_VAR_FLAG_SYNONYM && synonym_for < 0) {
1349 assert((flags & PMIX_MCA_BASE_VAR_FLAG_SYNONYM) && synonym_for >= 0);
1350 }
1351 #endif
1352
1353 if (flags & PMIX_MCA_BASE_VAR_FLAG_SYNONYM) {
1354 if (synonym_for < 0) {
1355 return PMIX_ERR_BAD_PARAM;
1356 }
1357 original = pmix_pointer_array_get_item (&pmix_mca_base_vars, synonym_for);
1358 if (NULL == original) {
1359
1360
1361 assert (NULL != original);
1362 return PMIX_ERR_NOT_FOUND;
1363 }
1364 }
1365
1366
1367 if (!pmix_mca_base_var_initialized) {
1368 ret = pmix_mca_base_var_init();
1369 if (PMIX_SUCCESS != ret) {
1370 return ret;
1371 }
1372 }
1373
1374
1375 var_index = var_find (project_name, framework_name, component_name, variable_name,
1376 true);
1377
1378 if (0 > var_index) {
1379
1380 group_index = pmix_mca_base_var_group_register (project_name, framework_name, component_name,
1381 NULL);
1382 if (-1 > group_index) {
1383 return group_index;
1384 }
1385
1386
1387 if (scope < PMIX_MCA_BASE_VAR_SCOPE_LOCAL || (flags & PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY)) {
1388 if ((flags & PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY) && (flags & PMIX_MCA_BASE_VAR_FLAG_SETTABLE)) {
1389 pmix_show_help("help-pmix-mca-var.txt", "invalid-flag-combination",
1390 true, "PMIX_MCA_BASE_VAR_FLAG_DEFAULT_ONLY", "PMIX_MCA_BASE_VAR_FLAG_SETTABLE");
1391 return PMIX_ERROR;
1392 }
1393
1394
1395 flags &= ~PMIX_MCA_BASE_VAR_FLAG_SETTABLE;
1396 }
1397
1398 var = PMIX_NEW(pmix_mca_base_var_t);
1399
1400 var->mbv_type = type;
1401 var->mbv_flags = flags;
1402 var->mbv_group_index = group_index;
1403 var->mbv_info_lvl = info_lvl;
1404 var->mbv_scope = scope;
1405 var->mbv_synonym_for = synonym_for;
1406 var->mbv_bind = bind;
1407
1408 if (NULL != description) {
1409 var->mbv_description = strdup(description);
1410 }
1411
1412 if (NULL != variable_name) {
1413 var->mbv_variable_name = strdup(variable_name);
1414 if (NULL == var->mbv_variable_name) {
1415 PMIX_RELEASE(var);
1416 return PMIX_ERR_OUT_OF_RESOURCE;
1417 }
1418 }
1419
1420 ret = pmix_mca_base_var_generate_full_name4 (NULL, framework_name, component_name,
1421 variable_name, &var->mbv_full_name);
1422 if (PMIX_SUCCESS != ret) {
1423 PMIX_RELEASE(var);
1424 return PMIX_ERROR;
1425 }
1426
1427 ret = pmix_mca_base_var_generate_full_name4 (project_name, framework_name, component_name,
1428 variable_name, &var->mbv_long_name);
1429 if (PMIX_SUCCESS != ret) {
1430 PMIX_RELEASE(var);
1431 return PMIX_ERROR;
1432 }
1433
1434
1435
1436
1437
1438 var_index = pmix_pointer_array_add (&pmix_mca_base_vars, var);
1439 if (0 > var_index) {
1440 PMIX_RELEASE(var);
1441 return PMIX_ERROR;
1442 }
1443
1444 var->mbv_index = var_index;
1445
1446 if (0 <= group_index) {
1447 pmix_mca_base_var_group_add_var (group_index, var_index);
1448 }
1449
1450 pmix_mca_base_var_count++;
1451 if (0 <= var_find_by_name (var->mbv_full_name, &tmp, 0)) {
1452
1453 assert (0);
1454 }
1455
1456 pmix_hash_table_set_value_ptr (&pmix_mca_base_var_index_hash, var->mbv_full_name, strlen (var->mbv_full_name),
1457 (void *)(uintptr_t) var_index);
1458 } else {
1459 ret = var_get (var_index, &var, false);
1460 if (PMIX_SUCCESS != ret) {
1461
1462 return PMIX_ERROR;
1463 }
1464
1465 ret = pmix_mca_base_var_group_get_internal (var->mbv_group_index, &group, true);
1466 if (PMIX_SUCCESS != ret) {
1467
1468 return PMIX_ERROR;
1469 }
1470
1471 if (!group->group_isvalid) {
1472 group->group_isvalid = true;
1473 }
1474
1475
1476 if (0 != compare_strings(framework_name, group->group_framework) ||
1477 0 != compare_strings(component_name, group->group_component) ||
1478 0 != compare_strings(variable_name, var->mbv_variable_name)) {
1479 pmix_show_help("help-pmix-mca-var.txt", "var-name-conflict",
1480 true, var->mbv_full_name, framework_name,
1481 component_name, variable_name,
1482 group->group_framework, group->group_component,
1483 var->mbv_variable_name);
1484
1485 assert (0);
1486 return PMIX_ERROR;
1487 }
1488
1489 if (var->mbv_type != type) {
1490 #if PMIX_ENABLE_DEBUG
1491 pmix_show_help("help-pmix-mca-var.txt",
1492 "re-register-with-different-type",
1493 true, var->mbv_full_name);
1494 #endif
1495 return PMIX_ERR_VALUE_OUT_OF_BOUNDS;
1496 }
1497 }
1498
1499 if (PMIX_MCA_BASE_VAR_TYPE_BOOL == var->mbv_type) {
1500 enumerator = &pmix_mca_base_var_enum_bool;
1501 } else if (NULL != enumerator) {
1502 if (var->mbv_enumerator) {
1503 PMIX_RELEASE (var->mbv_enumerator);
1504 }
1505
1506 if (!enumerator->enum_is_static) {
1507 PMIX_RETAIN(enumerator);
1508 }
1509 }
1510
1511 var->mbv_enumerator = enumerator;
1512
1513 if (!original) {
1514 var->mbv_storage = storage;
1515
1516
1517 if ((PMIX_MCA_BASE_VAR_TYPE_STRING == type || PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING == type) && NULL != ((char **)storage)[0]) {
1518 ((char **)storage)[0] = strdup (((char **)storage)[0]);
1519 }
1520 } else {
1521
1522 pmix_value_array_append_item(&original->mbv_synonyms, &var_index);
1523 }
1524
1525
1526 var->mbv_flags |= PMIX_MCA_BASE_VAR_FLAG_VALID;
1527
1528 ret = var_set_initial (var, original);
1529 if (PMIX_SUCCESS != ret) {
1530 return ret;
1531 }
1532
1533
1534 return var_index;
1535 }
1536
1537 int pmix_mca_base_var_register (const char *project_name, const char *framework_name,
1538 const char *component_name, const char *variable_name,
1539 const char *description, pmix_mca_base_var_type_t type,
1540 pmix_mca_base_var_enum_t *enumerator, int bind,
1541 pmix_mca_base_var_flag_t flags,
1542 pmix_mca_base_var_info_lvl_t info_lvl,
1543 pmix_mca_base_var_scope_t scope, void *storage)
1544 {
1545
1546 assert (NULL == enumerator || (PMIX_MCA_BASE_VAR_TYPE_INT == type || PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT == type));
1547
1548 return register_variable (project_name, framework_name, component_name,
1549 variable_name, description, type, enumerator,
1550 bind, flags, info_lvl, scope, -1, storage);
1551 }
1552
1553 int pmix_mca_base_component_var_register (const pmix_mca_base_component_t *component,
1554 const char *variable_name, const char *description,
1555 pmix_mca_base_var_type_t type, pmix_mca_base_var_enum_t *enumerator,
1556 int bind, pmix_mca_base_var_flag_t flags,
1557 pmix_mca_base_var_info_lvl_t info_lvl,
1558 pmix_mca_base_var_scope_t scope, void *storage)
1559 {
1560 return pmix_mca_base_var_register (component->pmix_mca_project_name,
1561 component->pmix_mca_type_name,
1562 component->pmix_mca_component_name,
1563 variable_name, description, type, enumerator,
1564 bind, flags | PMIX_MCA_BASE_VAR_FLAG_DWG,
1565 info_lvl, scope, storage);
1566 }
1567
1568 int pmix_mca_base_framework_var_register (const pmix_mca_base_framework_t *framework,
1569 const char *variable_name,
1570 const char *help_msg, pmix_mca_base_var_type_t type,
1571 pmix_mca_base_var_enum_t *enumerator, int bind,
1572 pmix_mca_base_var_flag_t flags,
1573 pmix_mca_base_var_info_lvl_t info_level,
1574 pmix_mca_base_var_scope_t scope, void *storage)
1575 {
1576 return pmix_mca_base_var_register (framework->framework_project, framework->framework_name,
1577 "base", variable_name, help_msg, type, enumerator, bind,
1578 flags | PMIX_MCA_BASE_VAR_FLAG_DWG, info_level, scope, storage);
1579 }
1580
1581 int pmix_mca_base_var_register_synonym (int synonym_for, const char *project_name,
1582 const char *framework_name,
1583 const char *component_name,
1584 const char *synonym_name,
1585 pmix_mca_base_var_syn_flag_t flags)
1586 {
1587 pmix_mca_base_var_flag_t var_flags = (pmix_mca_base_var_flag_t) PMIX_MCA_BASE_VAR_FLAG_SYNONYM;
1588 pmix_mca_base_var_t *var;
1589 int ret;
1590
1591 ret = var_get (synonym_for, &var, false);
1592 if (PMIX_SUCCESS != ret || PMIX_VAR_IS_SYNONYM(var[0])) {
1593 return PMIX_ERR_BAD_PARAM;
1594 }
1595
1596 if (flags & PMIX_MCA_BASE_VAR_SYN_FLAG_DEPRECATED) {
1597 var_flags |= PMIX_MCA_BASE_VAR_FLAG_DEPRECATED;
1598 }
1599 if (flags & PMIX_MCA_BASE_VAR_SYN_FLAG_INTERNAL) {
1600 var_flags |= PMIX_MCA_BASE_VAR_FLAG_INTERNAL;
1601 }
1602
1603 return register_variable (project_name, framework_name, component_name,
1604 synonym_name, var->mbv_description, var->mbv_type, var->mbv_enumerator,
1605 var->mbv_bind, var_flags, var->mbv_info_lvl, var->mbv_scope,
1606 synonym_for, NULL);
1607 }
1608
1609 static int var_get_env (pmix_mca_base_var_t *var, const char *name, char **source, char **value)
1610 {
1611 char *source_env, *value_env;
1612 int ret;
1613
1614 ret = asprintf (&source_env, "%sSOURCE_%s", mca_prefix, name);
1615 if (0 > ret) {
1616 return PMIX_ERROR;
1617 }
1618
1619 ret = asprintf (&value_env, "%s%s", mca_prefix, name);
1620 if (0 > ret) {
1621 free (source_env);
1622 return PMIX_ERROR;
1623 }
1624
1625 *source = getenv (source_env);
1626 *value = getenv (value_env);
1627
1628 free (source_env);
1629 free (value_env);
1630
1631 if (NULL == *value) {
1632 *source = NULL;
1633 return PMIX_ERR_NOT_FOUND;
1634 }
1635
1636 return PMIX_SUCCESS;
1637 }
1638
1639
1640
1641
1642 static int var_set_from_env (pmix_mca_base_var_t *var, pmix_mca_base_var_t *original)
1643 {
1644 const char *var_full_name = var->mbv_full_name;
1645 const char *var_long_name = var->mbv_long_name;
1646 bool deprecated = PMIX_VAR_IS_DEPRECATED(var[0]);
1647 bool is_synonym = PMIX_VAR_IS_SYNONYM(var[0]);
1648 char *source_env, *value_env;
1649 int ret;
1650
1651 ret = var_get_env (var, var_long_name, &source_env, &value_env);
1652 if (PMIX_SUCCESS != ret) {
1653 ret = var_get_env (var, var_full_name, &source_env, &value_env);
1654 }
1655
1656 if (PMIX_SUCCESS != ret) {
1657 return ret;
1658 }
1659
1660
1661
1662 if (PMIX_VAR_IS_DEFAULT_ONLY(original[0])) {
1663 pmix_show_help("help-pmix-mca-var.txt", "default-only-param-set",
1664 true, var_full_name);
1665
1666 return PMIX_ERR_NOT_FOUND;
1667 }
1668
1669 if (PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE == original->mbv_source) {
1670 if (!pmix_mca_base_var_suppress_override_warning) {
1671 pmix_show_help("help-pmix-mca-var.txt", "overridden-param-set",
1672 true, var_full_name);
1673 }
1674
1675 return PMIX_ERR_NOT_FOUND;
1676 }
1677
1678 original->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_ENV;
1679
1680 if (NULL != source_env) {
1681 if (0 == strncasecmp (source_env, "file:", 5)) {
1682 original->mbv_source_file = append_filename_to_list(source_env + 5);
1683 if (0 == strcmp (var->mbv_source_file, pmix_mca_base_var_override_file)) {
1684 original->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE;
1685 } else {
1686 original->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_FILE;
1687 }
1688 } else if (0 == strcasecmp (source_env, "command")) {
1689 var->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_COMMAND_LINE;
1690 }
1691 }
1692
1693 if (deprecated) {
1694 const char *new_variable = "None (going away)";
1695
1696 if (is_synonym) {
1697 new_variable = var->mbv_full_name;
1698 }
1699
1700 switch (var->mbv_source) {
1701 case PMIX_MCA_BASE_VAR_SOURCE_ENV:
1702 pmix_show_help("help-pmix-mca-var.txt", "deprecated-mca-env",
1703 true, var_full_name, new_variable);
1704 break;
1705 case PMIX_MCA_BASE_VAR_SOURCE_COMMAND_LINE:
1706 pmix_show_help("help-pmix-mca-var.txt", "deprecated-mca-cli",
1707 true, var_full_name, new_variable);
1708 break;
1709 case PMIX_MCA_BASE_VAR_SOURCE_FILE:
1710 case PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE:
1711 pmix_show_help("help-pmix-mca-var.txt", "deprecated-mca-file",
1712 true, var_full_name, pmix_mca_base_var_source_file (var),
1713 new_variable);
1714 break;
1715
1716 case PMIX_MCA_BASE_VAR_SOURCE_DEFAULT:
1717 case PMIX_MCA_BASE_VAR_SOURCE_MAX:
1718 case PMIX_MCA_BASE_VAR_SOURCE_SET:
1719
1720 break;
1721 }
1722 }
1723
1724 return var_set_from_string (original, value_env);
1725 }
1726
1727
1728
1729
1730 static int var_set_from_file (pmix_mca_base_var_t *var, pmix_mca_base_var_t *original, pmix_list_t *file_values)
1731 {
1732 const char *var_full_name = var->mbv_full_name;
1733 const char *var_long_name = var->mbv_long_name;
1734 bool deprecated = PMIX_VAR_IS_DEPRECATED(var[0]);
1735 bool is_synonym = PMIX_VAR_IS_SYNONYM(var[0]);
1736 pmix_mca_base_var_file_value_t *fv;
1737
1738
1739
1740
1741
1742 PMIX_LIST_FOREACH(fv, file_values, pmix_mca_base_var_file_value_t) {
1743 if (0 != strcmp(fv->mbvfv_var, var_full_name) &&
1744 0 != strcmp(fv->mbvfv_var, var_long_name)) {
1745 continue;
1746 }
1747
1748
1749 if (PMIX_VAR_IS_DEFAULT_ONLY(var[0])) {
1750 pmix_show_help("help-pmix-mca-var.txt", "default-only-param-set",
1751 true, var_full_name);
1752
1753 return PMIX_ERR_NOT_FOUND;
1754 }
1755
1756 if (PMIX_MCA_BASE_VAR_FLAG_ENVIRONMENT_ONLY & original->mbv_flags) {
1757 pmix_show_help("help-pmix-mca-var.txt", "environment-only-param",
1758 true, var_full_name, fv->mbvfv_value,
1759 fv->mbvfv_file);
1760
1761 return PMIX_ERR_NOT_FOUND;
1762 }
1763
1764 if (PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE == original->mbv_source) {
1765 if (!pmix_mca_base_var_suppress_override_warning) {
1766 pmix_show_help("help-pmix-mca-var.txt", "overridden-param-set",
1767 true, var_full_name);
1768 }
1769
1770 return PMIX_ERR_NOT_FOUND;
1771 }
1772
1773 if (deprecated) {
1774 const char *new_variable = "None (going away)";
1775
1776 if (is_synonym) {
1777 new_variable = original->mbv_full_name;
1778 }
1779
1780 pmix_show_help("help-pmix-mca-var.txt", "deprecated-mca-file",
1781 true, var_full_name, fv->mbvfv_file,
1782 new_variable);
1783 }
1784
1785 original->mbv_file_value = (void *) fv;
1786 original->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_FILE;
1787 if (is_synonym) {
1788 var->mbv_file_value = (void *) fv;
1789 var->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_FILE;
1790 }
1791
1792 return var_set_from_string (original, fv->mbvfv_value);
1793 }
1794
1795 return PMIX_ERR_NOT_FOUND;
1796 }
1797
1798
1799
1800
1801 static int var_set_initial (pmix_mca_base_var_t *var, pmix_mca_base_var_t *original)
1802 {
1803 int ret;
1804
1805 if (original) {
1806
1807 var->mbv_source = original->mbv_source;
1808 var->mbv_file_value = original->mbv_file_value;
1809 var->mbv_source_file = original->mbv_source_file;
1810 } else {
1811 var->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_DEFAULT;
1812 original = var;
1813 }
1814
1815
1816
1817
1818
1819 ret = var_set_from_file (var, original, &pmix_mca_base_var_override_values);
1820 if (PMIX_SUCCESS == ret) {
1821 var->mbv_flags = ~PMIX_MCA_BASE_VAR_FLAG_SETTABLE & (var->mbv_flags | PMIX_MCA_BASE_VAR_FLAG_OVERRIDE);
1822 var->mbv_source = PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE;
1823 }
1824
1825 ret = var_set_from_env (var, original);
1826 if (PMIX_ERR_NOT_FOUND != ret) {
1827 return ret;
1828 }
1829
1830 ret = var_set_from_file (var, original, &pmix_mca_base_envar_file_values);
1831 if (PMIX_ERR_NOT_FOUND != ret) {
1832 return ret;
1833 }
1834
1835 ret = var_set_from_file (var, original, &pmix_mca_base_var_file_values);
1836 if (PMIX_ERR_NOT_FOUND != ret) {
1837 return ret;
1838 }
1839
1840 return PMIX_SUCCESS;
1841 }
1842
1843
1844
1845
1846 static void var_constructor(pmix_mca_base_var_t *var)
1847 {
1848 memset ((char *) var + sizeof (var->super), 0, sizeof (*var) - sizeof (var->super));
1849
1850 var->mbv_type = PMIX_MCA_BASE_VAR_TYPE_MAX;
1851 PMIX_CONSTRUCT(&var->mbv_synonyms, pmix_value_array_t);
1852 pmix_value_array_init (&var->mbv_synonyms, sizeof (int));
1853 }
1854
1855
1856
1857
1858
1859 static void var_destructor(pmix_mca_base_var_t *var)
1860 {
1861 if ((PMIX_MCA_BASE_VAR_TYPE_STRING == var->mbv_type ||
1862 PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type) &&
1863 NULL != var->mbv_storage &&
1864 NULL != var->mbv_storage->stringval) {
1865 free (var->mbv_storage->stringval);
1866 var->mbv_storage->stringval = NULL;
1867 }
1868
1869
1870 if (var->mbv_enumerator && !var->mbv_enumerator->enum_is_static) {
1871 PMIX_RELEASE(var->mbv_enumerator);
1872 }
1873
1874 if (NULL != var->mbv_variable_name) {
1875 free(var->mbv_variable_name);
1876 }
1877 if (NULL != var->mbv_full_name) {
1878 free(var->mbv_full_name);
1879 }
1880 if (NULL != var->mbv_long_name) {
1881 free(var->mbv_long_name);
1882 }
1883
1884 if (NULL != var->mbv_description) {
1885 free(var->mbv_description);
1886 }
1887
1888
1889 PMIX_DESTRUCT(&var->mbv_synonyms);
1890
1891
1892 var->mbv_type = PMIX_MCA_BASE_VAR_TYPE_MAX;
1893
1894 #if PMIX_ENABLE_DEBUG
1895
1896 memset ((char *) var + sizeof (var->super), 0, sizeof (*var) - sizeof (var->super));
1897 #endif
1898 }
1899
1900
1901 static void fv_constructor(pmix_mca_base_var_file_value_t *f)
1902 {
1903 memset ((char *) f + sizeof (f->super), 0, sizeof (*f) - sizeof (f->super));
1904 }
1905
1906
1907 static void fv_destructor(pmix_mca_base_var_file_value_t *f)
1908 {
1909 if (NULL != f->mbvfv_var) {
1910 free(f->mbvfv_var);
1911 }
1912 if (NULL != f->mbvfv_value) {
1913 free(f->mbvfv_value);
1914 }
1915
1916 fv_constructor(f);
1917 }
1918
1919 static char *source_name(pmix_mca_base_var_t *var)
1920 {
1921 char *ret;
1922
1923 if (PMIX_MCA_BASE_VAR_SOURCE_FILE == var->mbv_source || PMIX_MCA_BASE_VAR_SOURCE_OVERRIDE == var->mbv_source) {
1924 struct pmix_mca_base_var_file_value_t *fv = var->mbv_file_value;
1925 int rc;
1926
1927 if (fv) {
1928 rc = asprintf(&ret, "file (%s:%d)", fv->mbvfv_file, fv->mbvfv_lineno);
1929 } else {
1930 rc = asprintf(&ret, "file (%s)", var->mbv_source_file);
1931 }
1932
1933
1934 if (0 > rc) {
1935 return NULL;
1936 }
1937 return ret;
1938 } else if (PMIX_MCA_BASE_VAR_SOURCE_MAX <= var->mbv_source) {
1939 return strdup ("unknown(!!)");
1940 }
1941
1942 return strdup (pmix_var_source_names[var->mbv_source]);
1943 }
1944
1945 static int var_value_string (pmix_mca_base_var_t *var, char **value_string)
1946 {
1947 pmix_mca_base_var_storage_t *value=NULL;
1948 int ret;
1949
1950 assert (PMIX_MCA_BASE_VAR_TYPE_MAX > var->mbv_type);
1951
1952 ret = pmix_mca_base_var_get_value(var->mbv_index, &value, NULL, NULL);
1953 if (PMIX_SUCCESS != ret || NULL == value) {
1954 return ret;
1955 }
1956
1957 if (NULL == var->mbv_enumerator) {
1958 switch (var->mbv_type) {
1959 case PMIX_MCA_BASE_VAR_TYPE_INT:
1960 ret = asprintf (value_string, "%d", value->intval);
1961 break;
1962 case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_INT:
1963 ret = asprintf (value_string, "%u", value->uintval);
1964 break;
1965 case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG:
1966 ret = asprintf (value_string, "%lu", value->ulval);
1967 break;
1968 case PMIX_MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG:
1969 ret = asprintf (value_string, "%llu", value->ullval);
1970 break;
1971 case PMIX_MCA_BASE_VAR_TYPE_SIZE_T:
1972 ret = asprintf (value_string, "%" PRIsize_t, value->sizetval);
1973 break;
1974 case PMIX_MCA_BASE_VAR_TYPE_STRING:
1975 case PMIX_MCA_BASE_VAR_TYPE_VERSION_STRING:
1976 ret = asprintf (value_string, "%s",
1977 value->stringval ? value->stringval : "");
1978 break;
1979 case PMIX_MCA_BASE_VAR_TYPE_BOOL:
1980 ret = asprintf (value_string, "%d", value->boolval);
1981 break;
1982 case PMIX_MCA_BASE_VAR_TYPE_DOUBLE:
1983 ret = asprintf (value_string, "%lf", value->lfval);
1984 break;
1985 default:
1986 ret = -1;
1987 break;
1988 }
1989
1990 ret = (0 > ret) ? PMIX_ERR_OUT_OF_RESOURCE : PMIX_SUCCESS;
1991 } else {
1992
1993 if (PMIX_MCA_BASE_VAR_TYPE_BOOL == var->mbv_type) {
1994 ret = var->mbv_enumerator->string_from_value(var->mbv_enumerator, value->boolval, value_string);
1995 } else {
1996 ret = var->mbv_enumerator->string_from_value(var->mbv_enumerator, value->intval, value_string);
1997 }
1998
1999 if (PMIX_SUCCESS != ret) {
2000 return ret;
2001 }
2002 }
2003
2004 return ret;
2005 }
2006
2007 int pmix_mca_base_var_check_exclusive (const char *project,
2008 const char *type_a,
2009 const char *component_a,
2010 const char *param_a,
2011 const char *type_b,
2012 const char *component_b,
2013 const char *param_b)
2014 {
2015 pmix_mca_base_var_t *var_a = NULL, *var_b = NULL;
2016 int var_ai, var_bi;
2017
2018
2019 project = NULL;
2020
2021 var_ai = pmix_mca_base_var_find (project, type_a, component_a, param_a);
2022 var_bi = pmix_mca_base_var_find (project, type_b, component_b, param_b);
2023 if (var_bi < 0 || var_ai < 0) {
2024 return PMIX_ERR_NOT_FOUND;
2025 }
2026
2027 (void) var_get (var_ai, &var_a, true);
2028 (void) var_get (var_bi, &var_b, true);
2029 if (NULL == var_a || NULL == var_b) {
2030 return PMIX_ERR_NOT_FOUND;
2031 }
2032
2033 if (PMIX_MCA_BASE_VAR_SOURCE_DEFAULT != var_a->mbv_source &&
2034 PMIX_MCA_BASE_VAR_SOURCE_DEFAULT != var_b->mbv_source) {
2035 char *str_a, *str_b;
2036
2037
2038 str_a = source_name(var_a);
2039
2040
2041 str_b = source_name(var_b);
2042
2043
2044 pmix_show_help("help-pmix-mca-var.txt",
2045 "mutually-exclusive-vars",
2046 true, var_a->mbv_full_name,
2047 str_a, var_b->mbv_full_name,
2048 str_b);
2049
2050
2051 free(str_a);
2052 free(str_b);
2053
2054 return PMIX_ERR_BAD_PARAM;
2055 }
2056
2057 return PMIX_SUCCESS;
2058 }
2059
2060 int pmix_mca_base_var_get_count (void)
2061 {
2062 return pmix_mca_base_var_count;
2063 }
2064
2065 int pmix_mca_base_var_dump(int vari, char ***out, pmix_mca_base_var_dump_type_t output_type)
2066 {
2067 const char *framework, *component, *full_name;
2068 int i, line_count, line = 0, enum_count = 0;
2069 char *value_string, *source_string, *tmp;
2070 int synonym_count, ret, *synonyms = NULL;
2071 pmix_mca_base_var_t *var, *original=NULL;
2072 pmix_mca_base_var_group_t *group;
2073
2074 ret = var_get(vari, &var, false);
2075 if (PMIX_SUCCESS != ret) {
2076 return ret;
2077 }
2078
2079 ret = pmix_mca_base_var_group_get_internal(var->mbv_group_index, &group, false);
2080 if (PMIX_SUCCESS != ret) {
2081 return ret;
2082 }
2083
2084 if (PMIX_VAR_IS_SYNONYM(var[0])) {
2085 ret = var_get(var->mbv_synonym_for, &original, false);
2086 if (PMIX_SUCCESS != ret) {
2087 return ret;
2088 }
2089
2090 if (NULL == original) {
2091 return PMIX_ERR_NOT_FOUND;
2092 }
2093 }
2094
2095 framework = group->group_framework;
2096 component = group->group_component ? group->group_component : "base";
2097 full_name = var->mbv_full_name;
2098
2099 synonym_count = pmix_value_array_get_size(&var->mbv_synonyms);
2100 if (synonym_count) {
2101 synonyms = PMIX_VALUE_ARRAY_GET_BASE(&var->mbv_synonyms, int);
2102 }
2103
2104 ret = var_value_string (var, &value_string);
2105 if (PMIX_SUCCESS != ret) {
2106 return ret;
2107 }
2108
2109 source_string = source_name(var);
2110 if (NULL == source_string) {
2111 free (value_string);
2112 return PMIX_ERR_OUT_OF_RESOURCE;
2113 }
2114
2115 if (PMIX_MCA_BASE_VAR_DUMP_PARSABLE == output_type) {
2116 if (NULL != var->mbv_enumerator) {
2117 (void) var->mbv_enumerator->get_count(var->mbv_enumerator, &enum_count);
2118 }
2119
2120 line_count = 8 + (var->mbv_description ? 1 : 0) + (PMIX_VAR_IS_SYNONYM(var[0]) ? 1 : synonym_count) +
2121 enum_count;
2122
2123 *out = (char **) calloc (line_count + 1, sizeof (char *));
2124 if (NULL == *out) {
2125 free (value_string);
2126 free (source_string);
2127 return PMIX_ERR_OUT_OF_RESOURCE;
2128 }
2129
2130
2131 ret = asprintf(&tmp, "mca:%s:%s:param:%s:", framework, component, full_name);
2132 if (0 > ret) {
2133 return PMIX_ERR_OUT_OF_RESOURCE;
2134 }
2135
2136
2137 char *colon = strchr(value_string, ':');
2138 if (NULL != colon) {
2139 ret = asprintf(out[0] + line++, "%svalue:\"%s\"", tmp, value_string);
2140 } else {
2141 ret = asprintf(out[0] + line++, "%svalue:%s", tmp, value_string);
2142 }
2143 if (0 > ret) {
2144 return PMIX_ERR_OUT_OF_RESOURCE;
2145 }
2146
2147
2148 ret = asprintf(out[0] + line++, "%ssource:%s", tmp, source_string);
2149 if (0 > ret) {
2150 return PMIX_ERR_OUT_OF_RESOURCE;
2151 }
2152
2153
2154 ret = asprintf(out[0] + line++, "%sstatus:%s", tmp, PMIX_VAR_IS_DEFAULT_ONLY(var[0]) ? "read-only" : "writeable");
2155 if (0 > ret) {
2156 return PMIX_ERR_OUT_OF_RESOURCE;
2157 }
2158
2159
2160 ret = asprintf(out[0] + line++, "%slevel:%d", tmp, var->mbv_info_lvl + 1);
2161 if (0 > ret) {
2162 return PMIX_ERR_OUT_OF_RESOURCE;
2163 }
2164
2165
2166 if (var->mbv_description) {
2167 ret = asprintf(out[0] + line++, "%shelp:%s", tmp, var->mbv_description);
2168 }
2169 if (0 > ret) {
2170 return PMIX_ERR_OUT_OF_RESOURCE;
2171 }
2172
2173 if (NULL != var->mbv_enumerator) {
2174 for (i = 0 ; i < enum_count ; ++i) {
2175 const char *enum_string = NULL;
2176 int enum_value;
2177
2178 ret = var->mbv_enumerator->get_value(var->mbv_enumerator, i, &enum_value,
2179 &enum_string);
2180 if (PMIX_SUCCESS != ret) {
2181 continue;
2182 }
2183
2184 ret = asprintf(out[0] + line++, "%senumerator:value:%d:%s", tmp, enum_value, enum_string);
2185 if (0 > ret) {
2186 return PMIX_ERR_OUT_OF_RESOURCE;
2187 }
2188 }
2189 }
2190
2191
2192 ret = asprintf(out[0] + line++, "%sdeprecated:%s", tmp, PMIX_VAR_IS_DEPRECATED(var[0]) ? "yes" : "no");
2193 if (0 > ret) {
2194 return PMIX_ERR_OUT_OF_RESOURCE;
2195 }
2196
2197 ret = asprintf(out[0] + line++, "%stype:%s", tmp, pmix_var_type_names[var->mbv_type]);
2198 if (0 > ret) {
2199 return PMIX_ERR_OUT_OF_RESOURCE;
2200 }
2201
2202
2203 if (PMIX_VAR_IS_SYNONYM(var[0])) {
2204 ret = asprintf(out[0] + line++, "%ssynonym_of:name:%s", tmp, original->mbv_full_name);
2205 if (0 > ret) {
2206 return PMIX_ERR_OUT_OF_RESOURCE;
2207 }
2208 } else if (pmix_value_array_get_size(&var->mbv_synonyms)) {
2209 for (i = 0 ; i < synonym_count ; ++i) {
2210 pmix_mca_base_var_t *synonym;
2211
2212 ret = var_get(synonyms[i], &synonym, false);
2213 if (PMIX_SUCCESS != ret) {
2214 continue;
2215 }
2216
2217 ret = asprintf(out[0] + line++, "%ssynonym:name:%s", tmp, synonym->mbv_full_name);
2218 if (0 > ret) {
2219 return PMIX_ERR_OUT_OF_RESOURCE;
2220 }
2221 }
2222 }
2223
2224 free (tmp);
2225 } else if (PMIX_MCA_BASE_VAR_DUMP_READABLE == output_type) {
2226
2227 *out = (char **) calloc (4, sizeof (char *));
2228 if (NULL == *out) {
2229 free (value_string);
2230 free (source_string);
2231 return PMIX_ERR_OUT_OF_RESOURCE;
2232 }
2233
2234 ret = asprintf (out[0], "%s \"%s\" (current value: \"%s\", data source: %s, level: %d %s, type: %s",
2235 PMIX_VAR_IS_DEFAULT_ONLY(var[0]) ? "informational" : "parameter",
2236 full_name, value_string, source_string, var->mbv_info_lvl + 1,
2237 info_lvl_strings[var->mbv_info_lvl], pmix_var_type_names[var->mbv_type]);
2238 if (0 > ret) {
2239 return PMIX_ERR_OUT_OF_RESOURCE;
2240 }
2241
2242 tmp = out[0][0];
2243 if (PMIX_VAR_IS_DEPRECATED(var[0])) {
2244 ret = asprintf (out[0], "%s, deprecated", tmp);
2245 free (tmp);
2246 if (0 > ret) {
2247 return PMIX_ERR_OUT_OF_RESOURCE;
2248 }
2249 tmp = out[0][0];
2250 }
2251
2252
2253 if (PMIX_VAR_IS_SYNONYM(var[0])) {
2254 ret = asprintf(out[0], "%s, synonym of: %s)", tmp, original->mbv_full_name);
2255 free (tmp);
2256 if (0 > ret) {
2257 return PMIX_ERR_OUT_OF_RESOURCE;
2258 }
2259 } else if (synonym_count) {
2260 ret = asprintf(out[0], "%s, synonyms: ", tmp);
2261 free (tmp);
2262 if (0 > ret) {
2263 return PMIX_ERR_OUT_OF_RESOURCE;
2264 }
2265
2266 for (i = 0 ; i < synonym_count ; ++i) {
2267 pmix_mca_base_var_t *synonym;
2268
2269 ret = var_get(synonyms[i], &synonym, false);
2270 if (PMIX_SUCCESS != ret) {
2271 continue;
2272 }
2273
2274 tmp = out[0][0];
2275 if (synonym_count == i+1) {
2276 ret = asprintf(out[0], "%s%s)", tmp, synonym->mbv_full_name);
2277 } else {
2278 ret = asprintf(out[0], "%s%s, ", tmp, synonym->mbv_full_name);
2279 }
2280 free(tmp);
2281 if (0 > ret) {
2282 return PMIX_ERR_OUT_OF_RESOURCE;
2283 }
2284 }
2285 } else {
2286 ret = asprintf(out[0], "%s)", tmp);
2287 free(tmp);
2288 if (0 > ret) {
2289 return PMIX_ERR_OUT_OF_RESOURCE;
2290 }
2291 }
2292
2293 line++;
2294
2295 if (var->mbv_description) {
2296 ret = asprintf(out[0] + line++, "%s", var->mbv_description);
2297 if (0 > ret) {
2298 return PMIX_ERR_OUT_OF_RESOURCE;
2299 }
2300 }
2301
2302 if (NULL != var->mbv_enumerator) {
2303 char *values;
2304
2305 ret = var->mbv_enumerator->dump(var->mbv_enumerator, &values);
2306 if (PMIX_SUCCESS == ret) {
2307 ret = asprintf (out[0] + line++, "Valid values: %s", values);
2308 free (values);
2309 if (0 > ret) {
2310 return PMIX_ERR_OUT_OF_RESOURCE;
2311 }
2312 }
2313 }
2314 } else if (PMIX_MCA_BASE_VAR_DUMP_SIMPLE == output_type) {
2315 *out = (char **) calloc (2, sizeof (char *));
2316 if (NULL == *out) {
2317 free (value_string);
2318 free (source_string);
2319 return PMIX_ERR_OUT_OF_RESOURCE;
2320 }
2321
2322 ret = asprintf(out[0], "%s=%s (%s)", var->mbv_full_name, value_string, source_string);
2323 if (0 > ret) {
2324 return PMIX_ERR_OUT_OF_RESOURCE;
2325 }
2326 }
2327
2328 free (value_string);
2329 free (source_string);
2330
2331 return PMIX_SUCCESS;
2332 }