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 }