File: installdirs_base_expand.c

package info (click to toggle)
openmpi 5.0.8-4
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 201,684 kB
  • sloc: ansic: 613,078; makefile: 42,353; sh: 11,194; javascript: 9,244; f90: 7,052; java: 6,404; perl: 5,179; python: 1,859; lex: 740; fortran: 61; cpp: 20; tcl: 12
file content (169 lines) | stat: -rw-r--r-- 6,505 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
 * Copyright (c) 2006-2007 Los Alamos National Security, LLC.  All rights
 *                         reserved.
 * Copyright (c) 2007-2010 Cisco Systems, Inc.  All rights reserved.
 * Copyright (c) 2007      Sun Microsystem, Inc.  All rights reserved.
 * Copyright (c) 2010      Sandia National Laboratories. All rights reserved.
 * Copyright (c) 2018      Amazon.com, Inc. or its affiliates.  All Rights reserved.
 * $COPYRIGHT$
 *
 * Additional copyrights may follow
 *
 * $HEADER$
 *
 */

#include "opal_config.h"

#include <string.h>

#include "opal/mca/installdirs/base/base.h"
#include "opal/mca/installdirs/installdirs.h"
#include "opal/util/os_path.h"
#include "opal/util/printf.h"

/* Support both ${name} and @{name} forms.  The latter allows us to
   pass values through AC_SUBST without being munged by m4 (e.g., if
   we want to pass "@{libdir}" and not have it replaced by m4 to be
   whatever the actual value of the shell variable is. */
#define EXPAND_STRING(name) EXPAND_STRING2(name, name)

#define EXPAND_STRING2(ompiname, fieldname)                                                    \
    do {                                                                                       \
        if (NULL != (start_pos = strstr(retval, "${" #fieldname "}"))) {                       \
            tmp = retval;                                                                      \
            *start_pos = '\0';                                                                 \
            end_pos = start_pos + strlen("${" #fieldname "}");                                 \
            opal_asprintf(&retval, "%s%s%s", tmp, opal_install_dirs.ompiname + destdir_offset, \
                          end_pos);                                                            \
            free(tmp);                                                                         \
            changed = true;                                                                    \
        } else if (NULL != (start_pos = strstr(retval, "@{" #fieldname "}"))) {                \
            tmp = retval;                                                                      \
            *start_pos = '\0';                                                                 \
            end_pos = start_pos + strlen("@{" #fieldname "}");                                 \
            opal_asprintf(&retval, "%s%s%s", tmp, opal_install_dirs.ompiname + destdir_offset, \
                          end_pos);                                                            \
            free(tmp);                                                                         \
            changed = true;                                                                    \
        }                                                                                      \
    } while (0)

/*
 * Read the lengthy comment below to understand the value of the
 * is_setup parameter.
 */
static char *opal_install_dirs_expand_internal(const char *input, bool is_setup)
{
    size_t len, i;
    bool needs_expand = false;
    char *retval = NULL;
    char *destdir = NULL;
    size_t destdir_offset = 0;

    /* This is subtle, and worth explaining.

       If we substitute in any ${FIELD} values, we need to prepend it
       with the value of the $OPAL_DESTDIR environment variable -- if
       it is set.

       We need to handle at least three cases properly (assume that
       configure was invoked with --prefix=/opt/openmpi and no other
       directory specifications, and OPAL_DESTDIR is set to
       /tmp/buildroot):

       1. Individual directories, such as libdir.  These need to be
          prepended with DESTDIR.  I.e., return
          /tmp/buildroot/opt/openmpi/lib.

       2. Compiler flags that have ${FIELD} values embedded in them.
          For example, consider if a wrapper compiler data file
          contains the line:

          preprocessor_flags=-DMYFLAG="${prefix}/share/randomthingy/"

          The value we should return is:

          -DMYFLAG="/tmp/buildroot/opt/openmpi/share/randomthingy/"

       3. Compiler flags that do not have any ${FIELD} values.
          For example, consider if a wrapper compiler data file
          contains the line:

          preprocessor_flags=-pthread

          The value we should return is:

          -pthread

       Note, too, that this OPAL_DESTDIR futzing only needs to occur
       during opal_init().  By the time opal_init() has completed, all
       values should be substituted in that need substituting.  Hence,
       we take an extra parameter (is_setup) to know whether we should
       do this futzing or not. */
    if (is_setup) {
        destdir = getenv("OPAL_DESTDIR");
        if (NULL != destdir && strlen(destdir) > 0) {
            destdir_offset = strlen(destdir);
        }
    }

    len = strlen(input);
    for (i = 0; i < len; ++i) {
        if ('$' == input[i] || '@' == input[i]) {
            needs_expand = true;
            break;
        }
    }

    retval = strdup(input);
    if (NULL == retval) {
        return NULL;
    }

    if (needs_expand) {
        bool changed = false;
        char *start_pos, *end_pos, *tmp;

        do {
            changed = false;
            EXPAND_STRING(prefix);
            EXPAND_STRING(exec_prefix);
            EXPAND_STRING(bindir);
            EXPAND_STRING(sbindir);
            EXPAND_STRING(libexecdir);
            EXPAND_STRING(datarootdir);
            EXPAND_STRING(datadir);
            EXPAND_STRING(sysconfdir);
            EXPAND_STRING(sharedstatedir);
            EXPAND_STRING(localstatedir);
            EXPAND_STRING(libdir);
            EXPAND_STRING(includedir);
            EXPAND_STRING(infodir);
            EXPAND_STRING(mandir);
            EXPAND_STRING2(opaldatadir, pkgdatadir);
            EXPAND_STRING2(opallibdir, pkglibdir);
            EXPAND_STRING2(opalincludedir, pkgincludedir);
        } while (changed);
    }

    if (NULL != destdir) {
        char *tmp = retval;
        retval = opal_os_path(false, destdir, tmp, NULL);
        free(tmp);
    }

    return retval;
}

char *opal_install_dirs_expand(const char *input)
{
    /* We do NOT want OPAL_DESTDIR expansion in this case. */
    return opal_install_dirs_expand_internal(input, false);
}

char *opal_install_dirs_expand_setup(const char *input)
{
    /* We DO want OPAL_DESTDIR expansion in this case. */
    return opal_install_dirs_expand_internal(input, true);
}