root/opal/mca/pmix/pmix4x/pmix/src/mca/pinstalldirs/base/pinstalldirs_base_expand.c

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

DEFINITIONS

This source file includes following definitions.
  1. pmix_pinstall_dirs_expand_internal
  2. pmix_pinstall_dirs_expand
  3. pmix_pinstall_dirs_expand_setup

   1 /*
   2  * Copyright (c) 2006-2007 Los Alamos National Security, LLC.  All rights
   3  *                         reserved.
   4  * Copyright (c) 2007-2010 Cisco Systems, Inc.  All rights reserved.
   5  * Copyright (c) 2007      Sun Microsystem, Inc.  All rights reserved.
   6  * Copyright (c) 2010      Sandia National Laboratories. All rights reserved.
   7  * Copyright (c) 2016-2017 Intel, Inc. All rights reserved.
   8  * $COPYRIGHT$
   9  *
  10  * Additional copyrights may follow
  11  *
  12  * $HEADER$
  13  *
  14  */
  15 
  16 #include <src/include/pmix_config.h>
  17 
  18 #include <string.h>
  19 
  20 #include "src/util/os_path.h"
  21 #include "src/mca/pinstalldirs/base/base.h"
  22 #include "src/mca/pinstalldirs/pinstalldirs.h"
  23 
  24 /* Support both ${name} and @{name} forms.  The latter allows us to
  25    pass values through AC_SUBST without being munged by m4 (e.g., if
  26    we want to pass "@{libdir}" and not have it replaced by m4 to be
  27    whatever the actual value of the shell variable is. */
  28 #define EXPAND_STRING(name) EXPAND_STRING2(name, name)
  29 
  30 #define EXPAND_STRING2(ompiname, fieldname)                                         \
  31     do {                                                                            \
  32         if (NULL != (start_pos = strstr(retval, "${" #fieldname "}"))) {            \
  33             tmp = retval;                                                           \
  34             *start_pos = '\0';                                                      \
  35             end_pos = start_pos + strlen("${" #fieldname "}");                      \
  36             if (0 > asprintf(&retval, "%s%s%s", tmp,                                \
  37                      pmix_pinstall_dirs.ompiname + destdir_offset,                  \
  38                      end_pos)) {                                                    \
  39                 pmix_output(0, "NOMEM");                                            \
  40             }                                                                       \
  41             free(tmp);                                                              \
  42             changed = true;                                                         \
  43         } else if (NULL != (start_pos = strstr(retval, "@{" #fieldname "}"))) {     \
  44             tmp = retval;                                                           \
  45             *start_pos = '\0';                                                      \
  46             end_pos = start_pos + strlen("@{" #fieldname "}");                      \
  47             if (0 > asprintf(&retval, "%s%s%s", tmp,                                \
  48                      pmix_pinstall_dirs.ompiname + destdir_offset,                  \
  49                      end_pos)) {                                                    \
  50                 pmix_output(0, "NOMEM");                                            \
  51             }                                                                       \
  52             free(tmp);                                                              \
  53             changed = true;                                                         \
  54         }                                                                           \
  55     } while (0)
  56 
  57 
  58 /*
  59  * Read the lengthy comment below to understand the value of the
  60  * is_setup parameter.
  61  */
  62 static char *
  63 pmix_pinstall_dirs_expand_internal(const char* input, bool is_setup)
  64 {
  65     size_t len, i;
  66     bool needs_expand = false;
  67     char *retval = NULL;
  68     char *destdir = NULL;
  69     size_t destdir_offset = 0;
  70 
  71     /* This is subtle, and worth explaining.
  72 
  73        If we substitute in any ${FIELD} values, we need to prepend it
  74        with the value of the $PMIX_DESTDIR environment variable -- if
  75        it is set.
  76 
  77        We need to handle at least three cases properly (assume that
  78        configure was invoked with --prefix=/opt/pmix and no other
  79        directory specifications, and PMIX_DESTDIR is set to
  80        /tmp/buildroot):
  81 
  82        1. Individual directories, such as libdir.  These need to be
  83           prepended with DESTDIR.  I.e., return
  84           /tmp/buildroot/opt/pmix/lib.
  85 
  86        2. Compiler flags that have ${FIELD} values embedded in them.
  87           For example, consider if a wrapper compiler data file
  88           contains the line:
  89 
  90           preprocessor_flags=-DMYFLAG="${prefix}/share/randomthingy/"
  91 
  92           The value we should return is:
  93 
  94           -DMYFLAG="/tmp/buildroot/opt/pmix/share/randomthingy/"
  95 
  96        3. Compiler flags that do not have any ${FIELD} values.
  97           For example, consider if a wrapper compiler data file
  98           contains the line:
  99 
 100           preprocessor_flags=-pthread
 101 
 102           The value we should return is:
 103 
 104           -pthread
 105 
 106        Note, too, that this PMIX_DESTDIR futzing only needs to occur
 107        during pmix_init().  By the time pmix_init() has completed, all
 108        values should be substituted in that need substituting.  Hence,
 109        we take an extra parameter (is_setup) to know whether we should
 110        do this futzing or not. */
 111     if (is_setup) {
 112         destdir = getenv("PMIX_DESTDIR");
 113         if (NULL != destdir && strlen(destdir) > 0) {
 114             destdir_offset = strlen(destdir);
 115         }
 116     }
 117 
 118     len = strlen(input);
 119     for (i = 0 ; i < len ; ++i) {
 120         if ('$' == input[i] || '@' == input[i]) {
 121             needs_expand = true;
 122             break;
 123         }
 124     }
 125 
 126     retval = strdup(input);
 127     if (NULL == retval) return NULL;
 128 
 129     if (needs_expand) {
 130         bool changed = false;
 131         char *start_pos, *end_pos, *tmp;
 132 
 133         do {
 134             changed = false;
 135             EXPAND_STRING(prefix);
 136             EXPAND_STRING(exec_prefix);
 137             EXPAND_STRING(bindir);
 138             EXPAND_STRING(sbindir);
 139             EXPAND_STRING(libexecdir);
 140             EXPAND_STRING(datarootdir);
 141             EXPAND_STRING(datadir);
 142             EXPAND_STRING(sysconfdir);
 143             EXPAND_STRING(sharedstatedir);
 144             EXPAND_STRING(localstatedir);
 145             EXPAND_STRING(libdir);
 146             EXPAND_STRING(includedir);
 147             EXPAND_STRING(infodir);
 148             EXPAND_STRING(mandir);
 149             EXPAND_STRING2(pmixdatadir, pkgdatadir);
 150             EXPAND_STRING2(pmixlibdir, pkglibdir);
 151             EXPAND_STRING2(pmixincludedir, pkgincludedir);
 152         } while (changed);
 153     }
 154 
 155     if (NULL != destdir) {
 156         char *tmp = retval;
 157         retval = pmix_os_path(false, destdir, tmp, NULL);
 158         free(tmp);
 159     }
 160 
 161     return retval;
 162 }
 163 
 164 
 165 char *
 166 pmix_pinstall_dirs_expand(const char* input)
 167 {
 168     /* We do NOT want PMIX_DESTDIR expansion in this case. */
 169     return pmix_pinstall_dirs_expand_internal(input, false);
 170 }
 171 
 172 
 173 char *
 174 pmix_pinstall_dirs_expand_setup(const char* input)
 175 {
 176     /* We DO want PMIX_DESTDIR expansion in this case. */
 177     return pmix_pinstall_dirs_expand_internal(input, true);
 178 }

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