env: add env_update()
This add/append/replace the sub value of an environment variable. Change-Id: I0fcda0a1c631013eb9458a04a09546ba1c643db3 Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
parent
fafee76a04
commit
64c74e0b2d
216
cmd/nvedit.c
216
cmd/nvedit.c
|
|
@ -297,6 +297,222 @@ int env_set(const char *varname, const char *varvalue)
|
|||
return _do_env_set(0, 3, (char * const *)argv, H_PROGRAMMATIC);
|
||||
}
|
||||
|
||||
static int env_append(const char *varname, const char *varvalue)
|
||||
{
|
||||
int len = 0;
|
||||
char *oldvalue, *newvalue;
|
||||
|
||||
/* before import into hashtable */
|
||||
if (!(gd->flags & GD_FLG_ENV_READY) || !varname)
|
||||
return 1;
|
||||
|
||||
if (varvalue)
|
||||
len += strlen(varvalue);
|
||||
|
||||
oldvalue = env_get(varname);
|
||||
if (oldvalue) {
|
||||
len += strlen(oldvalue);
|
||||
/* Exist ! */
|
||||
if (strstr(oldvalue, varvalue))
|
||||
return 0;
|
||||
}
|
||||
|
||||
newvalue = malloc(len + 2);
|
||||
if (!newvalue) {
|
||||
printf("Error: malloc in %s failed!\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
*newvalue = '\0';
|
||||
|
||||
if (oldvalue) {
|
||||
strcpy(newvalue, oldvalue);
|
||||
strcat(newvalue, " ");
|
||||
}
|
||||
|
||||
if (varvalue)
|
||||
strcat(newvalue, varvalue);
|
||||
|
||||
env_set(varname, newvalue);
|
||||
free(newvalue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int env_replace(const char *varname, const char *substr,
|
||||
const char *replacement)
|
||||
{
|
||||
char *oldvalue, *newvalue, *dst, *sub;
|
||||
int substr_len, replace_len, oldvalue_len, len;
|
||||
|
||||
/* before import into hashtable */
|
||||
if (!(gd->flags & GD_FLG_ENV_READY) || !varname)
|
||||
return 1;
|
||||
|
||||
oldvalue = env_get(varname);
|
||||
if (!oldvalue)
|
||||
return 1;
|
||||
|
||||
sub = strstr(oldvalue, substr);
|
||||
if (!sub)
|
||||
return 1;
|
||||
|
||||
oldvalue_len = strlen(oldvalue) + 1;
|
||||
substr_len = strlen(substr);
|
||||
replace_len = strlen(replacement);
|
||||
|
||||
if (replace_len >= substr_len)
|
||||
len = oldvalue_len + replace_len - substr_len;
|
||||
else
|
||||
len = oldvalue_len + substr_len - replace_len;
|
||||
|
||||
newvalue = malloc(len);
|
||||
if (!newvalue) {
|
||||
printf("Error: malloc in %s failed!\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
*newvalue = '\0';
|
||||
|
||||
/*
|
||||
* Orignal string is splited like format: [str1.. substr str2..]
|
||||
*/
|
||||
|
||||
/* str1.. */
|
||||
dst = newvalue;
|
||||
dst = strncat(dst, oldvalue, sub - oldvalue);
|
||||
|
||||
/* substr */
|
||||
dst += sub - oldvalue;
|
||||
dst = strncat(dst, replacement, replace_len);
|
||||
|
||||
/* str2.. */
|
||||
dst += replace_len;
|
||||
len = oldvalue_len - substr_len - (sub - oldvalue);
|
||||
dst = strncat(dst, sub + substr_len, len);
|
||||
|
||||
env_set(varname, newvalue);
|
||||
free(newvalue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ARGS_ITEM_NUM 50
|
||||
|
||||
int env_update(const char *varname, char *varvalue)
|
||||
{
|
||||
/* 'a_' means "varargs_'; 'v_' means 'varvalue_' */
|
||||
char *varargs;
|
||||
char *a_title, *v_title;
|
||||
char *a_string_tok, *a_item_tok = NULL;
|
||||
char *v_string_tok, *v_item_tok = NULL;
|
||||
char *a_item, *a_items[ARGS_ITEM_NUM] = { NULL };
|
||||
char *v_item, *v_items[ARGS_ITEM_NUM] = { NULL };
|
||||
bool match = false;
|
||||
int i = 0, j = 0;
|
||||
|
||||
/* Before import into hashtable */
|
||||
if (!(gd->flags & GD_FLG_ENV_READY) || !varname)
|
||||
return 1;
|
||||
|
||||
/* If varname doesn't exist, create it and set varvalue */
|
||||
varargs = env_get(varname);
|
||||
if (!varargs) {
|
||||
env_set(varname, varvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Malloc a temporary varargs for strtok */
|
||||
a_string_tok = strdup(varargs);
|
||||
if (!a_string_tok) {
|
||||
printf("Error: strdup in failed, line=%d\n", __LINE__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Malloc a temporary varvalue for strtok */
|
||||
v_string_tok = strdup(varvalue);
|
||||
if (!v_string_tok) {
|
||||
free(a_string_tok);
|
||||
printf("Error: strdup in failed, line=%d\n", __LINE__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Splite varargs into items containing "=" by the blank */
|
||||
a_item = strtok(a_string_tok, " ");
|
||||
while (a_item && i < ARGS_ITEM_NUM) {
|
||||
debug("%s: [a_item %d]: %s\n", __func__, i, a_item);
|
||||
if (strstr(a_item, "="))
|
||||
a_items[i++] = a_item;
|
||||
a_item = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
/*
|
||||
* Splite varvalue into items containing "=" by the blank.
|
||||
* parse varvalue title, eg: "bootmode=emmc", title is "bootmode"
|
||||
*/
|
||||
v_item = strtok(v_string_tok, " ");
|
||||
while (v_item && j < ARGS_ITEM_NUM) {
|
||||
debug("%s: <v_item %d>: %s\n", __func__, j, v_item);
|
||||
if (strstr(v_item, "="))
|
||||
v_items[j++] = v_item;
|
||||
else
|
||||
env_append(varname, v_item);
|
||||
v_item = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
/* For every v_item, search its title */
|
||||
for (j = 0; j < ARGS_ITEM_NUM && v_items[j]; j++) {
|
||||
v_item = v_items[j];
|
||||
/* Malloc a temporary a_item for strtok */
|
||||
v_item_tok = strdup(v_item);
|
||||
if (!v_item_tok) {
|
||||
printf("Error: strdup in failed, line=%d\n", __LINE__);
|
||||
free(a_string_tok);
|
||||
free(v_string_tok);
|
||||
return 1;
|
||||
}
|
||||
v_title = strtok(v_item_tok, "=");
|
||||
debug("%s: <v_title>: %s\n", __func__, v_title);
|
||||
|
||||
/* For every a_item, search its title */
|
||||
for (i = 0; i < ARGS_ITEM_NUM && a_items[i]; i++) {
|
||||
a_item = a_items[i];
|
||||
/* Malloc a temporary a_item for strtok */
|
||||
a_item_tok = strdup(a_item);
|
||||
if (!a_item_tok) {
|
||||
printf("Error: strdup in failed, line=%d\n", __LINE__);
|
||||
free(a_string_tok);
|
||||
free(v_string_tok);
|
||||
free(v_item_tok);
|
||||
return 1;
|
||||
}
|
||||
|
||||
a_title = strtok(a_item_tok, "=");
|
||||
debug("%s: [a_title]: %s\n", __func__, a_title);
|
||||
if (!strcmp(a_title, v_title)) {
|
||||
/* Find! replace it */
|
||||
env_replace(varname, a_item, v_item);
|
||||
free(a_item_tok);
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
free(a_item_tok);
|
||||
}
|
||||
|
||||
/* Not find, just append */
|
||||
if (!match)
|
||||
env_append(varname, v_item);
|
||||
|
||||
match = false;
|
||||
free(v_item_tok);
|
||||
}
|
||||
|
||||
free(v_string_tok);
|
||||
free(a_string_tok);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an environment variable to an integer value
|
||||
*
|
||||
|
|
|
|||
|
|
@ -378,6 +378,17 @@ int env_get_yesno(const char *var);
|
|||
*/
|
||||
int env_set(const char *varname, const char *value);
|
||||
|
||||
/**
|
||||
* env_update() - update sub value of an environment variable
|
||||
*
|
||||
* This add/append/replace the sub value of an environment variable.
|
||||
*
|
||||
* @varname: Variable to adjust
|
||||
* @valude: Value to append/replace
|
||||
* @return 0 if OK, 1 on error
|
||||
*/
|
||||
int env_update(const char *varname, char *varvalue);
|
||||
|
||||
/**
|
||||
* env_set_ulong() - set an environment variable to an integer
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue