forked from espressif/esp-idf
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
This commit is contained in:
@@ -192,13 +192,13 @@ lxdialog/%.o: $(SRCDIR)/lxdialog/%.c
|
|||||||
lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
|
lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
|
||||||
lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
|
lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
|
||||||
|
|
||||||
conf-objs := conf.o zconf.tab.o
|
conf-objs := conf.o zconf.tab.o expand_env.o
|
||||||
mconf-objs := mconf.o zconf.tab.o $(lxdialog)
|
mconf-objs := mconf.o zconf.tab.o $(lxdialog) expand_env.o
|
||||||
nconf-objs := nconf.o zconf.tab.o nconf.gui.o
|
nconf-objs := nconf.o zconf.tab.o nconf.gui.o expand_env.o
|
||||||
kxgettext-objs := kxgettext.o zconf.tab.o
|
kxgettext-objs := kxgettext.o zconf.tab.o expand_env.o
|
||||||
qconf-cxxobjs := qconf.o
|
qconf-cxxobjs := qconf.o
|
||||||
qconf-objs := zconf.tab.o
|
qconf-objs := zconf.tab.o expand_env.o
|
||||||
gconf-objs := gconf.o zconf.tab.o
|
gconf-objs := gconf.o zconf.tab.o expand_env.o
|
||||||
|
|
||||||
hostprogs-y := conf-idf nconf mconf-idf kxgettext qconf gconf
|
hostprogs-y := conf-idf nconf mconf-idf kxgettext qconf gconf
|
||||||
|
|
||||||
|
88
tools/kconfig/expand_env.c
Normal file
88
tools/kconfig/expand_env.c
Normal file
@@ -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
tools/kconfig/expand_env.h
Normal file
13
tools/kconfig/expand_env.h
Normal file
@@ -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);
|
@@ -13,9 +13,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wordexp.h>
|
|
||||||
|
|
||||||
#include "lkc.h"
|
#include "lkc.h"
|
||||||
|
#include "expand_env.h"
|
||||||
|
|
||||||
#define START_STRSIZE 16
|
#define START_STRSIZE 16
|
||||||
|
|
||||||
@@ -348,19 +348,33 @@ void zconf_nextfile(const char *name)
|
|||||||
current_file = file;
|
current_file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zconf_nextfiles(const char *wildcard)
|
void zconf_nextfiles(const char *expression)
|
||||||
{
|
{
|
||||||
wordexp_t p;
|
/* Expand environment variables in 'expression' */
|
||||||
char **w;
|
char* str = expand_environment(expression, zconf_curname(), zconf_lineno());
|
||||||
int i;
|
|
||||||
|
|
||||||
wordexp(wildcard, &p, 0);
|
/* zconf_nextfile() processes files in LIFO order, so to keep the
|
||||||
w = p.we_wordv;
|
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
|
||||||
|
|
||||||
for (i = p.we_wordc - 1; i >= 0; i--)
|
while (pos != str) {
|
||||||
zconf_nextfile(w[i]);
|
pos--;
|
||||||
|
if(*pos == ' ') {
|
||||||
|
*pos = '\0'; // split buffer into multiple c-strings
|
||||||
|
if (strlen(pos + 1)) {
|
||||||
|
zconf_nextfile(pos + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wordfree(&p);
|
if (strlen(str)) { // re-check as first character may have been a space
|
||||||
|
zconf_nextfile(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free_expanded(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zconf_endfile(void)
|
static void zconf_endfile(void)
|
||||||
|
Reference in New Issue
Block a user