aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/qregisters.cpp
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2015-06-14 19:08:06 +0200
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2015-06-14 19:08:06 +0200
commit15409bae5ffdfce4ef17c4ccf14c8cd4c1b8f37e (patch)
tree852b915a69d57679a05ef5fec0ee6608cdcf2dee /src/qregisters.cpp
parent573951d4e2bb4fb1d14212583a59ce76344593cc (diff)
downloadsciteco-15409bae5ffdfce4ef17c4ccf14c8cd4c1b8f37e.tar.gz
handle environment variables more consistently
* the registers beginning with "$" are exported into sub-process environments. Therefore macros can now modify the environment (variables) of commands executed via EC/EG. A variable can be modified temporarily, e.g.: [[$FOO] ^U[$FOO]bar$ EC...$ ][$FOO] * SciTECO accesses the global environment registers instead of using g_getenv(). Therefore now, tilde-expansion will always use the current value of the "$HOME" register. Previously, both register and environment variable could diverge. * This effectively fully maps the process environment to a subset of Q-Registers beginning with "$". * This hasn't been implemented by mapping those registers to special implementations that updates the process environment directly, since g_setenv() is non-thread-safe on UNIX and we're expected to have threads soon - at least in the GTK+ UI.
Diffstat (limited to 'src/qregisters.cpp')
-rw-r--r--src/qregisters.cpp75
1 files changed, 74 insertions, 1 deletions
diff --git a/src/qregisters.cpp b/src/qregisters.cpp
index 20c1380..22d7300 100644
--- a/src/qregisters.cpp
+++ b/src/qregisters.cpp
@@ -529,7 +529,80 @@ QRegisterTable::edit(QRegister *reg)
QRegisters::current = reg;
}
-/*
+void
+QRegisterTable::set_environ(void)
+{
+ /*
+ * NOTE: Using g_get_environ() would be more efficient,
+ * but it appears to be broken, at least on Wine
+ * and Windows 2000.
+ */
+ gchar **env = g_listenv();
+
+ for (gchar **key = env; *key; key++) {
+ gchar name[1 + strlen(*key) + 1];
+ QRegister *reg;
+
+ name[0] = '$';
+ strcpy(name + 1, *key);
+
+ reg = insert(name);
+ reg->set_string(g_getenv(*key));
+ }
+
+ g_strfreev(env);
+}
+
+gchar **
+QRegisterTable::get_environ(void)
+{
+ QRegister *first = nfind("$");
+
+ gint envp_len = 1;
+ gchar **envp, **p;
+
+ /*
+ * Iterate over all registers beginning with "$" to
+ * guess the size required for the environment array.
+ * This may waste a few bytes because not __every__
+ * register beginning with "$" is an environment
+ * register.
+ */
+ for (QRegister *cur = first;
+ cur && cur->name[0] == '$';
+ cur = (QRegister *)cur->next())
+ envp_len++;
+
+ p = envp = (gchar **)g_malloc(sizeof(gchar *)*envp_len);
+
+ for (QRegister *cur = first;
+ cur && cur->name[0] == '$';
+ cur = (QRegister *)cur->next()) {
+ gchar *value;
+
+ /*
+ * Ignore the "$" register (not an environment
+ * variable register) and registers whose
+ * name contains "=" (not allowed in environment
+ * variable names).
+ */
+ if (!cur->name[1] || strchr(cur->name+1, '='))
+ continue;
+
+ value = cur->get_string();
+ /* more efficient than g_environ_setenv() */
+ *p++ = g_strconcat(cur->name+1, "=", value, NIL);
+ g_free(value);
+ }
+
+ *p = NULL;
+
+ return envp;
+}
+
+/**
+ * Free resources associated with table.
+ *
* This is similar to RBTree::clear() but
* has the advantage that we can check whether some
* register is currently edited.