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
|
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <wordexp.h>
#include <lib/base/eenv.h>
#include <lib/base/eerror.h>
bool eEnv::initialized = false;
void eEnv::initialize()
{
static const struct {
std::string name;
std::string value;
} cfgenv[] = {
{ "prefix", "@prefix@" },
{ "exec_prefix", "@exec_prefix@" },
{ "bindir", "@bindir@" },
{ "sbindir", "@sbindir@" },
{ "libexecdir", "@libexecdir@" },
{ "datarootdir", "@datarootdir@" },
{ "datadir", "@datadir@" },
{ "sysconfdir", "@sysconfdir@" },
{ "sharedstatedir", "@sharedstatedir@" },
{ "localstatedir", "@localstatedir@" },
{ "libdir", "@libdir@" },
{ "localedir", "@localedir@" },
};
size_t i;
// 1st pass, as generated by configure.
// Variables set by the user will not be overwritten.
for (i = 0; i < (sizeof(cfgenv) / sizeof(*cfgenv)); i++) {
eDebug("setenv('%s', '%s', 0)", cfgenv[i].name.c_str(), cfgenv[i].value.c_str());
setenv(cfgenv[i].name.c_str(), cfgenv[i].value.c_str(), 0);
}
// 2nd pass: Resolve directories.
for (i = 0; i < (sizeof(cfgenv) / sizeof(*cfgenv)); i++) {
std::string dest;
eEnv::resolveVar(dest, "${" + cfgenv[i].name + "}");
eDebug("setenv('%s', '%s', 1)", cfgenv[i].name.c_str(), dest.c_str());
setenv(cfgenv[i].name.c_str(), dest.c_str(), 1);
}
}
int eEnv::resolveVar(std::string &dest, const char *src)
{
size_t i = 0;
int ret;
wordexp_t p;
ret = wordexp(src, &p, WRDE_NOCMD | WRDE_UNDEF);
if (ret != 0) {
switch (ret) {
case WRDE_BADCHAR:
eDebug("%s: bad character", __func__);
break;
case WRDE_BADVAL:
eDebug("%s: bad value", __func__);
break;
case WRDE_CMDSUB:
eDebug("%s: invalid command substitution", __func__);
break;
case WRDE_NOSPACE:
eDebug("%s: out of memory", __func__);
break;
case WRDE_SYNTAX:
eDebug("%s: syntax error", __func__);
break;
default:
eDebug("%s: unknown error", __func__);
break;
}
return -1;
}
while (i < p.we_wordc) {
if (strchr(p.we_wordv[i], '$')) {
ret = eEnv::resolveVar(dest, p.we_wordv[i]);
if (ret < 0)
break;
} else {
dest.append(p.we_wordv[i]);
}
if (++i < p.we_wordc)
dest.append(" ");
}
wordfree(&p);
return ret;
}
int eEnv::resolveVar(std::string &dest, const std::string &src)
{
return eEnv::resolveVar(dest, src.c_str());
}
std::string eEnv::resolve(const std::string &src)
{
std::string dest;
if (!initialized) {
eEnv::initialize();
initialized = true;
}
eDebug("%s: resolve %s", __func__, src.c_str());
eEnv::resolveVar(dest, src);
eDebug("%s: -> %s", __func__, dest.c_str());
return dest;
}
|