summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c10
-rw-r--r--cgit.h2
-rw-r--r--shared.c71
3 files changed, 78 insertions, 5 deletions
diff --git a/cgit.c b/cgit.c
index ab25b6a..fde0757 100644
--- a/cgit.c
+++ b/cgit.c
@@ -154,3 +154,3 @@ void config_cb(const char *name, const char *value)
else if (!strcmp(name, "cache-root"))
- ctx.cfg.cache_root = xstrdup(value);
+ ctx.cfg.cache_root = xstrdup(expand_macros(value));
else if (!strcmp(name, "cache-root-ttl"))
@@ -185,5 +185,5 @@ void config_cb(const char *name, const char *value)
if (!ctx.cfg.nocache && ctx.cfg.cache_size)
- process_cached_repolist(value);
+ process_cached_repolist(expand_macros(value));
else
- scan_tree(value, repo_config);
+ scan_tree(expand_macros(value), repo_config);
else if (!strcmp(name, "source-filter"))
@@ -211,3 +211,3 @@ void config_cb(const char *name, const char *value)
else if (!strcmp(name, "include"))
- parse_configfile(value, config_cb);
+ parse_configfile(expand_macros(value), config_cb);
}
@@ -707,3 +707,3 @@ int main(int argc, const char **argv)
cgit_parse_args(argc, argv);
- parse_configfile(ctx.env.cgit_config, config_cb);
+ parse_configfile(expand_macros(ctx.env.cgit_config), config_cb);
ctx.repo = NULL;
diff --git a/cgit.h b/cgit.h
index 2b28d63..2bf6ab0 100644
--- a/cgit.h
+++ b/cgit.h
@@ -304,2 +304,4 @@ extern int readfile(const char *path, char **buf, size_t *size);
+extern char *expand_macros(const char *txt);
+
#endif /* CGIT_H */
diff --git a/shared.c b/shared.c
index 06f70bb..9f7d6a5 100644
--- a/shared.c
+++ b/shared.c
@@ -434 +434,72 @@ int readfile(const char *path, char **buf, size_t *size)
}
+
+int is_token_char(char c)
+{
+ return isalnum(c) || c == '_';
+}
+
+/* Replace name with getenv(name), return pointer to zero-terminating char
+ */
+char *expand_macro(char *name, int maxlength)
+{
+ char *value;
+ int len;
+
+ len = 0;
+ value = getenv(name);
+ if (value) {
+ len = strlen(value);
+ if (len > maxlength)
+ len = maxlength;
+ strncpy(name, value, len);
+ }
+ return name + len;
+}
+
+#define EXPBUFSIZE (1024 * 8)
+
+/* Replace all tokens prefixed by '$' in the specified text with the
+ * value of the named environment variable.
+ * NB: the return value is a static buffer, i.e. it must be strdup'd
+ * by the caller.
+ */
+char *expand_macros(const char *txt)
+{
+ static char result[EXPBUFSIZE];
+ char *p, *start;
+ int len;
+
+ p = result;
+ start = NULL;
+ while (p < result + EXPBUFSIZE - 1 && txt && *txt) {
+ *p = *txt;
+ if (start) {
+ if (!is_token_char(*txt)) {
+ if (p - start > 0) {
+ *p = '\0';
+ len = result + EXPBUFSIZE - start - 1;
+ p = expand_macro(start, len) - 1;
+ }
+ start = NULL;
+ txt--;
+ }
+ p++;
+ txt++;
+ continue;
+ }
+ if (*txt == '$') {
+ start = p;
+ txt++;
+ continue;
+ }
+ p++;
+ txt++;
+ }
+ *p = '\0';
+ if (start && p - start > 0) {
+ len = result + EXPBUFSIZE - start - 1;
+ p = expand_macro(start, len);
+ *p = '\0';
+ }
+ return result;
+}