summaryrefslogtreecommitdiff
path: root/avr
diff options
context:
space:
mode:
authorLeo C2018-07-26 17:44:46 +0200
committerLeo C2018-07-26 17:44:46 +0200
commit8b2c7c224f3ff45c5404501034bdc2e01612eef0 (patch)
tree65337e3ff819e08835f790bafa18a5321b4225bf /avr
parentdd2c2ec080fbb9b9d0d3145887d05347934dddba (diff)
downloadz180-stamp-8b2c7c224f3ff45c5404501034bdc2e01612eef0.zip
heap.c: Eliminate malloc/free in envlist_import() and _do_env_set()
Diffstat (limited to 'avr')
-rw-r--r--avr/env.c112
1 files changed, 82 insertions, 30 deletions
diff --git a/avr/env.c b/avr/env.c
index 1ec0c8e..6bbd99c 100644
--- a/avr/env.c
+++ b/avr/env.c
@@ -132,6 +132,55 @@ static char *envlist_search(const MEMX char *name)
return NULL;
}
+static char *env_item_insert_name(char *pos, const char *name, int len)
+{
+ char *dstp = pos + len + 1;
+ char *end = pos;
+ while (*end++ != 0)
+ while (*end++ != 0);
+
+ if (end > env_list + ENV_SIZE)
+ return NULL;
+
+ memmove(dstp, pos, end - pos);
+ strcpy(pos, name);
+ memset(pos + strlen(name), '=', dstp - pos - strlen(name));
+ *(dstp - 1) = '\0';
+
+ return pos;
+}
+
+
+static char *envlist_alloc(const char *name, int len)
+{
+ char *lp;
+ int rc;
+
+
+ for (lp = env_list; *lp != 0; ++lp) {
+
+ rc = envcmp(lp, name);
+ if (rc >= 0)
+ break;
+
+ /* rc < 0 : check next place */
+ while (*lp != 0)
+ ++lp;
+ }
+
+ /* rc == 0 : entry found, replace */
+ if (rc == 0)
+ env_item_delete(lp);
+
+ /* rc > 0 : entry not in list, insert */
+ /* *lp == 0 : entry not in list, insert */
+
+ lp = env_item_insert_name(lp, name, len);
+
+ return lp;
+}
+
+#if 0
static char *env_item_insert(char *pos, const char *envstr)
{
char *dstp = pos + strlen(envstr) + 1;
@@ -148,14 +197,11 @@ static char *env_item_insert(char *pos, const char *envstr)
return pos;
}
-
static char *envlist_enter(const char *ep)
{
char *lp;
- size_t len = strchr(ep, '=') - ep;
int rc;
-
for (lp = env_list; *lp != 0; ++lp) {
rc = envcmp(lp, ep);
@@ -178,7 +224,7 @@ static char *envlist_enter(const char *ep)
return lp;
}
-
+#endif
static
int envlist_delete(const MEMX char *name)
@@ -194,31 +240,40 @@ int envlist_delete(const MEMX char *name)
static
int envlist_import(uint8_t flags)
{
- uint16_t index;
- int len;
- char *ep;
-
if ((flags & ENVLIST_DELETE) != 0)
envlist_clear();
- for (index = 0; env_get_char(index) != '\0'; ) {
- for (len = 0; env_get_char(index + len) != '\0'; ++len) {
+ for (uint_fast16_t index = 0; env_get_char(index) != '\0'; ) {
+ char name[CONFIG_SYS_ENV_NAMELEN+1];
+ uint_fast8_t nlen = 0;
+ size_t len;
+ char ch;
+ for (len = 0; (ch = env_get_char(index + len)) != '\0'; ++len) {
if ((index + len) >= ENV_SIZE)
return -1;
+ if (nlen == 0) {
+ if (ch == '=') {
+ nlen = len;
+ name[nlen] = '\0';
+ } else {
+ if (len > CONFIG_SYS_ENV_NAMELEN)
+ return -1;
+ name[len] = ch;
+ }
+ }
}
- ep = (char *) malloc(len+1);
+ char *ep = envlist_alloc(name, len);
if (ep == NULL) {
- printf_P(PSTR("## Can't malloc %d bytes\n"), len+1);
+ printf_P(PSTR("## Error inserting \"%s\" variable.\n"), name);
return 1;
}
- char *p = ep;
+
+ index += nlen;
+ char *p = ep + nlen;
while ((*p++ = env_get_char(index++)) != '\0')
;
- envlist_enter(ep);
- free(ep);
}
-
return 0;
}
@@ -479,27 +534,24 @@ command_ret_t _do_env_set(uint_fast8_t flag UNUSED, int argc, char * const argv[
}
/* Insert / replace new value */
- len += 1;
+
for (int_fast8_t i = 2; i < argc; ++i)
len += strlen(argv[i]) + 1;
- char *envstr = malloc(len);
- if (envstr == NULL) {
- printf_P(PSTR("## Can't malloc %d bytes\n"), len);
+ char *pos = envlist_alloc(name, len);
+ if (pos == NULL) {
+ printf_P(PSTR("## Error inserting \"%s\" variable.\n"), name);
return CMD_RET_FAILURE;
}
- strcpy(envstr, name);
- strcat_P(envstr, PSTR("="));
- for (int_fast8_t i = 2; i < argc; ++i) {
- strcat(envstr, argv[i]);
- if (i < argc-1)
- strcat_P(envstr, PSTR(" "));
- }
- if (envlist_enter(envstr) == NULL) {
- printf_P(PSTR("## Error inserting \"%s\" variable.\n"), name);
- return CMD_RET_FAILURE;
+ char *vp = pos + strlen(name) + 1;
+ for (int_fast8_t i = 2; i < argc; ++i) {
+ char *ap = argv[i];
+ while ((*vp++ = *ap++) != '\0');
+ //if (i < argc-1)
+ *(vp-1) = ' ';
}
+ *(vp-1) = '\0';
return CMD_RET_SUCCESS;
}