root/opal/runtime/opal_info_support.c

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

DEFINITIONS

This source file includes following definitions.
  1. component_map_construct
  2. component_map_destruct
  3. opal_info_init
  4. opal_info_finalize
  5. info_register_framework
  6. opal_info_register_project_frameworks
  7. opal_info_register_types
  8. opal_info_register_framework_params
  9. opal_info_close_components
  10. opal_info_show_path
  11. opal_info_do_path
  12. opal_info_do_params
  13. opal_info_err_params
  14. opal_info_do_type
  15. opal_info_show_mca_group_params
  16. opal_info_show_mca_params
  17. opal_info_do_arch
  18. opal_info_do_hostname
  19. escape_quotes
  20. opal_info_out
  21. opal_info_out_int
  22. opal_info_show_component_version
  23. opal_info_show_failed_component
  24. opal_info_show_mca_version
  25. opal_info_make_version_str
  26. opal_info_show_opal_version

   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-2017 Intel, Inc. All rights reserved.
  18  * Copyright (c) 2017 IBM Corporation.  All rights reserved.
  19  * Copyright (c) 2018      Amazon.com, Inc. or its affiliates.  All Rights reserved.
  20  * $COPYRIGHT$
  21  *
  22  * Additional copyrights may follow
  23  *
  24  * $HEADER$
  25  */
  26 
  27 #include "opal_config.h"
  28 
  29 #include <string.h>
  30 #include <ctype.h>
  31 
  32 #ifdef HAVE_UNISTD_H
  33 #include <unistd.h>
  34 #endif
  35 
  36 #include <errno.h>
  37 
  38 #include "opal/class/opal_list.h"
  39 #include "opal/class/opal_pointer_array.h"
  40 
  41 #include "opal/util/output.h"
  42 #include "opal/util/cmd_line.h"
  43 #include "opal/util/error.h"
  44 #include "opal/util/argv.h"
  45 #include "opal/util/show_help.h"
  46 #include "opal/util/printf.h"
  47 #include "opal/runtime/opal.h"
  48 #include "opal/dss/dss.h"
  49 #include "opal/mca/base/mca_base_pvar.h"
  50 
  51 #include "opal/include/opal/frameworks.h"
  52 
  53 #include "opal/mca/installdirs/installdirs.h"
  54 
  55 #include "opal/runtime/opal_info_support.h"
  56 #include "opal/mca/base/mca_base_component_repository.h"
  57 
  58 const char *opal_info_path_prefix = "prefix";
  59 const char *opal_info_path_bindir = "bindir";
  60 const char *opal_info_path_libdir = "libdir";
  61 const char *opal_info_path_incdir = "incdir";
  62 const char *opal_info_path_mandir = "mandir";
  63 const char *opal_info_path_pkglibdir = "pkglibdir";
  64 const char *opal_info_path_sysconfdir = "sysconfdir";
  65 const char *opal_info_path_exec_prefix = "exec_prefix";
  66 const char *opal_info_path_sbindir = "sbindir";
  67 const char *opal_info_path_libexecdir = "libexecdir";
  68 const char *opal_info_path_datarootdir = "datarootdir";
  69 const char *opal_info_path_datadir = "datadir";
  70 const char *opal_info_path_sharedstatedir = "sharedstatedir";
  71 const char *opal_info_path_localstatedir = "localstatedir";
  72 const char *opal_info_path_infodir = "infodir";
  73 const char *opal_info_path_pkgdatadir = "pkgdatadir";
  74 const char *opal_info_path_pkgincludedir = "pkgincludedir";
  75 
  76 bool opal_info_pretty = true;
  77 mca_base_register_flag_t opal_info_register_flags = MCA_BASE_REGISTER_ALL;
  78 
  79 const char *opal_info_type_all = "all";
  80 const char *opal_info_type_opal = "opal";
  81 const char *opal_info_component_all = "all";
  82 const char *opal_info_param_all = "all";
  83 
  84 const char *opal_info_ver_full = "full";
  85 const char *opal_info_ver_major = "major";
  86 const char *opal_info_ver_minor = "minor";
  87 const char *opal_info_ver_release = "release";
  88 const char *opal_info_ver_greek = "greek";
  89 const char *opal_info_ver_repo = "repo";
  90 
  91 const char *opal_info_ver_all = "all";
  92 const char *opal_info_ver_mca = "mca";
  93 const char *opal_info_ver_type = "type";
  94 const char *opal_info_ver_component = "component";
  95 
  96 static int opal_info_registered = 0;
  97 
  98 static void component_map_construct(opal_info_component_map_t *map)
  99 {
 100     map->type = NULL;
 101 }
 102 static void component_map_destruct(opal_info_component_map_t *map)
 103 {
 104     if (NULL != map->type) {
 105         free(map->type);
 106     }
 107     /* the type close functions will release the
 108      * list of components
 109      */
 110 }
 111 OBJ_CLASS_INSTANCE(opal_info_component_map_t,
 112                    opal_list_item_t,
 113                    component_map_construct,
 114                    component_map_destruct);
 115 
 116 static void opal_info_show_failed_component(const mca_base_component_repository_item_t* ri,
 117                                             const char *error_msg);
 118 
 119 int opal_info_init(int argc, char **argv,
 120                    opal_cmd_line_t *opal_info_cmd_line)
 121 {
 122     int ret;
 123     bool want_help = false;
 124     bool cmd_error = false;
 125     char **app_env = NULL, **global_env = NULL;
 126 
 127     /* Initialize the argv parsing handle */
 128     if (OPAL_SUCCESS != (ret = opal_init_util(&argc, &argv))) {
 129         opal_show_help("help-opal_info.txt", "lib-call-fail", true,
 130                        "opal_init_util", __FILE__, __LINE__, NULL);
 131         exit(ret);
 132     }
 133 
 134     /* add the cmd line options */
 135     opal_cmd_line_make_opt3(opal_info_cmd_line, 'V', NULL, "version", 0,
 136                             "Show version of Open MPI");
 137     opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "param", 2,
 138                             "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\").");
 139     opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "params", 2,
 140                             "Synonym for --param");
 141     opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "internal", 0,
 142                             "Show internal MCA parameters (not meant to be modified by users)");
 143     opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "path", 1,
 144                             "Show paths that Open MPI was configured with.  Accepts the following parameters: prefix, bindir, libdir, incdir, mandir, pkglibdir, sysconfdir, all");
 145     opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "arch", 0,
 146                             "Show architecture Open MPI was compiled on");
 147     opal_cmd_line_make_opt3(opal_info_cmd_line, 'c', NULL, "config", 0,
 148                             "Show configuration options");
 149     opal_cmd_line_make_opt3(opal_info_cmd_line, 't', NULL, "type", 1,
 150                             "Show internal MCA parameters with the type specified in parameter.");
 151     opal_cmd_line_make_opt3(opal_info_cmd_line, 'h', NULL, "help", 0,
 152                             "Show this help message");
 153     opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "pretty-print", 0,
 154                             "When used in conjunction with other parameters, the output is displayed in 'pretty-print' format (default)");
 155     opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "parsable", 0,
 156                             "When used in conjunction with other parameters, the output is displayed in a machine-parsable format");
 157     opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "parseable", 0,
 158                             "Synonym for --parsable");
 159     opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "hostname", 0,
 160                             "Show the hostname that Open MPI was configured and built on");
 161     opal_cmd_line_make_opt3(opal_info_cmd_line, 'a', NULL, "all", 0,
 162                             "Show all configuration options and MCA parameters");
 163     opal_cmd_line_make_opt3(opal_info_cmd_line, 'l', NULL, "level", 1,
 164                             "Show only variables with at most this level (1-9)");
 165     opal_cmd_line_make_opt3(opal_info_cmd_line, 's', NULL, "selected-only", 0,
 166                             "Show only variables from selected components");
 167     opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "show-failed", 0,
 168                             "Show the components that failed to load along with the reason why they failed.");
 169 
 170     /* set our threading level */
 171     opal_set_using_threads(false);
 172 
 173     /* Get MCA parameters, if any */
 174     if( OPAL_SUCCESS != mca_base_open() ) {
 175         opal_show_help("help-opal_info.txt", "lib-call-fail", true, "mca_base_open", __FILE__, __LINE__ );
 176         opal_finalize_util();
 177         return OPAL_ERROR;
 178     }
 179     mca_base_cmd_line_setup(opal_info_cmd_line);
 180 
 181     /* Initialize the opal_output system */
 182     if (!opal_output_init()) {
 183         return OPAL_ERROR;
 184     }
 185 
 186     /* Do the parsing */
 187     ret = opal_cmd_line_parse(opal_info_cmd_line, false, false, argc, argv);
 188     if (OPAL_SUCCESS != ret) {
 189         cmd_error = true;
 190         if (OPAL_ERR_SILENT != ret) {
 191             fprintf(stderr, "%s: command line error (%s)\n", argv[0],
 192                     opal_strerror(ret));
 193         }
 194     }
 195     if (!cmd_error &&
 196         (opal_cmd_line_is_taken(opal_info_cmd_line, "help") ||
 197          opal_cmd_line_is_taken(opal_info_cmd_line, "h"))) {
 198         char *str, *usage;
 199 
 200         want_help = true;
 201         usage = opal_cmd_line_get_usage_msg(opal_info_cmd_line);
 202         str = opal_show_help_string("help-opal_info.txt", "usage",
 203                                     true, usage);
 204         if (NULL != str) {
 205             printf("%s", str);
 206             free(str);
 207         }
 208         free(usage);
 209     }
 210 
 211     /* If we had a cmd line parse error, or we showed the help
 212        message, it's time to exit. */
 213     if (cmd_error || want_help) {
 214         mca_base_close();
 215         OBJ_RELEASE(opal_info_cmd_line);
 216         opal_finalize_util();
 217         exit(cmd_error ? 1 : 0);
 218     }
 219 
 220     mca_base_cmd_line_process_args(opal_info_cmd_line, &app_env, &global_env);
 221 
 222 
 223     /* set the flags */
 224     if (opal_cmd_line_is_taken(opal_info_cmd_line, "pretty-print")) {
 225         opal_info_pretty = true;
 226     } else if (opal_cmd_line_is_taken(opal_info_cmd_line, "parsable") || opal_cmd_line_is_taken(opal_info_cmd_line, "parseable")) {
 227         opal_info_pretty = false;
 228     }
 229 
 230     if (opal_cmd_line_is_taken(opal_info_cmd_line, "selected-only")) {
 231         /* register only selected components */
 232         opal_info_register_flags = MCA_BASE_REGISTER_DEFAULT;
 233     }
 234 
 235     if( opal_cmd_line_is_taken(opal_info_cmd_line, "show-failed") ) {
 236         mca_base_component_track_load_errors = true;
 237     }
 238 
 239     return OPAL_SUCCESS;
 240 }
 241 
 242 void opal_info_finalize(void)
 243 {
 244     opal_finalize_util();
 245 }
 246 
 247 static int info_register_framework (mca_base_framework_t *framework, opal_pointer_array_t *component_map)
 248 {
 249     opal_info_component_map_t *map;
 250     int rc;
 251 
 252     rc = mca_base_framework_register(framework, opal_info_register_flags);
 253     if (OPAL_SUCCESS != rc && OPAL_ERR_BAD_PARAM != rc) {
 254         return rc;
 255     }
 256 
 257     if (NULL != component_map) {
 258         map = OBJ_NEW(opal_info_component_map_t);
 259         map->type = strdup(framework->framework_name);
 260         map->components = &framework->framework_components;
 261         map->failed_components = &framework->framework_failed_components;
 262         opal_pointer_array_add(component_map, map);
 263     }
 264 
 265     return rc;
 266 }
 267 
 268 int opal_info_register_project_frameworks (const char *project_name, mca_base_framework_t **frameworks,
 269                                            opal_pointer_array_t *component_map)
 270 {
 271     int i, rc=OPAL_SUCCESS;
 272 
 273     for (i=0; NULL != frameworks[i]; i++) {
 274         if (OPAL_SUCCESS != (rc = info_register_framework(frameworks[i], component_map))) {
 275             if (OPAL_ERR_BAD_PARAM == rc) {
 276                 fprintf(stderr, "\nA \"bad parameter\" error was encountered when opening the %s %s framework\n",
 277                         project_name, frameworks[i]->framework_name);
 278                 fprintf(stderr, "The output received from that framework includes the following parameters:\n\n");
 279             } else if (OPAL_ERR_NOT_AVAILABLE != rc) {
 280                 fprintf(stderr, "%s_info_register: %s failed\n", project_name, frameworks[i]->framework_name);
 281                 rc = OPAL_ERROR;
 282             } else {
 283                 continue;
 284             }
 285 
 286             break;
 287         }
 288     }
 289 
 290     return rc;
 291 }
 292 
 293 void opal_info_register_types(opal_pointer_array_t *mca_types)
 294 {
 295     int i;
 296 
 297     /* add the top-level types */
 298     opal_pointer_array_add(mca_types, "mca");
 299     opal_pointer_array_add(mca_types, "opal");
 300 
 301     /* push all the types found by autogen */
 302     for (i=0; NULL != opal_frameworks[i]; i++) {
 303         opal_pointer_array_add(mca_types, opal_frameworks[i]->framework_name);
 304     }
 305 }
 306 
 307 int opal_info_register_framework_params(opal_pointer_array_t *component_map)
 308 {
 309     int rc;
 310 
 311     if (opal_info_registered++) {
 312         return OPAL_SUCCESS;
 313     }
 314 
 315     /* Register mca/base parameters */
 316     if( OPAL_SUCCESS != mca_base_open() ) {
 317         opal_show_help("help-opal_info.txt", "lib-call-fail", true, "mca_base_open", __FILE__, __LINE__ );
 318         return OPAL_ERROR;
 319     }
 320 
 321     /* Register the OPAL layer's MCA parameters */
 322     if (OPAL_SUCCESS != (rc = opal_register_params())) {
 323         fprintf(stderr, "opal_info_register: opal_register_params failed\n");
 324         return rc;
 325     }
 326 
 327     return opal_info_register_project_frameworks("opal", opal_frameworks, component_map);
 328 }
 329 
 330 
 331 void opal_info_close_components(void)
 332 {
 333     int i;
 334 
 335     assert(opal_info_registered);
 336     if (--opal_info_registered) {
 337         return;
 338     }
 339 
 340     for (i=0; NULL != opal_frameworks[i]; i++) {
 341         (void) mca_base_framework_close(opal_frameworks[i]);
 342     }
 343 
 344     /* release our reference to MCA */
 345     mca_base_close ();
 346 }
 347 
 348 
 349 void opal_info_show_path(const char *type, const char *value)
 350 {
 351     char *pretty, *path;
 352 
 353     pretty = strdup(type);
 354     pretty[0] = toupper(pretty[0]);
 355 
 356     opal_asprintf(&path, "path:%s", type);
 357     opal_info_out(pretty, path, value);
 358     free(pretty);
 359     free(path);
 360 }
 361 
 362 void opal_info_do_path(bool want_all, opal_cmd_line_t *cmd_line)
 363 {
 364     int i, count;
 365     char *scope;
 366 
 367     /* Check bozo case */
 368     count = opal_cmd_line_get_ninsts(cmd_line, "path");
 369     for (i = 0; i < count; ++i) {
 370         scope = opal_cmd_line_get_param(cmd_line, "path", i, 0);
 371         if (0 == strcmp("all", scope)) {
 372             want_all = true;
 373             break;
 374         }
 375     }
 376 
 377     if (want_all) {
 378         opal_info_show_path(opal_info_path_prefix, opal_install_dirs.prefix);
 379         opal_info_show_path(opal_info_path_exec_prefix, opal_install_dirs.exec_prefix);
 380         opal_info_show_path(opal_info_path_bindir, opal_install_dirs.bindir);
 381         opal_info_show_path(opal_info_path_sbindir, opal_install_dirs.sbindir);
 382         opal_info_show_path(opal_info_path_libdir, opal_install_dirs.libdir);
 383         opal_info_show_path(opal_info_path_incdir, opal_install_dirs.includedir);
 384         opal_info_show_path(opal_info_path_mandir, opal_install_dirs.mandir);
 385         opal_info_show_path(opal_info_path_pkglibdir, opal_install_dirs.opallibdir);
 386         opal_info_show_path(opal_info_path_libexecdir, opal_install_dirs.libexecdir);
 387         opal_info_show_path(opal_info_path_datarootdir, opal_install_dirs.datarootdir);
 388         opal_info_show_path(opal_info_path_datadir, opal_install_dirs.datadir);
 389         opal_info_show_path(opal_info_path_sysconfdir, opal_install_dirs.sysconfdir);
 390         opal_info_show_path(opal_info_path_sharedstatedir, opal_install_dirs.sharedstatedir);
 391         opal_info_show_path(opal_info_path_localstatedir, opal_install_dirs.localstatedir);
 392         opal_info_show_path(opal_info_path_infodir, opal_install_dirs.infodir);
 393         opal_info_show_path(opal_info_path_pkgdatadir, opal_install_dirs.opaldatadir);
 394         opal_info_show_path(opal_info_path_pkglibdir, opal_install_dirs.opallibdir);
 395         opal_info_show_path(opal_info_path_pkgincludedir, opal_install_dirs.opalincludedir);
 396     } else {
 397         count = opal_cmd_line_get_ninsts(cmd_line, "path");
 398         for (i = 0; i < count; ++i) {
 399             scope = opal_cmd_line_get_param(cmd_line, "path", i, 0);
 400 
 401             if (0 == strcmp(opal_info_path_prefix, scope)) {
 402                 opal_info_show_path(opal_info_path_prefix, opal_install_dirs.prefix);
 403             } else if (0 == strcmp(opal_info_path_bindir, scope)) {
 404                 opal_info_show_path(opal_info_path_bindir, opal_install_dirs.bindir);
 405             } else if (0 == strcmp(opal_info_path_libdir, scope)) {
 406                 opal_info_show_path(opal_info_path_libdir, opal_install_dirs.libdir);
 407             } else if (0 == strcmp(opal_info_path_incdir, scope)) {
 408                 opal_info_show_path(opal_info_path_incdir, opal_install_dirs.includedir);
 409             } else if (0 == strcmp(opal_info_path_mandir, scope)) {
 410                 opal_info_show_path(opal_info_path_mandir, opal_install_dirs.mandir);
 411             } else if (0 == strcmp(opal_info_path_pkglibdir, scope)) {
 412                 opal_info_show_path(opal_info_path_pkglibdir, opal_install_dirs.opallibdir);
 413             } else if (0 == strcmp(opal_info_path_sysconfdir, scope)) {
 414                 opal_info_show_path(opal_info_path_sysconfdir, opal_install_dirs.sysconfdir);
 415             } else if (0 == strcmp(opal_info_path_exec_prefix, scope)) {
 416                 opal_info_show_path(opal_info_path_exec_prefix, opal_install_dirs.exec_prefix);
 417             } else if (0 == strcmp(opal_info_path_sbindir, scope)) {
 418                 opal_info_show_path(opal_info_path_sbindir, opal_install_dirs.sbindir);
 419             } else if (0 == strcmp(opal_info_path_libexecdir, scope)) {
 420                 opal_info_show_path(opal_info_path_libexecdir, opal_install_dirs.libexecdir);
 421             } else if (0 == strcmp(opal_info_path_datarootdir, scope)) {
 422                 opal_info_show_path(opal_info_path_datarootdir, opal_install_dirs.datarootdir);
 423             } else if (0 == strcmp(opal_info_path_datadir, scope)) {
 424                 opal_info_show_path(opal_info_path_datadir, opal_install_dirs.datadir);
 425             } else if (0 == strcmp(opal_info_path_sharedstatedir, scope)) {
 426                 opal_info_show_path(opal_info_path_sharedstatedir, opal_install_dirs.sharedstatedir);
 427             } else if (0 == strcmp(opal_info_path_localstatedir, scope)) {
 428                 opal_info_show_path(opal_info_path_localstatedir, opal_install_dirs.localstatedir);
 429             } else if (0 == strcmp(opal_info_path_infodir, scope)) {
 430                 opal_info_show_path(opal_info_path_infodir, opal_install_dirs.infodir);
 431             } else if (0 == strcmp(opal_info_path_pkgdatadir, scope)) {
 432                 opal_info_show_path(opal_info_path_pkgdatadir, opal_install_dirs.opaldatadir);
 433             } else if (0 == strcmp(opal_info_path_pkgincludedir, scope)) {
 434                 opal_info_show_path(opal_info_path_pkgincludedir, opal_install_dirs.opalincludedir);
 435             } else {
 436                 char *usage = opal_cmd_line_get_usage_msg(cmd_line);
 437                 opal_show_help("help-opal_info.txt", "usage", true, usage);
 438                 free(usage);
 439                 exit(1);
 440             }
 441         }
 442     }
 443 }
 444 
 445 void opal_info_do_params(bool want_all_in, bool want_internal,
 446                          opal_pointer_array_t *mca_types,
 447                          opal_pointer_array_t *component_map,
 448                          opal_cmd_line_t *opal_info_cmd_line)
 449 {
 450     mca_base_var_info_lvl_t max_level = OPAL_INFO_LVL_1;
 451     int count;
 452     char *type, *component, *str;
 453     bool found;
 454     int i;
 455     bool want_all = false;
 456     char *p;
 457 
 458     if (opal_cmd_line_is_taken(opal_info_cmd_line, "param")) {
 459         p = "param";
 460     } else if (opal_cmd_line_is_taken(opal_info_cmd_line, "params")) {
 461         p = "params";
 462     } else {
 463         p = "foo";  /* should never happen, but protect against segfault */
 464     }
 465 
 466     if (NULL != (str = opal_cmd_line_get_param (opal_info_cmd_line, "level", 0, 0))) {
 467         char *tmp;
 468 
 469         errno = 0;
 470         max_level = strtol (str, &tmp, 10) + OPAL_INFO_LVL_1 - 1;
 471         if (0 != errno || '\0' != tmp[0] || max_level < OPAL_INFO_LVL_1 || max_level > OPAL_INFO_LVL_9) {
 472             char *usage = opal_cmd_line_get_usage_msg(opal_info_cmd_line);
 473             opal_show_help("help-opal_info.txt", "invalid-level", true, str);
 474             free(usage);
 475             exit(1);
 476         }
 477     } else if (want_all_in) {
 478         /* if not specified default to level 9 if all components are requested */
 479         max_level = OPAL_INFO_LVL_9;
 480     }
 481 
 482     if (want_all_in) {
 483         want_all = true;
 484     } else {
 485         /* See if the special param "all" was given to --param; that
 486          * supercedes any individual type
 487          */
 488         count = opal_cmd_line_get_ninsts(opal_info_cmd_line, p);
 489         for (i = 0; i < count; ++i) {
 490             type = opal_cmd_line_get_param(opal_info_cmd_line, p, (int)i, 0);
 491             if (0 == strcmp(opal_info_type_all, type)) {
 492                 want_all = true;
 493                 break;
 494             }
 495         }
 496     }
 497 
 498     /* Show the params */
 499 
 500     if (want_all) {
 501         opal_info_show_component_version(mca_types, component_map, opal_info_type_all,
 502                                          opal_info_component_all, opal_info_ver_full,
 503                                          opal_info_ver_all);
 504         for (i = 0; i < mca_types->size; ++i) {
 505             if (NULL == (type = (char *)opal_pointer_array_get_item(mca_types, i))) {
 506                 continue;
 507             }
 508             opal_info_show_mca_params(type, opal_info_component_all, max_level, want_internal);
 509         }
 510     } else {
 511         for (i = 0; i < count; ++i) {
 512             type = opal_cmd_line_get_param(opal_info_cmd_line, p, (int)i, 0);
 513             component = opal_cmd_line_get_param(opal_info_cmd_line, p, (int)i, 1);
 514 
 515             for (found = false, i = 0; i < mca_types->size; ++i) {
 516                 if (NULL == (str = (char *)opal_pointer_array_get_item(mca_types, i))) {
 517                     continue;
 518                 }
 519                 if (0 == strcmp(str, type)) {
 520                     found = true;
 521                     break;
 522                 }
 523             }
 524 
 525             if (!found) {
 526                 char *usage = opal_cmd_line_get_usage_msg(opal_info_cmd_line);
 527                 opal_show_help("help-opal_info.txt", "not-found", true, type);
 528                 free(usage);
 529                 exit(1);
 530             }
 531 
 532             opal_info_show_component_version(mca_types, component_map, type,
 533                                              component, opal_info_ver_full,
 534                                              opal_info_ver_all);
 535             opal_info_show_mca_params(type, component, max_level, want_internal);
 536         }
 537     }
 538 }
 539 
 540 void opal_info_err_params(opal_pointer_array_t *component_map)
 541 {
 542     opal_info_component_map_t *map=NULL, *mptr;
 543     int i;
 544 
 545     /* all we want to do is display the LAST entry in the
 546      * component_map array as this is the one that generated the error
 547      */
 548     for (i=0; i < component_map->size; i++) {
 549         if (NULL == (mptr = (opal_info_component_map_t*)opal_pointer_array_get_item(component_map, i))) {
 550             continue;
 551         }
 552         map = mptr;
 553     }
 554     if (NULL == map) {
 555         fprintf(stderr, "opal_info_err_params: map not found\n");
 556         return;
 557     }
 558     opal_info_show_mca_params(map->type, opal_info_component_all, OPAL_INFO_LVL_9, true);
 559     fprintf(stderr, "\n");
 560     return;
 561 }
 562 
 563 void opal_info_do_type(opal_cmd_line_t *opal_info_cmd_line)
 564 {
 565     mca_base_var_info_lvl_t max_level = OPAL_INFO_LVL_1;
 566     int count;
 567     char *type, *str;
 568     int i, j, k, len, ret;
 569     char *p;
 570     const mca_base_var_t *var;
 571     char** strings, *message;
 572     const mca_base_var_group_t *group;
 573     p = "type";
 574 
 575     if (NULL != (str = opal_cmd_line_get_param (opal_info_cmd_line, "level", 0, 0))) {
 576         char *tmp;
 577 
 578         errno = 0;
 579         max_level = strtol (str, &tmp, 10) + OPAL_INFO_LVL_1 - 1;
 580         if (0 != errno || '\0' != tmp[0] || max_level < OPAL_INFO_LVL_1 || max_level > OPAL_INFO_LVL_9) {
 581             char *usage = opal_cmd_line_get_usage_msg(opal_info_cmd_line);
 582             opal_show_help("help-opal_info.txt", "invalid-level", true, str);
 583             free(usage);
 584             exit(1);
 585         }
 586     }
 587 
 588     count = opal_cmd_line_get_ninsts(opal_info_cmd_line, p);
 589     len = mca_base_var_get_count ();
 590 
 591     for (k = 0; k < count; ++k) {
 592         type = opal_cmd_line_get_param(opal_info_cmd_line, p, k, 0);
 593         for (i = 0; i < len; ++i) {
 594             ret = mca_base_var_get (i, &var);
 595             if (OPAL_SUCCESS != ret) {
 596                 continue;
 597             }
 598             if (0 == strcmp(type, ompi_var_type_names[var->mbv_type]) && (var->mbv_info_lvl <= max_level)) {
 599                 ret = mca_base_var_dump(var->mbv_index, &strings, !opal_info_pretty ? MCA_BASE_VAR_DUMP_PARSABLE : MCA_BASE_VAR_DUMP_READABLE);
 600                 if (OPAL_SUCCESS != ret) {
 601                     continue;
 602                 }
 603                 (void) mca_base_var_group_get(var->mbv_group_index, &group);
 604                 for (j = 0 ; strings[j] ; ++j) {
 605                     if (0 == j && opal_info_pretty) {
 606                         opal_asprintf (&message, "MCA %s", group->group_framework);
 607                         opal_info_out(message, message, strings[j]);
 608                         free(message);
 609                     } else {
 610                         opal_info_out("", "", strings[j]);
 611                     }
 612                     free(strings[j]);
 613                 }
 614                 free(strings);
 615             }
 616         }
 617     }
 618 }
 619 
 620 static void opal_info_show_mca_group_params(const mca_base_var_group_t *group, mca_base_var_info_lvl_t max_level, bool want_internal)
 621 {
 622     const int *variables, *groups;
 623     const mca_base_pvar_t *pvar;
 624     const char *group_component;
 625     const mca_base_var_t *var;
 626     char **strings, *message;
 627     bool requested = true;
 628     int ret, i, j, count;
 629 
 630     variables = OPAL_VALUE_ARRAY_GET_BASE(&group->group_vars, const int);
 631     count = opal_value_array_get_size((opal_value_array_t *)&group->group_vars);
 632 
 633     /* the default component name is "base". depending on how the
 634      * group was registered the group may or not have this set.  */
 635     group_component = group->group_component ? group->group_component : "base";
 636 
 637     /* check if this group may be disabled due to a selection variable */
 638     if (0 != strcmp (group_component, "base")) {
 639         int var_id;
 640 
 641         /* read the selection parameter */
 642         var_id = mca_base_var_find (group->group_project, group->group_framework, NULL, NULL);
 643         if (0 <= var_id) {
 644             const mca_base_var_storage_t *value=NULL;
 645             char **requested_components;
 646             bool include_mode;
 647 
 648             mca_base_var_get_value (var_id, &value, NULL, NULL);
 649             if (NULL != value && NULL != value->stringval && '\0' != value->stringval[0]) {
 650                 mca_base_component_parse_requested (value->stringval, &include_mode, &requested_components);
 651 
 652                 for (i = 0, requested = !include_mode ; requested_components[i] ; ++i) {
 653                     if (0 == strcmp (requested_components[i], group_component)) {
 654                         requested = include_mode;
 655                         break;
 656                     }
 657                 }
 658 
 659                 opal_argv_free (requested_components);
 660             }
 661         }
 662     }
 663 
 664     const mca_base_var_group_t *curr_group = NULL;
 665     char *component_msg = NULL;
 666     opal_asprintf(&component_msg, " %s", group_component);
 667 
 668     for (i = 0 ; i < count ; ++i) {
 669         ret = mca_base_var_get(variables[i], &var);
 670         if (OPAL_SUCCESS != ret || ((var->mbv_flags & MCA_BASE_VAR_FLAG_INTERNAL) &&
 671                                     !want_internal) ||
 672             max_level < var->mbv_info_lvl) {
 673             continue;
 674         }
 675 
 676         if (opal_info_pretty && curr_group != group) {
 677             opal_asprintf(&message, "MCA%s %s%s", requested ? "" : " (-)",
 678                      group->group_framework,
 679                      component_msg ? component_msg : "");
 680             opal_info_out(message, message, "---------------------------------------------------");
 681             free(message);
 682             curr_group = group;
 683         }
 684 
 685         ret = mca_base_var_dump(variables[i], &strings, !opal_info_pretty ? MCA_BASE_VAR_DUMP_PARSABLE : MCA_BASE_VAR_DUMP_READABLE);
 686         if (OPAL_SUCCESS != ret) {
 687             continue;
 688         }
 689 
 690         for (j = 0 ; strings[j] ; ++j) {
 691             if (0 == j && opal_info_pretty) {
 692                 opal_asprintf (&message, "MCA%s %s%s", requested ? "" : " (-)",
 693                           group->group_framework,
 694                           component_msg ? component_msg : "");
 695                 opal_info_out(message, message, strings[j]);
 696                 free(message);
 697             } else {
 698                 opal_info_out("", "", strings[j]);
 699             }
 700             free(strings[j]);
 701         }
 702         if (!opal_info_pretty) {
 703             /* generate an entry indicating whether this variable is disabled or not. if the
 704              * format in mca_base_var/pvar.c changes this needs to be changed as well */
 705             opal_asprintf (&message, "mca:%s:%s:param:%s:disabled:%s", group->group_framework,
 706                       group_component, var->mbv_full_name, requested ? "false" : "true");
 707             opal_info_out("", "", message);
 708             free (message);
 709         }
 710         free(strings);
 711     }
 712 
 713     variables = OPAL_VALUE_ARRAY_GET_BASE(&group->group_pvars, const int);
 714     count = opal_value_array_get_size((opal_value_array_t *)&group->group_pvars);
 715 
 716     for (i = 0 ; i < count ; ++i) {
 717         ret = mca_base_pvar_get(variables[i], &pvar);
 718         if (OPAL_SUCCESS != ret || max_level < pvar->verbosity) {
 719             continue;
 720         }
 721 
 722         if (opal_info_pretty && curr_group != group) {
 723             opal_asprintf(&message, "MCA%s %s%s", requested ? "" : " (-)",
 724                      group->group_framework,
 725                      component_msg ? component_msg : "");
 726             opal_info_out(message, message, "---------------------------------------------------");
 727             free(message);
 728             curr_group = group;
 729         }
 730 
 731         ret = mca_base_pvar_dump (variables[i], &strings, !opal_info_pretty ? MCA_BASE_VAR_DUMP_PARSABLE : MCA_BASE_VAR_DUMP_READABLE);
 732         if (OPAL_SUCCESS != ret) {
 733             continue;
 734         }
 735 
 736         for (j = 0 ; strings[j] ; ++j) {
 737             if (0 == j && opal_info_pretty) {
 738                 opal_asprintf (&message, "MCA%s %s%s", requested ? "" : " (-)",
 739                           group->group_framework,
 740                           component_msg ? component_msg : "");
 741                 opal_info_out(message, message, strings[j]);
 742                 free(message);
 743             } else {
 744                 opal_info_out("", "", strings[j]);
 745             }
 746             free(strings[j]);
 747         }
 748         if (!opal_info_pretty) {
 749             /* generate an entry indicating whether this variable is disabled or not. if the
 750              * format in mca_base_var/pvar.c changes this needs to be changed as well */
 751             opal_asprintf (&message, "mca:%s:%s:pvar:%s:disabled:%s", group->group_framework,
 752                       group_component, pvar->name, requested ? "false" : "true");
 753             opal_info_out("", "", message);
 754             free (message);
 755         }
 756         free(strings);
 757     }
 758 
 759     groups = OPAL_VALUE_ARRAY_GET_BASE(&group->group_subgroups, const int);
 760     count = opal_value_array_get_size((opal_value_array_t *)&group->group_subgroups);
 761 
 762     for (i = 0 ; i < count ; ++i) {
 763         ret = mca_base_var_group_get(groups[i], &group);
 764         if (OPAL_SUCCESS != ret) {
 765             continue;
 766         }
 767         opal_info_show_mca_group_params(group, max_level, want_internal);
 768     }
 769     free(component_msg);
 770 }
 771 
 772 void opal_info_show_mca_params(const char *type, const char *component,
 773                                mca_base_var_info_lvl_t max_level, bool want_internal)
 774 {
 775     const mca_base_var_group_t *group;
 776     int ret;
 777 
 778     if (0 == strcmp (component, "all")) {
 779         ret = mca_base_var_group_find("*", type, NULL);
 780         if (0 > ret) {
 781             return;
 782         }
 783 
 784         (void) mca_base_var_group_get(ret, &group);
 785 
 786         opal_info_show_mca_group_params(group, max_level, want_internal);
 787     } else {
 788         ret = mca_base_var_group_find("*", type, component);
 789         if (0 > ret) {
 790             return;
 791         }
 792 
 793         (void) mca_base_var_group_get(ret, &group);
 794         opal_info_show_mca_group_params(group, max_level, want_internal);
 795     }
 796 }
 797 
 798 
 799 
 800 void opal_info_do_arch()
 801 {
 802     opal_info_out("Configured architecture", "config:arch", OPAL_ARCH);
 803 }
 804 
 805 
 806 void opal_info_do_hostname()
 807 {
 808     opal_info_out("Configure host", "config:host", OPAL_CONFIGURE_HOST);
 809 }
 810 
 811 
 812 static char *escape_quotes(const char *value)
 813 {
 814     const char *src;
 815     int num_quotes = 0;
 816     for (src = value; src != NULL && *src != '\0'; ++src) {
 817         if ('"' == *src) {
 818             ++num_quotes;
 819         }
 820     }
 821 
 822     // If there are no quotes in the string, there's nothing to do
 823     if (0 == num_quotes) {
 824         return NULL;
 825     }
 826 
 827     // If we have quotes, make a new string.  Copy over the old
 828     // string, escaping the quotes along the way.  This is simple and
 829     // clear to read; it's not particularly efficient (performance is
 830     // definitely not important here).
 831     char *quoted_value;
 832     quoted_value = calloc(1, strlen(value) + num_quotes + 1);
 833     if (NULL == quoted_value) {
 834         return NULL;
 835     }
 836 
 837     char *dest;
 838     for (src = value, dest = quoted_value; *src != '\0'; ++src, ++dest) {
 839         if ('"' == *src) {
 840             *dest++ = '\\';
 841         }
 842         *dest = *src;
 843     }
 844 
 845     return quoted_value;
 846 }
 847 
 848 
 849 /*
 850  * Private variables - set some reasonable screen size defaults
 851  */
 852 
 853 static int centerpoint = 24;
 854 static int screen_width = 78;
 855 
 856 /*
 857  * Prints the passed message in a pretty or parsable format.
 858  */
 859 void opal_info_out(const char *pretty_message, const char *plain_message, const char *value)
 860 {
 861     size_t len, max_value_width, value_offset;
 862     char *spaces = NULL;
 863     char *filler = NULL;
 864     char *pos, *v, savev, *v_to_free;
 865 
 866 #ifdef HAVE_ISATTY
 867     /* If we have isatty(), if this is not a tty, then disable
 868      * wrapping for grep-friendly behavior
 869      */
 870     if (0 == isatty(STDOUT_FILENO)) {
 871         screen_width = INT_MAX;
 872     }
 873 #endif
 874 
 875 #ifdef TIOCGWINSZ
 876     if (screen_width < INT_MAX) {
 877         struct winsize size;
 878         if (ioctl(STDOUT_FILENO, TIOCGWINSZ, (char*) &size) >= 0) {
 879             screen_width = size.ws_col;
 880         }
 881     }
 882 #endif
 883 
 884     /* Sanity check (allow NULL to mean "") */
 885     if (NULL == value) {
 886         value = "";
 887     }
 888 
 889     /* Strip leading and trailing whitespace from the string value */
 890     value_offset = strspn(value, " ");
 891 
 892     v = v_to_free = strdup(value + value_offset);
 893     len = strlen(v);
 894 
 895     if (len > 0) {
 896         while (len > 0 && isspace(v[len-1])) len--;
 897         v[len] = '\0';
 898     }
 899 
 900     if (opal_info_pretty && NULL != pretty_message) {
 901         if (centerpoint > (int)strlen(pretty_message)) {
 902             opal_asprintf(&spaces, "%*s", centerpoint -
 903                      (int)strlen(pretty_message), " ");
 904         } else {
 905             spaces = strdup("");
 906 #if OPAL_ENABLE_DEBUG
 907             if (centerpoint < (int)strlen(pretty_message)) {
 908                 opal_show_help("help-opal_info.txt",
 909                                "developer warning: field too long", false,
 910                                pretty_message, centerpoint);
 911             }
 912 #endif
 913         }
 914         max_value_width = screen_width - strlen(spaces) - strlen(pretty_message) - 2;
 915         if (0 < strlen(pretty_message)) {
 916             opal_asprintf(&filler, "%s%s: ", spaces, pretty_message);
 917         } else {
 918             opal_asprintf(&filler, "%s  ", spaces);
 919         }
 920         free(spaces);
 921         spaces = NULL;
 922 
 923         while (true) {
 924             if (strlen(v) < max_value_width) {
 925                 printf("%s%s\n", filler, v);
 926                 break;
 927             } else {
 928                 opal_asprintf(&spaces, "%*s", centerpoint + 2, " ");
 929 
 930                 /* Work backwards to find the first space before
 931                  * max_value_width
 932                  */
 933                 savev = v[max_value_width];
 934                 v[max_value_width] = '\0';
 935                 pos = (char*)strrchr(v, (int)' ');
 936                 v[max_value_width] = savev;
 937                 if (NULL == pos) {
 938                     /* No space found < max_value_width.  Look for the first
 939                      * space after max_value_width.
 940                      */
 941                     pos = strchr(&v[max_value_width], ' ');
 942 
 943                     if (NULL == pos) {
 944 
 945                         /* There's just no spaces.  So just print it and be done. */
 946 
 947                         printf("%s%s\n", filler, v);
 948                         break;
 949                     } else {
 950                         *pos = '\0';
 951                         printf("%s%s\n", filler, v);
 952                         v = pos + 1;
 953                     }
 954                 } else {
 955                     *pos = '\0';
 956                     printf("%s%s\n", filler, v);
 957                     v = pos + 1;
 958                 }
 959 
 960                 /* Reset for the next iteration */
 961                 free(filler);
 962                 filler = strdup(spaces);
 963                 free(spaces);
 964                 spaces = NULL;
 965             }
 966         }
 967         if (NULL != filler) {
 968             free(filler);
 969         }
 970         if (NULL != spaces) {
 971             free(spaces);
 972         }
 973     } else {
 974         if (NULL != plain_message && 0 < strlen(plain_message)) {
 975             // Escape any double quotes in the value.
 976             char *quoted_value;
 977             quoted_value = escape_quotes(value);
 978             if (NULL != quoted_value) {
 979                 value = quoted_value;
 980             }
 981 
 982             char *colon = strchr(value, ':');
 983             if (NULL != colon) {
 984                 printf("%s:\"%s\"\n", plain_message, value);
 985             } else {
 986                 printf("%s:%s\n", plain_message, value);
 987             }
 988 
 989             if (NULL != quoted_value) {
 990                 free(quoted_value);
 991             }
 992         } else {
 993             printf("%s\n", value);
 994         }
 995     }
 996     if (NULL != v_to_free) {
 997         free(v_to_free);
 998     }
 999 }
1000 
1001 /*
1002  * Prints the passed integer in a pretty or parsable format.
1003  */
1004 void opal_info_out_int(const char *pretty_message,
1005                        const char *plain_message,
1006                        int value)
1007 {
1008     char *valstr;
1009 
1010     opal_asprintf(&valstr, "%d", (int)value);
1011     opal_info_out(pretty_message, plain_message, valstr);
1012     free(valstr);
1013 }
1014 
1015 /*
1016  * Show all the components of a specific type/component combo (component may be
1017  * a wildcard)
1018  */
1019 void opal_info_show_component_version(opal_pointer_array_t *mca_types,
1020                                       opal_pointer_array_t *component_map,
1021                                       const char *type_name,
1022                                       const char *component_name,
1023                                       const char *scope, const char *ver_type)
1024 {
1025     bool want_all_components = false;
1026     bool want_all_types = false;
1027     bool found;
1028     mca_base_component_list_item_t *cli;
1029     mca_base_failed_component_t *cli_failed;
1030     int j;
1031     char *pos;
1032     opal_info_component_map_t *map;
1033 
1034     /* see if all components wanted */
1035     if (0 == strcmp(opal_info_component_all, component_name)) {
1036         want_all_components = true;
1037     }
1038 
1039     /* see if all types wanted */
1040     if (0 != strcmp(opal_info_type_all, type_name)) {
1041         /* Check to see if the type is valid */
1042 
1043         for (found = false, j = 0; j < mca_types->size; ++j) {
1044             if (NULL == (pos = (char*)opal_pointer_array_get_item(mca_types, j))) {
1045                 continue;
1046             }
1047             if (0 == strcmp(pos, type_name)) {
1048                 found = true;
1049                 break;
1050             }
1051         }
1052 
1053         if (!found) {
1054             return;
1055         }
1056     } else {
1057         want_all_types = true;
1058     }
1059 
1060     /* Now that we have a valid type, find the right components */
1061     for (j=0; j < component_map->size; j++) {
1062         if (NULL == (map = (opal_info_component_map_t*)opal_pointer_array_get_item(component_map, j))) {
1063             continue;
1064         }
1065         if ((want_all_types || 0 == strcmp(type_name, map->type)) && map->components) {
1066             /* found it! */
1067             OPAL_LIST_FOREACH(cli, map->components, mca_base_component_list_item_t) {
1068                 const mca_base_component_t *component = cli->cli_component;
1069                 if (want_all_components ||
1070                     0 == strcmp(component->mca_component_name, component_name)) {
1071                     opal_info_show_mca_version(component, scope, ver_type);
1072                 }
1073             }
1074 
1075             /* found it! */
1076             OPAL_LIST_FOREACH(cli_failed, map->failed_components, mca_base_failed_component_t) {
1077                 mca_base_component_repository_item_t *ri = cli_failed->comp;
1078                 if (want_all_components ||
1079                     0 == strcmp(component_name, ri->ri_name) ) {
1080                     opal_info_show_failed_component(ri, cli_failed->error_msg);
1081                 }
1082             }
1083 
1084             if (!want_all_types) {
1085                 break;
1086             }
1087         }
1088     }
1089 }
1090 
1091 
1092 static void opal_info_show_failed_component(const mca_base_component_repository_item_t* ri,
1093                                             const char *error_msg)
1094 {
1095     char *message, *content;
1096 
1097     if (opal_info_pretty) {
1098         opal_asprintf(&message, "MCA %s", ri->ri_type);
1099         opal_asprintf(&content, "%s (failed to load) %s", ri->ri_name, error_msg);
1100 
1101         opal_info_out(message, NULL, content);
1102 
1103         free(message);
1104         free(content);
1105     } else {
1106         opal_asprintf(&message, "mca:%s:%s:failed", ri->ri_type, ri->ri_name);
1107         opal_asprintf(&content, "%s", error_msg);
1108 
1109         opal_info_out(NULL, message, content);
1110 
1111         free(message);
1112         free(content);
1113     }
1114 }
1115 
1116 /*
1117  * Given a component, display its relevant version(s)
1118  */
1119 void opal_info_show_mca_version(const mca_base_component_t* component,
1120                                 const char *scope, const char *ver_type)
1121 {
1122     bool printed;
1123     bool want_mca = false;
1124     bool want_type = false;
1125     bool want_component = false;
1126     char *message, *content;
1127     char *mca_version;
1128     char *api_version;
1129     char *component_version;
1130     char *tmp;
1131 
1132     if (0 == strcmp(ver_type, opal_info_ver_all) ||
1133         0 == strcmp(ver_type, opal_info_ver_mca)) {
1134         want_mca = true;
1135     }
1136 
1137     if (0 == strcmp(ver_type, opal_info_ver_all) ||
1138         0 == strcmp(ver_type, opal_info_ver_type)) {
1139         want_type = true;
1140     }
1141 
1142     if (0 == strcmp(ver_type, opal_info_ver_all) ||
1143         0 == strcmp(ver_type, opal_info_ver_component)) {
1144         want_component = true;
1145     }
1146 
1147     mca_version = opal_info_make_version_str(scope, component->mca_major_version,
1148                                              component->mca_minor_version,
1149                                              component->mca_release_version, "",
1150                                              "");
1151     api_version = opal_info_make_version_str(scope, component->mca_type_major_version,
1152                                              component->mca_type_minor_version,
1153                                              component->mca_type_release_version, "",
1154                                              "");
1155     component_version = opal_info_make_version_str(scope, component->mca_component_major_version,
1156                                                    component->mca_component_minor_version,
1157                                                    component->mca_component_release_version,
1158                                                    "", "");
1159     if (opal_info_pretty) {
1160         opal_asprintf(&message, "MCA %s", component->mca_type_name);
1161         printed = false;
1162         opal_asprintf(&content, "%s (", component->mca_component_name);
1163 
1164         if (want_mca) {
1165             opal_asprintf(&tmp, "%sMCA v%s", content, mca_version);
1166             free(content);
1167             content = tmp;
1168             printed = true;
1169         }
1170 
1171         if (want_type) {
1172             if (printed) {
1173                 opal_asprintf(&tmp, "%s, ", content);
1174                 free(content);
1175                 content = tmp;
1176             }
1177             opal_asprintf(&tmp, "%sAPI v%s", content, api_version);
1178             free(content);
1179             content = tmp;
1180             printed = true;
1181         }
1182 
1183         if (want_component) {
1184             if (printed) {
1185                 opal_asprintf(&tmp, "%s, ", content);
1186                 free(content);
1187                 content = tmp;
1188             }
1189             opal_asprintf(&tmp, "%sComponent v%s", content, component_version);
1190             free(content);
1191             content = tmp;
1192             printed = true;
1193         }
1194         if (NULL != content) {
1195             opal_asprintf(&tmp, "%s)", content);
1196             free(content);
1197         } else {
1198             tmp = NULL;
1199         }
1200 
1201         opal_info_out(message, NULL, tmp);
1202         free(message);
1203         if (NULL != tmp) {
1204             free(tmp);
1205         }
1206 
1207     } else {
1208         opal_asprintf(&message, "mca:%s:%s:version", component->mca_type_name, component->mca_component_name);
1209         if (want_mca) {
1210             opal_asprintf(&tmp, "mca:%s", mca_version);
1211             opal_info_out(NULL, message, tmp);
1212             free(tmp);
1213         }
1214         if (want_type) {
1215             opal_asprintf(&tmp, "api:%s", api_version);
1216             opal_info_out(NULL, message, tmp);
1217             free(tmp);
1218         }
1219         if (want_component) {
1220             opal_asprintf(&tmp, "component:%s", component_version);
1221             opal_info_out(NULL, message, tmp);
1222             free(tmp);
1223         }
1224         free(message);
1225     }
1226 
1227     if (NULL != mca_version) {
1228         free(mca_version);
1229     }
1230     if (NULL != api_version) {
1231         free(api_version);
1232     }
1233     if (NULL != component_version) {
1234         free(component_version);
1235     }
1236 }
1237 
1238 
1239 char *opal_info_make_version_str(const char *scope,
1240                                  int major, int minor, int release,
1241                                  const char *greek,
1242                                  const char *repo)
1243 {
1244     char *str = NULL, *tmp;
1245     char temp[BUFSIZ];
1246 
1247     temp[BUFSIZ - 1] = '\0';
1248     if (0 == strcmp(scope, opal_info_ver_full) ||
1249         0 == strcmp(scope, opal_info_ver_all)) {
1250         snprintf(temp, BUFSIZ - 1, "%d.%d.%d", major, minor, release);
1251         str = strdup(temp);
1252         if (NULL != greek) {
1253             opal_asprintf(&tmp, "%s%s", str, greek);
1254             free(str);
1255             str = tmp;
1256         }
1257     } else if (0 == strcmp(scope, opal_info_ver_major)) {
1258         snprintf(temp, BUFSIZ - 1, "%d", major);
1259     } else if (0 == strcmp(scope, opal_info_ver_minor)) {
1260         snprintf(temp, BUFSIZ - 1, "%d", minor);
1261     } else if (0 == strcmp(scope, opal_info_ver_release)) {
1262         snprintf(temp, BUFSIZ - 1, "%d", release);
1263     } else if (0 == strcmp(scope, opal_info_ver_greek)) {
1264         str = strdup(greek);
1265     } else if (0 == strcmp(scope, opal_info_ver_repo)) {
1266         str = strdup(repo);
1267     }
1268 
1269     if (NULL == str) {
1270         str = strdup(temp);
1271     }
1272 
1273     return str;
1274 }
1275 
1276 void opal_info_show_opal_version(const char *scope)
1277 {
1278     char *tmp, *tmp2;
1279 
1280     opal_asprintf(&tmp, "%s:version:full", opal_info_type_opal);
1281     tmp2 = opal_info_make_version_str(scope,
1282                                       OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION,
1283                                       OPAL_RELEASE_VERSION,
1284                                       OPAL_GREEK_VERSION,
1285                                       OPAL_REPO_REV);
1286     opal_info_out("OPAL", tmp, tmp2);
1287     free(tmp);
1288     free(tmp2);
1289     opal_asprintf(&tmp, "%s:version:repo", opal_info_type_opal);
1290     opal_info_out("OPAL repo revision", tmp, OPAL_REPO_REV);
1291     free(tmp);
1292     opal_asprintf(&tmp, "%s:version:release_date", opal_info_type_opal);
1293     opal_info_out("OPAL release date", tmp, OPAL_RELEASE_DATE);
1294     free(tmp);
1295 }

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