root/opal/mca/pmix/pmix4x/pmix/src/tools/pmix_info/support.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. component_map_construct
  2. component_map_destruct
  3. pmix_info_init
  4. pmix_info_finalize
  5. info_register_framework
  6. pmix_info_register_project_frameworks
  7. pmix_info_register_types
  8. pmix_info_register_framework_params
  9. pmix_info_close_components
  10. pmix_info_show_path
  11. pmix_info_do_path
  12. pmix_info_do_params
  13. pmix_info_err_params
  14. pmix_info_do_type
  15. pmix_info_show_mca_group_params
  16. pmix_info_show_mca_params
  17. pmix_info_do_arch
  18. pmix_info_do_hostname
  19. escape_quotes
  20. pmix_info_out
  21. pmix_info_out_int
  22. pmix_info_show_component_version
  23. pmix_info_show_failed_component
  24. pmix_info_show_mca_version
  25. pmix_info_make_version_str
  26. pmix_info_show_pmix_version
  27. pmix_info_do_config

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2011 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2006-2015 Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2010-2016 Los Alamos National Security, LLC. All rights
  15  *                         reserved.
  16  * Copyright (c) 2011-2012 University of Houston. All rights reserved.
  17  * Copyright (c) 2016-2018 Intel, Inc. All rights reserved.
  18  * Copyright (c) 2017      IBM Corporation.  All rights reserved.
  19  * Copyright (c) 2017      Research Organization for Information Science
  20  *                         and Technology (RIST). All rights reserved.
  21  * $COPYRIGHT$
  22  *
  23  * Additional copyrights may follow
  24  *
  25  * $HEADER$
  26  */
  27 
  28 #include "pmix_config.h"
  29 
  30 #include <string.h>
  31 #include <ctype.h>
  32 
  33 #ifdef HAVE_UNISTD_H
  34 #include <unistd.h>
  35 #endif
  36 
  37 #include <errno.h>
  38 
  39 #include "src/class/pmix_list.h"
  40 #include "src/class/pmix_pointer_array.h"
  41 #include "src/runtime/pmix_rte.h"
  42 #include "src/util/output.h"
  43 #include "src/util/cmd_line.h"
  44 #include "src/util/error.h"
  45 #include "src/util/argv.h"
  46 #include "src/util/show_help.h"
  47 
  48 #include "src/include/frameworks.h"
  49 #include "src/include/pmix_portable_platform.h"
  50 
  51 #include "src/mca/pinstalldirs/pinstalldirs.h"
  52 #include "pinfo.h"
  53 #include "support.h"
  54 #include "src/mca/base/pmix_mca_base_component_repository.h"
  55 
  56 const char *pmix_info_path_prefix = "prefix";
  57 const char *pmix_info_path_bindir = "bindir";
  58 const char *pmix_info_path_libdir = "libdir";
  59 const char *pmix_info_path_incdir = "incdir";
  60 const char *pmix_info_path_mandir = "mandir";
  61 const char *pmix_info_path_pkglibdir = "pkglibdir";
  62 const char *pmix_info_path_sysconfdir = "sysconfdir";
  63 const char *pmix_info_path_exec_prefix = "exec_prefix";
  64 const char *pmix_info_path_sbindir = "sbindir";
  65 const char *pmix_info_path_libexecdir = "libexecdir";
  66 const char *pmix_info_path_datarootdir = "datarootdir";
  67 const char *pmix_info_path_datadir = "datadir";
  68 const char *pmix_info_path_sharedstatedir = "sharedstatedir";
  69 const char *pmix_info_path_localstatedir = "localstatedir";
  70 const char *pmix_info_path_infodir = "infodir";
  71 const char *pmix_info_path_pkgdatadir = "pkgdatadir";
  72 const char *pmix_info_path_pkgincludedir = "pkgincludedir";
  73 
  74 bool pmix_info_pretty = true;
  75 pmix_mca_base_register_flag_t pmix_info_register_flags = PMIX_MCA_BASE_REGISTER_ALL;
  76 
  77 const char *pmix_info_type_all = "all";
  78 const char *pmix_info_type_pmix = "pmix";
  79 const char *pmix_info_component_all = "all";
  80 const char *pmix_info_param_all = "all";
  81 
  82 const char *pmix_info_ver_full = "full";
  83 const char *pmix_info_ver_major = "major";
  84 const char *pmix_info_ver_minor = "minor";
  85 const char *pmix_info_ver_release = "release";
  86 const char *pmix_info_ver_greek = "greek";
  87 const char *pmix_info_ver_repo = "repo";
  88 
  89 const char *pmix_info_ver_all = "all";
  90 const char *pmix_info_ver_mca = "mca";
  91 const char *pmix_info_ver_type = "type";
  92 const char *pmix_info_ver_component = "component";
  93 
  94 static int pmix_info_registered = 0;
  95 
  96 static void component_map_construct(pmix_info_component_map_t *map)
  97 {
  98     map->type = NULL;
  99 }
 100 static void component_map_destruct(pmix_info_component_map_t *map)
 101 {
 102     if (NULL != map->type) {
 103         free(map->type);
 104     }
 105     /* the type close functions will release the
 106      * list of components
 107      */
 108 }
 109 PMIX_CLASS_INSTANCE(pmix_info_component_map_t,
 110                     pmix_list_item_t,
 111                     component_map_construct,
 112                     component_map_destruct);
 113 
 114 static void pmix_info_show_failed_component(const pmix_mca_base_component_repository_item_t* ri,
 115                                             const char *error_msg);
 116 
 117 int pmix_info_init(int argc, char **argv,
 118                    pmix_cmd_line_t *pmix_info_cmd_line)
 119 {
 120     int ret;
 121     bool want_help = false;
 122     bool cmd_error = false;
 123     char **app_env = NULL, **global_env = NULL;
 124 
 125     /* add the cmd line options */
 126     pmix_cmd_line_make_opt3(pmix_info_cmd_line, 'V', NULL, "version", 0,
 127                             "Show version of Open MPI");
 128     pmix_cmd_line_make_opt3(pmix_info_cmd_line, '\0', NULL, "param", 2,
 129                             "Show MCA parameters.  The first parameter is the framework (or the keyword \"all\"); the second parameter is the specific component name (or the keyword \"all\").");
 130     pmix_cmd_line_make_opt3(pmix_info_cmd_line, '\0', NULL, "params", 2,
 131                             "Synonym for --param");
 132     pmix_cmd_line_make_opt3(pmix_info_cmd_line, '\0', NULL, "internal", 0,
 133                             "Show internal MCA parameters (not meant to be modified by users)");
 134     pmix_cmd_line_make_opt3(pmix_info_cmd_line, '\0', NULL, "path", 1,
 135                             "Show paths that Open MPI was configured with.  Accepts the following parameters: prefix, bindir, libdir, incdir, mandir, pkglibdir, sysconfdir, all");
 136     pmix_cmd_line_make_opt3(pmix_info_cmd_line, '\0', NULL, "arch", 0,
 137                             "Show architecture Open MPI was compiled on");
 138     pmix_cmd_line_make_opt3(pmix_info_cmd_line, 'c', NULL, "config", 0,
 139                             "Show configuration options");
 140     pmix_cmd_line_make_opt3(pmix_info_cmd_line, 't', NULL, "type", 1,
 141                             "Show internal MCA parameters with the type specified in parameter.");
 142     pmix_cmd_line_make_opt3(pmix_info_cmd_line, 'h', NULL, "help", 0,
 143                             "Show this help message");
 144     pmix_cmd_line_make_opt3(pmix_info_cmd_line, '\0', NULL, "pretty-print", 0,
 145                             "When used in conjunction with other parameters, the output is displayed in 'pretty-print' format (default)");
 146     pmix_cmd_line_make_opt3(pmix_info_cmd_line, '\0', NULL, "parsable", 0,
 147                             "When used in conjunction with other parameters, the output is displayed in a machine-parsable format");
 148     pmix_cmd_line_make_opt3(pmix_info_cmd_line, '\0', NULL, "parseable", 0,
 149                             "Synonym for --parsable");
 150     pmix_cmd_line_make_opt3(pmix_info_cmd_line, '\0', NULL, "hostname", 0,
 151                             "Show the hostname that Open MPI was configured and built on");
 152     pmix_cmd_line_make_opt3(pmix_info_cmd_line, 'a', NULL, "all", 0,
 153                             "Show all configuration options and MCA parameters");
 154     pmix_cmd_line_make_opt3(pmix_info_cmd_line, 'l', NULL, "level", 1,
 155                             "Show only variables with at most this level (1-9)");
 156     pmix_cmd_line_make_opt3(pmix_info_cmd_line, 's', NULL, "selected-only", 0,
 157                             "Show only variables from selected components");
 158     pmix_cmd_line_make_opt3(pmix_info_cmd_line, '\0', NULL, "show-failed", 0,
 159                             "Show the components that failed to load along with the reason why they failed.");
 160 
 161     if( PMIX_SUCCESS != pmix_mca_base_open() ) {
 162         pmix_show_help("help-pinfo.txt", "lib-call-fail", true, "mca_base_open", __FILE__, __LINE__ );
 163         PMIX_RELEASE(pmix_info_cmd_line);
 164         exit(1);
 165     }
 166     pmix_mca_base_cmd_line_setup(pmix_info_cmd_line);
 167 
 168     /* Do the parsing */
 169 
 170     ret = pmix_cmd_line_parse(pmix_info_cmd_line, false, false, argc, argv);
 171     if (PMIX_SUCCESS != ret) {
 172         if (PMIX_ERR_SILENT != ret) {
 173             fprintf(stderr, "%s: command line error (%s)\n", argv[0],
 174                     PMIx_Error_string(ret));
 175         }
 176         cmd_error = true;
 177     }
 178     if (!cmd_error &&
 179         (pmix_cmd_line_is_taken(pmix_info_cmd_line, "help") ||
 180          pmix_cmd_line_is_taken(pmix_info_cmd_line, "h"))) {
 181         char *str, *usage;
 182 
 183         want_help = true;
 184         usage = pmix_cmd_line_get_usage_msg(pmix_info_cmd_line);
 185         str = pmix_show_help_string("help-pmix-info.txt", "usage", true,
 186                                     usage);
 187         if (NULL != str) {
 188             printf("%s", str);
 189             free(str);
 190         }
 191         free(usage);
 192     }
 193 
 194 
 195     /* If we had a cmd line parse error, or we showed the help
 196        message, it's time to exit. */
 197     if (cmd_error || want_help) {
 198         pmix_mca_base_close();
 199         PMIX_RELEASE(pmix_info_cmd_line);
 200         exit(cmd_error ? 1 : 0);
 201     }
 202 
 203     pmix_mca_base_cmd_line_process_args(pmix_info_cmd_line, &app_env, &global_env);
 204 
 205 
 206     /* set the flags */
 207     if (pmix_cmd_line_is_taken(pmix_info_cmd_line, "pretty-print")) {
 208         pmix_info_pretty = true;
 209     } else if (pmix_cmd_line_is_taken(pmix_info_cmd_line, "parsable") || pmix_cmd_line_is_taken(pmix_info_cmd_line, "parseable")) {
 210         pmix_info_pretty = false;
 211     }
 212 
 213     if (pmix_cmd_line_is_taken(pmix_info_cmd_line, "selected-only")) {
 214         /* register only selected components */
 215         pmix_info_register_flags = PMIX_MCA_BASE_REGISTER_DEFAULT;
 216     }
 217 
 218     if (pmix_cmd_line_is_taken(pmix_info_cmd_line, "show-failed")) {
 219         pmix_mca_base_component_track_load_errors = true;
 220     }
 221 
 222     return PMIX_SUCCESS;
 223 }
 224 
 225 void pmix_info_finalize(void)
 226 {
 227     pmix_mca_base_close();
 228 }
 229 
 230 static int info_register_framework (pmix_mca_base_framework_t *framework, pmix_pointer_array_t *component_map)
 231 {
 232     pmix_info_component_map_t *map;
 233     int rc;
 234     rc = pmix_mca_base_framework_register(framework, pmix_info_register_flags);
 235     if (PMIX_SUCCESS != rc && PMIX_ERR_BAD_PARAM != rc) {
 236         return rc;
 237     }
 238 
 239     if (NULL != component_map) {
 240         map = PMIX_NEW(pmix_info_component_map_t);
 241         map->type = strdup(framework->framework_name);
 242         map->components = &framework->framework_components;
 243         map->failed_components = &framework->framework_failed_components;
 244         pmix_pointer_array_add(component_map, map);
 245     }
 246 
 247     return rc;
 248 }
 249 
 250 int pmix_info_register_project_frameworks (const char *project_name, pmix_mca_base_framework_t **frameworks,
 251                                            pmix_pointer_array_t *component_map)
 252 {
 253     int i, rc=PMIX_SUCCESS;
 254 
 255     for (i=0; NULL != frameworks[i]; i++) {
 256         if (PMIX_SUCCESS != (rc = info_register_framework(frameworks[i], component_map))) {
 257             if (PMIX_ERR_BAD_PARAM == rc) {
 258                 fprintf(stderr, "\nA \"bad parameter\" error was encountered when opening the %s %s framework\n",
 259                         project_name, frameworks[i]->framework_name);
 260                 fprintf(stderr, "The output received from that framework includes the following parameters:\n\n");
 261             } else if (PMIX_ERR_NOT_AVAILABLE != rc) {
 262                 fprintf(stderr, "%s_info_register: %s failed\n", project_name, frameworks[i]->framework_name);
 263                 rc = PMIX_ERROR;
 264             } else {
 265                 continue;
 266             }
 267 
 268             break;
 269         }
 270     }
 271 
 272     return rc;
 273 }
 274 
 275 void pmix_info_register_types(pmix_pointer_array_t *mca_types)
 276 {
 277     int i;
 278 
 279     /* add the top-level types */
 280     pmix_pointer_array_add(mca_types, "mca");
 281     pmix_pointer_array_add(mca_types, "pmix");
 282 
 283     /* push all the types found by autogen */
 284     for (i=0; NULL != pmix_frameworks[i]; i++) {
 285         pmix_pointer_array_add(mca_types, pmix_frameworks[i]->framework_name);
 286     }
 287 }
 288 
 289 int pmix_info_register_framework_params(pmix_pointer_array_t *component_map)
 290 {
 291     int rc;
 292 
 293     if (pmix_info_registered++) {
 294         return PMIX_SUCCESS;
 295     }
 296 
 297     /* Register mca/base parameters */
 298     if( PMIX_SUCCESS != pmix_mca_base_open() ) {
 299         pmix_show_help("help-pmix_info.txt", "lib-call-fail", true, "mca_base_open", __FILE__, __LINE__ );
 300         return PMIX_ERROR;
 301     }
 302 
 303     /* Register the PMIX layer's MCA parameters */
 304     if (PMIX_SUCCESS != (rc = pmix_register_params())) {
 305         fprintf(stderr, "pmix_info_register: pmix_register_params failed\n");
 306         return rc;
 307     }
 308 
 309     return pmix_info_register_project_frameworks("pmix", pmix_frameworks, component_map);
 310 }
 311 
 312 
 313 void pmix_info_close_components(void)
 314 {
 315     int i;
 316 
 317     assert(pmix_info_registered);
 318     if (--pmix_info_registered) {
 319         return;
 320     }
 321 
 322     for (i=0; NULL != pmix_frameworks[i]; i++) {
 323         (void) pmix_mca_base_framework_close(pmix_frameworks[i]);
 324     }
 325 
 326     /* release our reference to MCA */
 327     pmix_mca_base_close ();
 328 }
 329 
 330 
 331 void pmix_info_show_path(const char *type, const char *value)
 332 {
 333     char *pretty, *path;
 334 
 335     pretty = strdup(type);
 336     pretty[0] = toupper(pretty[0]);
 337 
 338     if (0 > asprintf(&path, "path:%s", type)) {
 339         free(pretty);
 340         return;
 341     }
 342     pmix_info_out(pretty, path, value);
 343     free(pretty);
 344     free(path);
 345 }
 346 
 347 void pmix_info_do_path(bool want_all, pmix_cmd_line_t *cmd_line)
 348 {
 349     int i, count;
 350     char *scope;
 351 
 352     /* Check bozo case */
 353     count = pmix_cmd_line_get_ninsts(cmd_line, "path");
 354     for (i = 0; i < count; ++i) {
 355         scope = pmix_cmd_line_get_param(cmd_line, "path", i, 0);
 356         if (0 == strcmp("all", scope)) {
 357             want_all = true;
 358             break;
 359         }
 360     }
 361 
 362     if (want_all) {
 363         pmix_info_show_path(pmix_info_path_prefix, pmix_pinstall_dirs.prefix);
 364         pmix_info_show_path(pmix_info_path_exec_prefix, pmix_pinstall_dirs.exec_prefix);
 365         pmix_info_show_path(pmix_info_path_bindir, pmix_pinstall_dirs.bindir);
 366         pmix_info_show_path(pmix_info_path_sbindir, pmix_pinstall_dirs.sbindir);
 367         pmix_info_show_path(pmix_info_path_libdir, pmix_pinstall_dirs.libdir);
 368         pmix_info_show_path(pmix_info_path_incdir, pmix_pinstall_dirs.includedir);
 369         pmix_info_show_path(pmix_info_path_mandir, pmix_pinstall_dirs.mandir);
 370         pmix_info_show_path(pmix_info_path_pkglibdir, pmix_pinstall_dirs.pmixlibdir);
 371         pmix_info_show_path(pmix_info_path_libexecdir, pmix_pinstall_dirs.libexecdir);
 372         pmix_info_show_path(pmix_info_path_datarootdir, pmix_pinstall_dirs.datarootdir);
 373         pmix_info_show_path(pmix_info_path_datadir, pmix_pinstall_dirs.datadir);
 374         pmix_info_show_path(pmix_info_path_sysconfdir, pmix_pinstall_dirs.sysconfdir);
 375         pmix_info_show_path(pmix_info_path_sharedstatedir, pmix_pinstall_dirs.sharedstatedir);
 376         pmix_info_show_path(pmix_info_path_localstatedir, pmix_pinstall_dirs.localstatedir);
 377         pmix_info_show_path(pmix_info_path_infodir, pmix_pinstall_dirs.infodir);
 378         pmix_info_show_path(pmix_info_path_pkgdatadir, pmix_pinstall_dirs.pmixdatadir);
 379         pmix_info_show_path(pmix_info_path_pkglibdir, pmix_pinstall_dirs.pmixlibdir);
 380         pmix_info_show_path(pmix_info_path_pkgincludedir, pmix_pinstall_dirs.pmixincludedir);
 381     } else {
 382         count = pmix_cmd_line_get_ninsts(cmd_line, "path");
 383         for (i = 0; i < count; ++i) {
 384             scope = pmix_cmd_line_get_param(cmd_line, "path", i, 0);
 385 
 386             if (0 == strcmp(pmix_info_path_prefix, scope)) {
 387                 pmix_info_show_path(pmix_info_path_prefix, pmix_pinstall_dirs.prefix);
 388             } else if (0 == strcmp(pmix_info_path_bindir, scope)) {
 389                 pmix_info_show_path(pmix_info_path_bindir, pmix_pinstall_dirs.bindir);
 390             } else if (0 == strcmp(pmix_info_path_libdir, scope)) {
 391                 pmix_info_show_path(pmix_info_path_libdir, pmix_pinstall_dirs.libdir);
 392             } else if (0 == strcmp(pmix_info_path_incdir, scope)) {
 393                 pmix_info_show_path(pmix_info_path_incdir, pmix_pinstall_dirs.includedir);
 394             } else if (0 == strcmp(pmix_info_path_mandir, scope)) {
 395                 pmix_info_show_path(pmix_info_path_mandir, pmix_pinstall_dirs.mandir);
 396             } else if (0 == strcmp(pmix_info_path_pkglibdir, scope)) {
 397                 pmix_info_show_path(pmix_info_path_pkglibdir, pmix_pinstall_dirs.pmixlibdir);
 398             } else if (0 == strcmp(pmix_info_path_sysconfdir, scope)) {
 399                 pmix_info_show_path(pmix_info_path_sysconfdir, pmix_pinstall_dirs.sysconfdir);
 400             } else if (0 == strcmp(pmix_info_path_exec_prefix, scope)) {
 401                 pmix_info_show_path(pmix_info_path_exec_prefix, pmix_pinstall_dirs.exec_prefix);
 402             } else if (0 == strcmp(pmix_info_path_sbindir, scope)) {
 403                 pmix_info_show_path(pmix_info_path_sbindir, pmix_pinstall_dirs.sbindir);
 404             } else if (0 == strcmp(pmix_info_path_libexecdir, scope)) {
 405                 pmix_info_show_path(pmix_info_path_libexecdir, pmix_pinstall_dirs.libexecdir);
 406             } else if (0 == strcmp(pmix_info_path_datarootdir, scope)) {
 407                 pmix_info_show_path(pmix_info_path_datarootdir, pmix_pinstall_dirs.datarootdir);
 408             } else if (0 == strcmp(pmix_info_path_datadir, scope)) {
 409                 pmix_info_show_path(pmix_info_path_datadir, pmix_pinstall_dirs.datadir);
 410             } else if (0 == strcmp(pmix_info_path_sharedstatedir, scope)) {
 411                 pmix_info_show_path(pmix_info_path_sharedstatedir, pmix_pinstall_dirs.sharedstatedir);
 412             } else if (0 == strcmp(pmix_info_path_localstatedir, scope)) {
 413                 pmix_info_show_path(pmix_info_path_localstatedir, pmix_pinstall_dirs.localstatedir);
 414             } else if (0 == strcmp(pmix_info_path_infodir, scope)) {
 415                 pmix_info_show_path(pmix_info_path_infodir, pmix_pinstall_dirs.infodir);
 416             } else if (0 == strcmp(pmix_info_path_pkgdatadir, scope)) {
 417                 pmix_info_show_path(pmix_info_path_pkgdatadir, pmix_pinstall_dirs.pmixdatadir);
 418             } else if (0 == strcmp(pmix_info_path_pkgincludedir, scope)) {
 419                 pmix_info_show_path(pmix_info_path_pkgincludedir, pmix_pinstall_dirs.pmixincludedir);
 420             } else {
 421                 char *usage = pmix_cmd_line_get_usage_msg(cmd_line);
 422                 pmix_show_help("help-pmix_info.txt", "usage", true, usage);
 423                 free(usage);
 424                 exit(1);
 425             }
 426         }
 427     }
 428 }
 429 
 430 void pmix_info_do_params(bool want_all_in, bool want_internal,
 431                          pmix_pointer_array_t *mca_types,
 432                          pmix_pointer_array_t *component_map,
 433                          pmix_cmd_line_t *pmix_info_cmd_line)
 434 {
 435     pmix_mca_base_var_info_lvl_t max_level = PMIX_INFO_LVL_1;
 436     int count;
 437     char *type, *component, *str;
 438     bool found;
 439     int i;
 440     bool want_all = false;
 441     char *p;
 442 
 443     if (pmix_cmd_line_is_taken(pmix_info_cmd_line, "param")) {
 444         p = "param";
 445     } else if (pmix_cmd_line_is_taken(pmix_info_cmd_line, "params")) {
 446         p = "params";
 447     } else {
 448         p = "foo";  /* should never happen, but protect against segfault */
 449     }
 450 
 451     if (NULL != (str = pmix_cmd_line_get_param (pmix_info_cmd_line, "level", 0, 0))) {
 452         char *tmp;
 453 
 454         errno = 0;
 455         max_level = strtol (str, &tmp, 10) + PMIX_INFO_LVL_1 - 1;
 456         if (0 != errno || '\0' != tmp[0] || max_level < PMIX_INFO_LVL_1 || max_level > PMIX_INFO_LVL_9) {
 457             char *usage = pmix_cmd_line_get_usage_msg(pmix_info_cmd_line);
 458             pmix_show_help("help-pmix_info.txt", "invalid-level", true, str);
 459             free(usage);
 460             exit(1);
 461         }
 462     } else if (want_all_in) {
 463         /* if not specified default to level 9 if all components are requested */
 464         max_level = PMIX_INFO_LVL_9;
 465     }
 466 
 467     if (want_all_in) {
 468         want_all = true;
 469     } else {
 470         /* See if the special param "all" was given to --param; that
 471          * supercedes any individual type
 472          */
 473         count = pmix_cmd_line_get_ninsts(pmix_info_cmd_line, p);
 474         for (i = 0; i < count; ++i) {
 475             type = pmix_cmd_line_get_param(pmix_info_cmd_line, p, (int)i, 0);
 476             if (0 == strcmp(pmix_info_type_all, type)) {
 477                 want_all = true;
 478                 break;
 479             }
 480         }
 481     }
 482 
 483     /* Show the params */
 484 
 485     if (want_all) {
 486         pmix_info_show_component_version(mca_types, component_map, pmix_info_type_all,
 487                                          pmix_info_component_all, pmix_info_ver_full,
 488                                          pmix_info_ver_all);
 489         for (i = 0; i < mca_types->size; ++i) {
 490             if (NULL == (type = (char *)pmix_pointer_array_get_item(mca_types, i))) {
 491                 continue;
 492             }
 493             pmix_info_show_mca_params(type, pmix_info_component_all, max_level, want_internal);
 494         }
 495     } else {
 496         for (i = 0; i < count; ++i) {
 497             type = pmix_cmd_line_get_param(pmix_info_cmd_line, p, (int)i, 0);
 498             component = pmix_cmd_line_get_param(pmix_info_cmd_line, p, (int)i, 1);
 499 
 500             for (found = false, i = 0; i < mca_types->size; ++i) {
 501                 if (NULL == (str = (char *)pmix_pointer_array_get_item(mca_types, i))) {
 502                     continue;
 503                 }
 504                 if (0 == strcmp(str, type)) {
 505                     found = true;
 506                     break;
 507                 }
 508             }
 509 
 510             if (!found) {
 511                 char *usage = pmix_cmd_line_get_usage_msg(pmix_info_cmd_line);
 512                 pmix_show_help("help-pmix_info.txt", "not-found", true, type);
 513                 free(usage);
 514                 exit(1);
 515             }
 516 
 517             pmix_info_show_component_version(mca_types, component_map, type,
 518                                              component, pmix_info_ver_full,
 519                                              pmix_info_ver_all);
 520             pmix_info_show_mca_params(type, component, max_level, want_internal);
 521         }
 522     }
 523 }
 524 
 525 void pmix_info_err_params(pmix_pointer_array_t *component_map)
 526 {
 527     pmix_info_component_map_t *map=NULL, *mptr;
 528     int i;
 529 
 530     /* all we want to do is display the LAST entry in the
 531      * component_map array as this is the one that generated the error
 532      */
 533     for (i=0; i < component_map->size; i++) {
 534         if (NULL == (mptr = (pmix_info_component_map_t*)pmix_pointer_array_get_item(component_map, i))) {
 535             continue;
 536         }
 537         map = mptr;
 538     }
 539     if (NULL == map) {
 540         fprintf(stderr, "pmix_info_err_params: map not found\n");
 541         return;
 542     }
 543     pmix_info_show_mca_params(map->type, pmix_info_component_all, PMIX_INFO_LVL_9, true);
 544     fprintf(stderr, "\n");
 545     return;
 546 }
 547 
 548 void pmix_info_do_type(pmix_cmd_line_t *pmix_info_cmd_line)
 549 {
 550     pmix_mca_base_var_info_lvl_t max_level = PMIX_INFO_LVL_1;
 551     int count;
 552     char *type, *str;
 553     int i, j, k, len, ret;
 554     char *p;
 555     const pmix_mca_base_var_t *var;
 556     char** strings, *message;
 557     const pmix_mca_base_var_group_t *group;
 558     p = "type";
 559 
 560     if (NULL != (str = pmix_cmd_line_get_param (pmix_info_cmd_line, "level", 0, 0))) {
 561         char *tmp;
 562 
 563         errno = 0;
 564         max_level = strtol (str, &tmp, 10) + PMIX_INFO_LVL_1 - 1;
 565         if (0 != errno || '\0' != tmp[0] || max_level < PMIX_INFO_LVL_1 || max_level > PMIX_INFO_LVL_9) {
 566             char *usage = pmix_cmd_line_get_usage_msg(pmix_info_cmd_line);
 567             pmix_show_help("help-pmix_info.txt", "invalid-level", true, str);
 568             free(usage);
 569             exit(1);
 570         }
 571     }
 572 
 573     count = pmix_cmd_line_get_ninsts(pmix_info_cmd_line, p);
 574     len = pmix_mca_base_var_get_count ();
 575 
 576     for (k = 0; k < count; ++k) {
 577         type = pmix_cmd_line_get_param(pmix_info_cmd_line, p, k, 0);
 578         for (i = 0; i < len; ++i) {
 579             ret = pmix_mca_base_var_get (i, &var);
 580             if (PMIX_SUCCESS != ret) {
 581                 continue;
 582             }
 583             if (0 == strcmp(type, pmix_var_type_names[var->mbv_type]) && (var->mbv_info_lvl <= max_level)) {
 584                 ret = pmix_mca_base_var_dump(var->mbv_index, &strings, !pmix_info_pretty ? PMIX_MCA_BASE_VAR_DUMP_PARSABLE : PMIX_MCA_BASE_VAR_DUMP_READABLE);
 585                 if (PMIX_SUCCESS != ret) {
 586                     continue;
 587                 }
 588                 (void) pmix_mca_base_var_group_get(var->mbv_group_index, &group);
 589                 for (j = 0 ; strings[j] ; ++j) {
 590                     if (0 == j && pmix_info_pretty) {
 591                         if (0 > asprintf (&message, "MCA %s", group->group_framework)) {
 592                             continue;
 593                         }
 594                         pmix_info_out(message, message, strings[j]);
 595                         free(message);
 596                     } else {
 597                         pmix_info_out("", "", strings[j]);
 598                     }
 599                     free(strings[j]);
 600                 }
 601                 free(strings);
 602             }
 603         }
 604     }
 605 }
 606 
 607 static void pmix_info_show_mca_group_params(const pmix_mca_base_var_group_t *group, pmix_mca_base_var_info_lvl_t max_level, bool want_internal)
 608 {
 609     const int *variables, *groups;
 610     const char *group_component;
 611     const pmix_mca_base_var_t *var;
 612     char **strings, *message;
 613     bool requested = true;
 614     int ret, i, j, count;
 615 
 616     variables = PMIX_VALUE_ARRAY_GET_BASE(&group->group_vars, const int);
 617     count = pmix_value_array_get_size((pmix_value_array_t *)&group->group_vars);
 618 
 619     /* the default component name is "base". depending on how the
 620      * group was registered the group may or not have this set.  */
 621     group_component = group->group_component ? group->group_component : "base";
 622 
 623     /* check if this group may be disabled due to a selection variable */
 624     if (0 != strcmp (group_component, "base")) {
 625         int var_id;
 626 
 627         /* read the selection parameter */
 628         var_id = pmix_mca_base_var_find (group->group_project, group->group_framework, NULL, NULL);
 629         if (0 <= var_id) {
 630             const pmix_mca_base_var_storage_t *value=NULL;
 631             char **requested_components;
 632             bool include_mode;
 633 
 634             pmix_mca_base_var_get_value (var_id, &value, NULL, NULL);
 635             if (NULL != value && NULL != value->stringval && '\0' != value->stringval[0]) {
 636                 pmix_mca_base_component_parse_requested (value->stringval, &include_mode, &requested_components);
 637 
 638                 for (i = 0, requested = !include_mode ; requested_components[i] ; ++i) {
 639                     if (0 == strcmp (requested_components[i], group_component)) {
 640                         requested = include_mode;
 641                         break;
 642                     }
 643                 }
 644 
 645                 pmix_argv_free (requested_components);
 646             }
 647         }
 648     }
 649 
 650     const pmix_mca_base_var_group_t *curr_group = NULL;
 651     char *component_msg = NULL;
 652     if (0 > asprintf(&component_msg, " %s", group_component)) {
 653         return;
 654     }
 655 
 656     for (i = 0 ; i < count ; ++i) {
 657         ret = pmix_mca_base_var_get(variables[i], &var);
 658         if (PMIX_SUCCESS != ret || ((var->mbv_flags & PMIX_MCA_BASE_VAR_FLAG_INTERNAL) &&
 659                                     !want_internal) ||
 660             max_level < var->mbv_info_lvl) {
 661             continue;
 662         }
 663 
 664         if (pmix_info_pretty && curr_group != group) {
 665             if (0 > asprintf(&message, "MCA%s %s%s", requested ? "" : " (-)",
 666                              group->group_framework,
 667                              component_msg ? component_msg : "")) {
 668                 continue;
 669             }
 670             pmix_info_out(message, message, "---------------------------------------------------");
 671             free(message);
 672             curr_group = group;
 673         }
 674 
 675         ret = pmix_mca_base_var_dump(variables[i], &strings, !pmix_info_pretty ? PMIX_MCA_BASE_VAR_DUMP_PARSABLE : PMIX_MCA_BASE_VAR_DUMP_READABLE);
 676         if (PMIX_SUCCESS != ret) {
 677             continue;
 678         }
 679 
 680         for (j = 0 ; strings[j] ; ++j) {
 681             if (0 == j && pmix_info_pretty) {
 682                 if (0 > asprintf (&message, "MCA%s %s%s", requested ? "" : " (-)",
 683                                   group->group_framework,
 684                                   component_msg ? component_msg : "")) {
 685                     continue;
 686                 }
 687                 pmix_info_out(message, message, strings[j]);
 688                 free(message);
 689             } else {
 690                 pmix_info_out("", "", strings[j]);
 691             }
 692             free(strings[j]);
 693         }
 694         if (!pmix_info_pretty) {
 695             /* generate an entry indicating whether this variable is disabled or not. if the
 696              * format in mca_base_var/pvar.c changes this needs to be changed as well */
 697             if (0 > asprintf (&message, "mca:%s:%s:param:%s:disabled:%s", group->group_framework,
 698                               group_component, var->mbv_full_name, requested ? "false" : "true")) {
 699                 continue;
 700             }
 701             pmix_info_out("", "", message);
 702             free (message);
 703         }
 704         free(strings);
 705     }
 706 
 707     groups = PMIX_VALUE_ARRAY_GET_BASE(&group->group_subgroups, const int);
 708     count = pmix_value_array_get_size((pmix_value_array_t *)&group->group_subgroups);
 709 
 710     for (i = 0 ; i < count ; ++i) {
 711         ret = pmix_mca_base_var_group_get(groups[i], &group);
 712         if (PMIX_SUCCESS != ret) {
 713             continue;
 714         }
 715         pmix_info_show_mca_group_params(group, max_level, want_internal);
 716     }
 717     free(component_msg);
 718 }
 719 
 720 void pmix_info_show_mca_params(const char *type, const char *component,
 721                                pmix_mca_base_var_info_lvl_t max_level, bool want_internal)
 722 {
 723     const pmix_mca_base_var_group_t *group;
 724     int ret;
 725 
 726     if (0 == strcmp (component, "all")) {
 727         ret = pmix_mca_base_var_group_find("*", type, NULL);
 728         if (0 > ret) {
 729             return;
 730         }
 731 
 732         (void) pmix_mca_base_var_group_get(ret, &group);
 733 
 734         pmix_info_show_mca_group_params(group, max_level, want_internal);
 735     } else {
 736         ret = pmix_mca_base_var_group_find("*", type, component);
 737         if (0 > ret) {
 738             return;
 739         }
 740 
 741         (void) pmix_mca_base_var_group_get(ret, &group);
 742         pmix_info_show_mca_group_params(group, max_level, want_internal);
 743     }
 744 }
 745 
 746 
 747 
 748 void pmix_info_do_arch()
 749 {
 750     pmix_info_out("Configured architecture", "config:arch", PMIX_ARCH);
 751 }
 752 
 753 
 754 void pmix_info_do_hostname()
 755 {
 756     pmix_info_out("Configure host", "config:host", PMIX_CONFIGURE_HOST);
 757 }
 758 
 759 
 760 static char *escape_quotes(const char *value)
 761 {
 762     const char *src;
 763     int num_quotes = 0;
 764     for (src = value; src != NULL && *src != '\0'; ++src) {
 765         if ('"' == *src) {
 766             ++num_quotes;
 767         }
 768     }
 769 
 770     // If there are no quotes in the string, there's nothing to do
 771     if (0 == num_quotes) {
 772         return NULL;
 773     }
 774 
 775     // If we have quotes, make a new string.  Copy over the old
 776     // string, escaping the quotes along the way.  This is simple and
 777     // clear to read; it's not particularly efficient (performance is
 778     // definitely not important here).
 779     char *quoted_value;
 780     quoted_value = calloc(1, strlen(value) + num_quotes + 1);
 781     if (NULL == quoted_value) {
 782         return NULL;
 783     }
 784 
 785     char *dest;
 786     for (src = value, dest = quoted_value; *src != '\0'; ++src, ++dest) {
 787         if ('"' == *src) {
 788             *dest++ = '\\';
 789         }
 790         *dest = *src;
 791     }
 792 
 793     return quoted_value;
 794 }
 795 
 796 
 797 /*
 798  * Private variables - set some reasonable screen size defaults
 799  */
 800 
 801 static int centerpoint = 24;
 802 static int screen_width = 78;
 803 
 804 /*
 805  * Prints the passed message in a pretty or parsable format.
 806  */
 807 void pmix_info_out(const char *pretty_message, const char *plain_message, const char *value)
 808 {
 809     size_t len, max_value_width, value_offset;
 810     char *spaces = NULL;
 811     char *filler = NULL;
 812     char *pos, *v, savev, *v_to_free;
 813 
 814 #ifdef HAVE_ISATTY
 815     /* If we have isatty(), if this is not a tty, then disable
 816      * wrapping for grep-friendly behavior
 817      */
 818     if (0 == isatty(STDOUT_FILENO)) {
 819         screen_width = INT_MAX;
 820     }
 821 #endif
 822 
 823 #ifdef TIOCGWINSZ
 824     if (screen_width < INT_MAX) {
 825         struct winsize size;
 826         if (ioctl(STDOUT_FILENO, TIOCGWINSZ, (char*) &size) >= 0) {
 827             screen_width = size.ws_col;
 828         }
 829     }
 830 #endif
 831 
 832     /* Sanity check (allow NULL to mean "") */
 833     if (NULL == value) {
 834         value = "";
 835     }
 836 
 837     /* Strip leading and trailing whitespace from the string value */
 838     value_offset = strspn(value, " ");
 839 
 840     v = v_to_free = strdup(value + value_offset);
 841     len = strlen(v);
 842 
 843     if (len > 0) {
 844         while (len > 0 && isspace(v[len-1])) len--;
 845         v[len] = '\0';
 846     }
 847 
 848     if (pmix_info_pretty && NULL != pretty_message) {
 849         if (centerpoint > (int)strlen(pretty_message)) {
 850             if (0 > asprintf(&spaces, "%*s", centerpoint -
 851                              (int)strlen(pretty_message), " ")) {
 852                 if (NULL != v_to_free) {
 853                     free(v_to_free);
 854                 }
 855                 return;
 856             }
 857         } else {
 858             spaces = strdup("");
 859 #if PMIX_ENABLE_DEBUG
 860             if (centerpoint < (int)strlen(pretty_message)) {
 861                 pmix_show_help("help-pmix_info.txt",
 862                                "developer warning: field too long", false,
 863                                pretty_message, centerpoint);
 864             }
 865 #endif
 866         }
 867         max_value_width = screen_width - strlen(spaces) - strlen(pretty_message) - 2;
 868         if (0 < strlen(pretty_message)) {
 869             if (0 > asprintf(&filler, "%s%s: ", spaces, pretty_message)) {
 870                 if (NULL != v_to_free) {
 871                     free(v_to_free);
 872                 }
 873                 return;
 874             }
 875         } else {
 876             if (0 > asprintf(&filler, "%s  ", spaces)) {
 877                 if (NULL != v_to_free) {
 878                     free(v_to_free);
 879                 }
 880                 return;
 881             }
 882         }
 883         free(spaces);
 884         spaces = NULL;
 885 
 886         while (true) {
 887             if (strlen(v) < max_value_width) {
 888                 printf("%s%s\n", filler, v);
 889                 break;
 890             } else {
 891                 if (0 > asprintf(&spaces, "%*s", centerpoint + 2, " ")) {
 892                     if (NULL != v_to_free) {
 893                         free(v_to_free);
 894                     }
 895                     return;
 896                 }
 897 
 898                 /* Work backwards to find the first space before
 899                  * max_value_width
 900                  */
 901                 savev = v[max_value_width];
 902                 v[max_value_width] = '\0';
 903                 pos = (char*)strrchr(v, (int)' ');
 904                 v[max_value_width] = savev;
 905                 if (NULL == pos) {
 906                     /* No space found < max_value_width.  Look for the first
 907                      * space after max_value_width.
 908                      */
 909                     pos = strchr(&v[max_value_width], ' ');
 910 
 911                     if (NULL == pos) {
 912 
 913                         /* There's just no spaces.  So just print it and be done. */
 914 
 915                         printf("%s%s\n", filler, v);
 916                         break;
 917                     } else {
 918                         *pos = '\0';
 919                         printf("%s%s\n", filler, v);
 920                         v = pos + 1;
 921                     }
 922                 } else {
 923                     *pos = '\0';
 924                     printf("%s%s\n", filler, v);
 925                     v = pos + 1;
 926                 }
 927 
 928                 /* Reset for the next iteration */
 929                 free(filler);
 930                 filler = strdup(spaces);
 931                 free(spaces);
 932                 spaces = NULL;
 933             }
 934         }
 935         if (NULL != filler) {
 936             free(filler);
 937         }
 938         if (NULL != spaces) {
 939             free(spaces);
 940         }
 941     } else {
 942         if (NULL != plain_message && 0 < strlen(plain_message)) {
 943             // Escape any double quotes in the value.
 944             char *quoted_value;
 945             quoted_value = escape_quotes(value);
 946             if (NULL != quoted_value) {
 947                 value = quoted_value;
 948             }
 949 
 950             char *colon = strchr(value, ':');
 951             if (NULL != colon) {
 952                 printf("%s:\"%s\"\n", plain_message, value);
 953             } else {
 954                 printf("%s:%s\n", plain_message, value);
 955             }
 956 
 957             if (NULL != quoted_value) {
 958                 free(quoted_value);
 959             }
 960         } else {
 961             printf("%s\n", value);
 962         }
 963     }
 964     if (NULL != v_to_free) {
 965         free(v_to_free);
 966     }
 967 }
 968 
 969 /*
 970  * Prints the passed integer in a pretty or parsable format.
 971  */
 972 void pmix_info_out_int(const char *pretty_message,
 973                        const char *plain_message,
 974                        int value)
 975 {
 976     char *valstr;
 977 
 978     if (0 > asprintf(&valstr, "%d", (int)value)) {
 979         return;
 980     }
 981     pmix_info_out(pretty_message, plain_message, valstr);
 982     free(valstr);
 983 }
 984 
 985 /*
 986  * Show all the components of a specific type/component combo (component may be
 987  * a wildcard)
 988  */
 989 void pmix_info_show_component_version(pmix_pointer_array_t *mca_types,
 990                                       pmix_pointer_array_t *component_map,
 991                                       const char *type_name,
 992                                       const char *component_name,
 993                                       const char *scope, const char *ver_type)
 994 {
 995     bool want_all_components = false;
 996     bool want_all_types = false;
 997     bool found;
 998     pmix_mca_base_component_list_item_t *cli;
 999     pmix_mca_base_failed_component_t *cli_failed;
1000     int j;
1001     char *pos;
1002     pmix_info_component_map_t *map;
1003 
1004     /* see if all components wanted */
1005     if (0 == strcmp(pmix_info_component_all, component_name)) {
1006         want_all_components = true;
1007     }
1008 
1009     /* see if all types wanted */
1010     if (0 != strcmp(pmix_info_type_all, type_name)) {
1011         /* Check to see if the type is valid */
1012 
1013         for (found = false, j = 0; j < mca_types->size; ++j) {
1014             if (NULL == (pos = (char*)pmix_pointer_array_get_item(mca_types, j))) {
1015                 continue;
1016             }
1017             if (0 == strcmp(pos, type_name)) {
1018                 found = true;
1019                 break;
1020             }
1021         }
1022 
1023         if (!found) {
1024             return;
1025         }
1026     } else {
1027         want_all_types = true;
1028     }
1029 
1030     /* Now that we have a valid type, find the right components */
1031     for (j=0; j < component_map->size; j++) {
1032         if (NULL == (map = (pmix_info_component_map_t*)pmix_pointer_array_get_item(component_map, j))) {
1033             continue;
1034         }
1035         if ((want_all_types || 0 == strcmp(type_name, map->type)) && map->components) {
1036             /* found it! */
1037             PMIX_LIST_FOREACH(cli, map->components, pmix_mca_base_component_list_item_t) {
1038                 const pmix_mca_base_component_t *component = cli->cli_component;
1039                 if (want_all_components ||
1040                     0 == strcmp(component->pmix_mca_component_name, component_name)) {
1041                     pmix_info_show_mca_version(component, scope, ver_type);
1042                 }
1043             }
1044 
1045             /* found it! */
1046             PMIX_LIST_FOREACH(cli_failed, map->failed_components, pmix_mca_base_failed_component_t) {
1047                 pmix_mca_base_component_repository_item_t *ri = cli_failed->comp;
1048                 if (want_all_components ||
1049                     0 == strcmp(component_name, ri->ri_name) ) {
1050                     pmix_info_show_failed_component(ri, cli_failed->error_msg);
1051                 }
1052             }
1053 
1054             if (!want_all_types) {
1055                 break;
1056             }
1057         }
1058     }
1059 }
1060 
1061 
1062 static void pmix_info_show_failed_component(const pmix_mca_base_component_repository_item_t* ri,
1063                                             const char *error_msg)
1064 {
1065     char *message, *content;
1066 
1067     if (pmix_info_pretty) {
1068         if (0 > asprintf(&message, "MCA %s", ri->ri_type)) {
1069             return;
1070         }
1071         if (0 > asprintf(&content, "%s (failed to load) %s", ri->ri_name, error_msg)) {
1072             free(message);
1073             return;
1074         }
1075 
1076         pmix_info_out(message, NULL, content);
1077 
1078         free(message);
1079         free(content);
1080     } else {
1081         if (0 > asprintf(&message, "mca:%s:%s:failed", ri->ri_type, ri->ri_name)) {
1082             return;
1083         }
1084         if (0 > asprintf(&content, "%s", error_msg)) {
1085             free(message);
1086             return;
1087         }
1088 
1089         pmix_info_out(NULL, message, content);
1090 
1091         free(message);
1092         free(content);
1093     }
1094 }
1095 
1096 /*
1097  * Given a component, display its relevant version(s)
1098  */
1099 void pmix_info_show_mca_version(const pmix_mca_base_component_t* component,
1100                                 const char *scope, const char *ver_type)
1101 {
1102     bool printed;
1103     bool want_mca = false;
1104     bool want_type = false;
1105     bool want_component = false;
1106     char *message = NULL, *content = NULL;
1107     char *mca_version;
1108     char *api_version;
1109     char *component_version;
1110     char *tmp;
1111 
1112     if (0 == strcmp(ver_type, pmix_info_ver_all) ||
1113         0 == strcmp(ver_type, pmix_info_ver_mca)) {
1114         want_mca = true;
1115     }
1116 
1117     if (0 == strcmp(ver_type, pmix_info_ver_all) ||
1118         0 == strcmp(ver_type, pmix_info_ver_type)) {
1119         want_type = true;
1120     }
1121 
1122     if (0 == strcmp(ver_type, pmix_info_ver_all) ||
1123         0 == strcmp(ver_type, pmix_info_ver_component)) {
1124         want_component = true;
1125     }
1126 
1127     mca_version = pmix_info_make_version_str(scope, component->pmix_mca_major_version,
1128                                              component->pmix_mca_minor_version,
1129                                              component->pmix_mca_release_version, "",
1130                                              "");
1131     api_version = pmix_info_make_version_str(scope, component->pmix_mca_type_major_version,
1132                                              component->pmix_mca_type_minor_version,
1133                                              component->pmix_mca_type_release_version, "",
1134                                              "");
1135     component_version = pmix_info_make_version_str(scope, component->pmix_mca_component_major_version,
1136                                                    component->pmix_mca_component_minor_version,
1137                                                    component->pmix_mca_component_release_version,
1138                                                    "", "");
1139     if (pmix_info_pretty) {
1140         if (0 > asprintf(&message, "MCA %s", component->pmix_mca_type_name)) {
1141             goto exit;
1142         }
1143         printed = false;
1144         if (0 > asprintf(&content, "%s (", component->pmix_mca_component_name)) {
1145             goto exit;
1146         }
1147 
1148         if (want_mca) {
1149             if (0 > asprintf(&tmp, "%sMCA v%s", content, mca_version)) {
1150                 goto exit;
1151             }
1152             content = tmp;
1153             printed = true;
1154         }
1155 
1156         if (want_type) {
1157             if (printed) {
1158                 if (0 > asprintf(&tmp, "%s, ", content)) {
1159                     goto exit;
1160                 }
1161                 free(content);
1162                 content = tmp;
1163             }
1164             if (0 > asprintf(&tmp, "%sAPI v%s", content, api_version)) {
1165                 goto exit;
1166             }
1167             free(content);
1168             content = tmp;
1169             printed = true;
1170         }
1171 
1172         if (want_component) {
1173             if (printed) {
1174                 if (0 > asprintf(&tmp, "%s, ", content)) {
1175                     goto exit;
1176                 }
1177                 free(content);
1178                 content = tmp;
1179             }
1180             if (0 > asprintf(&tmp, "%sComponent v%s", content, component_version)) {
1181                 goto exit;
1182             }
1183             free(content);
1184             content = tmp;
1185             printed = true;
1186         }
1187         if (NULL != content) {
1188             if (0 > asprintf(&tmp, "%s)", content)) {
1189                 goto exit;
1190             }
1191         } else {
1192             tmp = NULL;
1193         }
1194 
1195         pmix_info_out(message, NULL, tmp);
1196         if (NULL != tmp) {
1197             free(tmp);
1198         }
1199 
1200     } else {
1201         if (0 > asprintf(&message, "mca:%s:%s:version", component->pmix_mca_type_name, component->pmix_mca_component_name)) {
1202             goto exit;
1203         }
1204         if (want_mca) {
1205             if (0 > asprintf(&tmp, "mca:%s", mca_version)) {
1206                 goto exit;
1207             }
1208             pmix_info_out(NULL, message, tmp);
1209             free(tmp);
1210         }
1211         if (want_type) {
1212             if (0 > asprintf(&tmp, "api:%s", api_version)) {
1213                 goto exit;
1214             }
1215             pmix_info_out(NULL, message, tmp);
1216             free(tmp);
1217         }
1218         if (want_component) {
1219             if (0 > asprintf(&tmp, "component:%s", component_version)) {
1220                 goto exit;
1221             }
1222             pmix_info_out(NULL, message, tmp);
1223             free(tmp);
1224         }
1225     }
1226 
1227 exit:
1228     if (NULL != mca_version) {
1229         free(mca_version);
1230     }
1231     if (NULL != api_version) {
1232         free(api_version);
1233     }
1234     if (NULL != component_version) {
1235         free(component_version);
1236     }
1237     if (NULL != message) {
1238         free(message);
1239     }
1240     if (NULL != content) {
1241         free(content);
1242     }
1243 }
1244 
1245 
1246 char *pmix_info_make_version_str(const char *scope,
1247                                  int major, int minor, int release,
1248                                  const char *greek,
1249                                  const char *repo)
1250 {
1251     char *str = NULL, *tmp;
1252     char temp[BUFSIZ];
1253 
1254     temp[BUFSIZ - 1] = '\0';
1255     if (0 == strcmp(scope, pmix_info_ver_full) ||
1256         0 == strcmp(scope, pmix_info_ver_all)) {
1257         snprintf(temp, BUFSIZ - 1, "%d.%d.%d", major, minor, release);
1258         str = strdup(temp);
1259         if (NULL != greek) {
1260             if (0 > asprintf(&tmp, "%s%s", str, greek)) {
1261                 free(str);
1262                 return NULL;
1263             }
1264             free(str);
1265             str = tmp;
1266         }
1267     } else if (0 == strcmp(scope, pmix_info_ver_major)) {
1268         snprintf(temp, BUFSIZ - 1, "%d", major);
1269     } else if (0 == strcmp(scope, pmix_info_ver_minor)) {
1270         snprintf(temp, BUFSIZ - 1, "%d", minor);
1271     } else if (0 == strcmp(scope, pmix_info_ver_release)) {
1272         snprintf(temp, BUFSIZ - 1, "%d", release);
1273     } else if (0 == strcmp(scope, pmix_info_ver_greek)) {
1274         str = strdup(greek);
1275     } else if (0 == strcmp(scope, pmix_info_ver_repo)) {
1276         str = strdup(repo);
1277     }
1278 
1279     if (NULL == str) {
1280         str = strdup(temp);
1281     }
1282 
1283     return str;
1284 }
1285 
1286 void pmix_info_show_pmix_version(const char *scope)
1287 {
1288     char *tmp, *tmp2;
1289 
1290     if (0 > asprintf(&tmp, "%s:version:full", pmix_info_type_pmix)) {
1291         return;
1292     }
1293     tmp2 = pmix_info_make_version_str(scope,
1294                                       PMIX_MAJOR_VERSION, PMIX_MINOR_VERSION,
1295                                       PMIX_RELEASE_VERSION,
1296                                       PMIX_GREEK_VERSION,
1297                                       PMIX_REPO_REV);
1298     pmix_info_out("PMIX", tmp, tmp2);
1299     free(tmp);
1300     free(tmp2);
1301     if (0 > asprintf(&tmp, "%s:version:repo", pmix_info_type_pmix)) {
1302         return;
1303     }
1304     pmix_info_out("PMIX repo revision", tmp, PMIX_REPO_REV);
1305     free(tmp);
1306     if (0 > asprintf(&tmp, "%s:version:release_date", pmix_info_type_pmix)) {
1307         return;
1308     }
1309     pmix_info_out("PMIX release date", tmp, PMIX_RELEASE_DATE);
1310     free(tmp);
1311 }
1312 
1313 /*
1314  * do_config
1315  * Accepts:
1316  *  - want_all: boolean flag; TRUE -> display all options
1317  *                FALSE -> display selected options
1318  *
1319  * This function displays all the options with which the current
1320  * installation of pmix was configured. There are many options here
1321  * that are carried forward from OMPI-7 and are not mca parameters
1322  * in OMPI-10. I have to dig through the invalid options and replace
1323  * them with OMPI-10 options.
1324  */
1325 void pmix_info_do_config(bool want_all)
1326 {
1327     char *debug;
1328     char *have_dl;
1329     char *symbol_visibility;
1330 
1331     /* setup the strings that don't require allocations*/
1332     debug = PMIX_ENABLE_DEBUG ? "yes" : "no";
1333     have_dl = PMIX_HAVE_PDL_SUPPORT ? "yes" : "no";
1334     symbol_visibility = PMIX_HAVE_VISIBILITY ? "yes" : "no";
1335 
1336     /* output values */
1337     pmix_info_out("Configured by", "config:user", PMIX_CONFIGURE_USER);
1338     pmix_info_out("Configured on", "config:timestamp", PMIX_CONFIGURE_DATE);
1339     pmix_info_out("Configure host", "config:host", PMIX_CONFIGURE_HOST);
1340     pmix_info_out("Configure command line", "config:cli", PMIX_CONFIGURE_CLI);
1341 
1342     pmix_info_out("Built by", "build:user", PMIX_BUILD_USER);
1343     pmix_info_out("Built on", "build:timestamp", PMIX_BUILD_DATE);
1344     pmix_info_out("Built host", "build:host", PMIX_BUILD_HOST);
1345 
1346     pmix_info_out("C compiler", "compiler:c:command", PMIX_CC);
1347     pmix_info_out("C compiler absolute", "compiler:c:absolute", PMIX_CC_ABSOLUTE);
1348     pmix_info_out("C compiler family name", "compiler:c:familyname", _STRINGIFY(PMIX_BUILD_PLATFORM_COMPILER_FAMILYNAME));
1349     pmix_info_out("C compiler version", "compiler:c:version", _STRINGIFY(PMIX_BUILD_PLATFORM_COMPILER_VERSION_STR));
1350 
1351     if (want_all) {
1352         pmix_info_out_int("C char size", "compiler:c:sizeof:char", sizeof(char));
1353         pmix_info_out_int("C bool size", "compiler:c:sizeof:bool", sizeof(bool));
1354         pmix_info_out_int("C short size", "compiler:c:sizeof:short", sizeof(short));
1355         pmix_info_out_int("C int size", "compiler:c:sizeof:int", sizeof(int));
1356         pmix_info_out_int("C long size", "compiler:c:sizeof:long", sizeof(long));
1357         pmix_info_out_int("C float size", "compiler:c:sizeof:float", sizeof(float));
1358         pmix_info_out_int("C double size", "compiler:c:sizeof:double", sizeof(double));
1359         pmix_info_out_int("C pointer size", "compiler:c:sizeof:pointer", sizeof(void *));
1360         pmix_info_out_int("C char align", "compiler:c:align:char", PMIX_ALIGNMENT_CHAR);
1361         pmix_info_out("C bool align", "compiler:c:align:bool", "skipped");
1362         pmix_info_out_int("C int align", "compiler:c:align:int", PMIX_ALIGNMENT_INT);
1363         pmix_info_out_int("C float align", "compiler:c:align:float", PMIX_ALIGNMENT_FLOAT);
1364         pmix_info_out_int("C double align", "compiler:c:align:double", PMIX_ALIGNMENT_DOUBLE);
1365     }
1366 
1367     if (want_all) {
1368         pmix_info_out("Build CFLAGS", "option:build:cflags", PMIX_BUILD_CFLAGS);
1369         pmix_info_out("Build LDFLAGS", "option:build:ldflags", PMIX_BUILD_LDFLAGS);
1370         pmix_info_out("Build LIBS", "option:build:libs", PMIX_BUILD_LIBS);
1371     }
1372 
1373     pmix_info_out("Internal debug support", "option:debug", debug);
1374     pmix_info_out("dl support", "option:dlopen", have_dl);
1375     pmix_info_out("Symbol vis. support", "options:visibility", symbol_visibility);
1376 }

/* [<][>][^][v][top][bottom][index][help] */