#include #include #include #include #include #include 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; }