Bläddra i källkod

Merge branch 'feature/mconf_simple_expand' into 'master'

mconf-idf: Use same 'simple expand' logic, same as kconfig-frontends

See merge request idf/esp-idf!5390
Angus Gratton 6 år sedan
förälder
incheckning
0c8192f3be
4 ändrade filer med 132 tillägg och 17 borttagningar
  1. 6 6
      tools/kconfig/Makefile
  2. 88 0
      tools/kconfig/expand_env.c
  3. 13 0
      tools/kconfig/expand_env.h
  4. 25 11
      tools/kconfig/zconf.l

+ 6 - 6
tools/kconfig/Makefile

@@ -192,13 +192,13 @@ lxdialog/%.o: $(SRCDIR)/lxdialog/%.c
 lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
 lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
 
-conf-objs	:= conf.o  zconf.tab.o
-mconf-objs     := mconf.o zconf.tab.o $(lxdialog)
-nconf-objs     := nconf.o zconf.tab.o nconf.gui.o
-kxgettext-objs	:= kxgettext.o zconf.tab.o
+conf-objs	:= conf.o  zconf.tab.o expand_env.o
+mconf-objs     := mconf.o zconf.tab.o $(lxdialog) expand_env.o
+nconf-objs     := nconf.o zconf.tab.o nconf.gui.o expand_env.o
+kxgettext-objs	:= kxgettext.o zconf.tab.o expand_env.o
 qconf-cxxobjs	:= qconf.o
-qconf-objs	:= zconf.tab.o
-gconf-objs	:= gconf.o zconf.tab.o
+qconf-objs	:= zconf.tab.o expand_env.o
+gconf-objs	:= gconf.o zconf.tab.o expand_env.o
 
 hostprogs-y := conf-idf nconf mconf-idf kxgettext qconf gconf
 

+ 88 - 0
tools/kconfig/expand_env.c

@@ -0,0 +1,88 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <stdbool.h>
+
+#include "expand_env.h"
+
+static bool allowed_env_var_name(char c)
+{
+  return c != '\0' &&
+    !isblank(c) &&
+    !iscntrl(c) &&
+    c != '/' &&
+    c != '\\' &&
+    c != '=' &&
+    c != '$';
+}
+
+#define MAX_LEN (128 * 1024) /* Longest a result can expand to */
+
+/* Very basic expansion that looks for variable references like $NAME and expands them
+ *
+ */
+char *expand_environment(const char *input, const char *src_name, int src_line_no)
+{
+  char *result = malloc(MAX_LEN);
+
+  char *out = result;
+  const char *in = input;
+
+  while (*in != '\0') {
+    // check for buffer overflow
+    if (out >= result + MAX_LEN - 1) {
+      goto too_long;
+    }
+
+    if (*in != '$') {
+      // not part of an environment variable name, copy directly
+      *out++ = *in++;
+      continue;
+    }
+
+    // *in points to start of an environment variable reference
+    in++;
+    const char *env_start = in;
+    while (allowed_env_var_name(*in)) { // scan to the end of the name
+      in++;
+    }
+    size_t env_len = in - env_start;
+
+    // make a buffer to hold the environment variable name
+    //
+    // strndup is not available on mingw32, apparently.
+    char *env_name = calloc(1, env_len + 1);
+    assert(env_name != NULL);
+    strncpy(env_name, env_start, env_len);
+
+    const char *value = getenv(env_name);
+    if (value == NULL || strlen(value) == 0) {
+      printf("%s:%d: undefined environment variable \"%s\"\n",
+             src_name, src_line_no, env_name);
+      exit(1);
+    }
+    free(env_name);
+    if (out + strlen(value) >= result + MAX_LEN - 1) {
+      goto too_long;
+    }
+    strcpy(out, value); // append the value to the result (range checked in previous statement)
+    out += strlen(value);
+  }
+
+  *out = '\0'; // null terminate the result string
+
+  return result;
+
+too_long:
+  printf("%s:%d: Expansion is longer than %d bytes\n",
+         src_name, src_line_no, MAX_LEN);
+  free(result);
+  exit(1);
+}
+
+void free_expanded(char *expanded)
+{
+  free(expanded);
+}

+ 13 - 0
tools/kconfig/expand_env.h

@@ -0,0 +1,13 @@
+#pragma once
+
+/* Expand any $ENV type environment variables in 'input',
+   return a newly allocated buffer with the result.
+
+   Buffer should be freed after use.
+
+   This is very basic expansion, doesn't do escaping or anything else.
+*/
+char *expand_environment(const char *input, const char *src_name, int src_line_no);
+
+/* Free a buffer allocated by expand_environment */
+void free_expanded(char *expanded);

+ 25 - 11
tools/kconfig/zconf.l

@@ -13,9 +13,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <wordexp.h>
 
 #include "lkc.h"
+#include "expand_env.h"
 
 #define START_STRSIZE	16
 
@@ -348,19 +348,33 @@ void zconf_nextfile(const char *name)
 	current_file = file;
 }
 
-void zconf_nextfiles(const char *wildcard)
+void zconf_nextfiles(const char *expression)
 {
-	wordexp_t p;
-	char **w;
-	int i;
-
-	wordexp(wildcard, &p, 0);
-	w = p.we_wordv;
+	/* Expand environment variables in 'expression' */
+	char* str = expand_environment(expression, zconf_curname(), zconf_lineno());
+
+	/* zconf_nextfile() processes files in LIFO order, so to keep the
+	   files in the order provided we need to process the list backwards
+	*/
+	if (str != NULL && strlen(str)) {
+		char* pos = str + strlen(str); // start at null terminator
+
+		while (pos != str) {
+			pos--;
+			if(*pos == ' ') {
+				*pos = '\0'; // split buffer into multiple c-strings
+				if (strlen(pos + 1)) {
+					zconf_nextfile(pos + 1);
+				}
+			}
+		}
 
-	for (i = p.we_wordc - 1; i >= 0; i--)
-		zconf_nextfile(w[i]);
+		if (strlen(str)) { // re-check as first character may have been a space
+			zconf_nextfile(str);
+		}
+	}
 
-	wordfree(&p);
+	free_expanded(str);
 }
 
 static void zconf_endfile(void)