/*
 * Function to find as many components of a given type as possible.  This
 * includes statically-linked in components as well as opening up a
 * directory and looking for shared-library MCA components of the
 * appropriate type (load them if available).
 *
 * Return one consolidated array of (mca_base_component_t*) pointing to all
 * available components.
 */
int mca_base_component_find(const char *directory, const char *type, 
                         const mca_base_component_t *static_components[], 
                            opal_list_t *found_components,
                            bool open_dso_components)
{
  int i;
  mca_base_component_list_item_t *cli;

  /* Find all the components that were statically linked in */

  OBJ_CONSTRUCT(found_components, opal_list_t);
  for (i = 0; NULL != static_components[i]; ++i) {
    cli = OBJ_NEW(mca_base_component_list_item_t);
    if (NULL == cli) {
      return OPAL_ERR_OUT_OF_RESOURCE;
    }
    cli->cli_component = static_components[i];
    opal_list_append(found_components, (opal_list_item_t *) cli);
  }

#if OMPI_WANT_LIBLTDL
  /* Find any available dynamic components in the specified directory */
  if (open_dso_components) {
      int param, param_disable_dlopen;
      param = mca_base_param_find("mca", NULL, "component_disable_dlopen");
      mca_base_param_lookup_int(param, &param_disable_dlopen);

      if (0 == param_disable_dlopen) {
          find_dyn_components(directory, type, NULL, found_components);
      }
  } else {
    opal_output_verbose(40, 0, 
                        "mca: base: component_find: dso loading for %s MCA components disabled", 
                        type);
  }
#endif

  /* All done */

  return OPAL_SUCCESS;
}
/*
 * Function to find as many components of a given type as possible.  This
 * includes statically-linked in components as well as opening up a
 * directory and looking for shared-library MCA components of the
 * appropriate type (load them if available).
 *
 * Return one consolidated array of (mca_base_component_t*) pointing to all
 * available components.
 */
int mca_base_component_find(const char *directory, const char *type, 
                            const mca_base_component_t *static_components[], 
                            const char *requested_components,
                            opal_list_t *found_components,
                            bool open_dso_components)
{
    char **requested_component_names = NULL;
    mca_base_component_list_item_t *cli;
    bool include_mode;
    int i, ret;

    ret = mca_base_component_parse_requested (requested_components, &include_mode,
                           &requested_component_names);
    if (OPAL_SUCCESS != ret) {
        return ret;
    }

    /* Find all the components that were statically linked in */
    OBJ_CONSTRUCT(found_components, opal_list_t);
    for (i = 0; NULL != static_components &&
             NULL != static_components[i]; ++i) {
        if ( use_component(include_mode,
                           (const char**)requested_component_names,
                           static_components[i]->mca_component_name) ) {
            cli = OBJ_NEW(mca_base_component_list_item_t);
            if (NULL == cli) {
                ret = OPAL_ERR_OUT_OF_RESOURCE;
                goto component_find_out;
            }
            cli->cli_component = static_components[i];
            opal_list_append(found_components, (opal_list_item_t *) cli);
        }
    }

#if OPAL_WANT_LIBLTDL
    /* Find any available dynamic components in the specified directory */
    if (open_dso_components && !mca_base_component_disable_dlopen) {
        find_dyn_components(directory, type,
                            (const char**)requested_component_names,
                            include_mode, found_components); 
    } else {
        opal_output_verbose(40, 0, 
                            "mca: base: component_find: dso loading for %s MCA components disabled", 
                            type);
    }
#endif

    if (include_mode) {
        ret = component_find_check (type, requested_component_names, found_components);
    } else {
        ret = OPAL_SUCCESS;
    }


    ret = OPAL_SUCCESS;

component_find_out:

    if (NULL != requested_component_names) {
        opal_argv_free(requested_component_names);
    }

    /* All done */

    return ret;
}
/*
 * Function to find as many components of a given type as possible.  This
 * includes statically-linked in components as well as opening up a
 * directory and looking for shared-library MCA components of the
 * appropriate type (load them if available).
 *
 * Return one consolidated array of (pmix_mca_base_component_t*) pointing to all
 * available components.
 */
int pmix_mca_base_component_find (const char *directory, pmix_mca_base_framework_t *framework,
                                  bool ignore_requested, bool open_dso_components)
{
    const pmix_mca_base_component_t **static_components = framework->framework_static_components;
    char **requested_component_names = NULL;
    pmix_mca_base_component_list_item_t *cli;
    bool include_mode = true;
    int ret;

    pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, framework->framework_output,
                         "mca: base: component_find: searching %s for %s components",
                         directory, framework->framework_name);

    if (!ignore_requested) {
        ret = pmix_mca_base_component_parse_requested (framework->framework_selection, &include_mode,
                                                       &requested_component_names);
        if (PMIX_SUCCESS != ret) {
            return ret;
        }
    }

    /* Find all the components that were statically linked in */
    if (static_components) {
        for (int i = 0 ; NULL != static_components[i]; ++i) {
            if ( use_component(include_mode,
                               (const char**)requested_component_names,
                               static_components[i]->pmix_mca_component_name) ) {
                cli = PMIX_NEW(pmix_mca_base_component_list_item_t);
                if (NULL == cli) {
                    ret = PMIX_ERR_OUT_OF_RESOURCE;
                    goto component_find_out;
                }
                cli->cli_component = static_components[i];
                pmix_list_append(&framework->framework_components, (pmix_list_item_t *) cli);
            }
        }
    }

#if PMIX_HAVE_PDL_SUPPORT
    /* Find any available dynamic components in the specified directory */
    if (open_dso_components && !pmix_mca_base_component_disable_dlopen) {
        find_dyn_components(directory, framework, (const char**)requested_component_names,
                            include_mode);
    } else {
        pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_INFO, 0,
                            "pmix:mca: base: component_find: dso loading for %s MCA components disabled",
                            framework->framework_name);
    }
#endif

    if (include_mode) {
        ret = component_find_check (framework, requested_component_names);
    } else {
        ret = PMIX_SUCCESS;
    }

component_find_out:

    if (NULL != requested_component_names) {
        pmix_argv_free(requested_component_names);
    }

    /* All done */

    return ret;
}
/*
 * Function to find as many components of a given type as possible.  This
 * includes statically-linked in components as well as opening up a
 * directory and looking for shared-library MCA components of the
 * appropriate type (load them if available).
 *
 * Return one consolidated array of (mca_base_component_t*) pointing to all
 * available components.
 */
int mca_base_component_find(const char *directory, const char *type, 
                            const mca_base_component_t *static_components[], 
                            char **requested_component_names,
                            bool include_mode,
                            opal_list_t *found_components,
                            bool open_dso_components)
{
    int i;
    opal_list_item_t *item;
    mca_base_component_list_item_t *cli;

    /* Find all the components that were statically linked in */
    OBJ_CONSTRUCT(found_components, opal_list_t);
    for (i = 0; NULL != static_components[i]; ++i) {
        if ( use_component(include_mode,
                           (const char**)requested_component_names,
                           static_components[i]->mca_component_name) ) {
            cli = OBJ_NEW(mca_base_component_list_item_t);
            if (NULL == cli) {
                return OPAL_ERR_OUT_OF_RESOURCE;
            }
            cli->cli_component = static_components[i];
            opal_list_append(found_components, (opal_list_item_t *) cli);
        }
    }

#if OMPI_WANT_LIBLTDL
    /* Find any available dynamic components in the specified directory */
    if (open_dso_components) {
        int param, param_disable_dlopen;
        param = mca_base_param_find("mca", NULL, "component_disable_dlopen");
        mca_base_param_lookup_int(param, &param_disable_dlopen);

        if (0 == param_disable_dlopen) {
            find_dyn_components(directory, type,
                                (const char**)requested_component_names,
                                include_mode, found_components); 
        }
    } else {
        opal_output_verbose(40, 0, 
                            "mca: base: component_find: dso loading for %s MCA components disabled", 
                            type);
    }
#endif

    /* Ensure that *all* requested components exist.  Print a warning
       and abort if they do not. */
    for (i = 0; include_mode && NULL != requested_component_names && 
             NULL != requested_component_names[i]; ++i) {
        for (item = opal_list_get_first(found_components);
             opal_list_get_end(found_components) != item; 
             item = opal_list_get_next(item)) {
            cli = (mca_base_component_list_item_t*) item;
            if (0 == strcmp(requested_component_names[i], 
                            cli->cli_component->mca_component_name)) {
                break;
            }
        }

        if (opal_list_get_end(found_components) == item) {
            char h[MAXHOSTNAMELEN];
            gethostname(h, sizeof(h));
            opal_show_help("help-mca-base.txt", 
                           "find-available:not-valid", true,
                           h, type, requested_component_names[i]);
            return OPAL_ERR_NOT_FOUND;
        }
    }

    /* All done */

    return OPAL_SUCCESS;
}