aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Oberritter <obi@opendreambox.org>2010-10-28 20:23:36 +0200
committerAndreas Oberritter <obi@opendreambox.org>2010-11-16 17:15:37 +0100
commitdb7f9eb0a8f0d7af9d34d74986b910fe689f711f (patch)
tree173701822d5cb9d86c6535087d2a4a207fc50c1a
parentded9f8508f8d0723d84cc9f4bc7d234b69b829e0 (diff)
downloadenigma2-db7f9eb0a8f0d7af9d34d74986b910fe689f711f.tar.gz
enigma2-db7f9eb0a8f0d7af9d34d74986b910fe689f711f.zip
add eEnv::resolve() to resolve install paths at runtime
-rw-r--r--lib/base/Makefile.am5
-rw-r--r--lib/base/eenv.cpp.in117
-rw-r--r--lib/base/eenv.h16
-rw-r--r--lib/python/enigma_python.i2
4 files changed, 140 insertions, 0 deletions
diff --git a/lib/base/Makefile.am b/lib/base/Makefile.am
index 498244fb..230a37ae 100644
--- a/lib/base/Makefile.am
+++ b/lib/base/Makefile.am
@@ -14,6 +14,8 @@ libenigma_base_la_SOURCES = \
console.h \
ebase.cpp \
ebase.h \
+ eenv.cpp \
+ eenv.h \
eerror.cpp \
eerror.h \
elock.cpp \
@@ -45,3 +47,6 @@ libenigma_base_la_SOURCES = \
smartptr.h \
thread.cpp \
thread.h
+
+EXTRA_DIST = \
+ eenv.cpp.in
diff --git a/lib/base/eenv.cpp.in b/lib/base/eenv.cpp.in
new file mode 100644
index 00000000..52c42147
--- /dev/null
+++ b/lib/base/eenv.cpp.in
@@ -0,0 +1,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;
+}
diff --git a/lib/base/eenv.h b/lib/base/eenv.h
new file mode 100644
index 00000000..3d149f5e
--- /dev/null
+++ b/lib/base/eenv.h
@@ -0,0 +1,16 @@
+#ifndef __lib_base_paths_h
+#define __lib_base_paths_h
+
+#include <string>
+
+class eEnv {
+private:
+ static bool initialized;
+ static void initialize();
+ static int resolveVar(std::string &dest, const char *src);
+ static int resolveVar(std::string &dest, const std::string &src);
+public:
+ static std::string resolve(const std::string &path);
+};
+
+#endif
diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i
index 19fb9254..43d94ac9 100644
--- a/lib/python/enigma_python.i
+++ b/lib/python/enigma_python.i
@@ -38,6 +38,7 @@ is usually caused by not marking PSignals as immutable.
#define SWIG_COMPILE
#include <lib/base/ebase.h>
#include <lib/base/smartptr.h>
+#include <lib/base/eenv.h>
#include <lib/base/eerror.h>
#include <lib/base/etpm.h>
#include <lib/base/nconfig.h>
@@ -133,6 +134,7 @@ typedef long time_t;
%include "std_string.i"
%include <lib/python/swig.h>
%include <lib/base/object.h>
+%include <lib/base/eenv.h>
%include <lib/base/eerror.h>
%immutable eSocketNotifier::activated;