]> cloudbase.mooo.com Git - z180-stamp.git/blobdiff - avr/env.c
ENV_SIZE
[z180-stamp.git] / avr / env.c
index 1ec0c8eae2dae65eacc736f96fe4a588ff7a55bc..44c5742afe3043a6054218eede24a7660436e62b 100644 (file)
--- a/avr/env.c
+++ b/avr/env.c
        debug_cond(DEBUG_ENV, fmt, ##args)
 
 
-#define ENV_SIZE       (CONFIG_ENV_SIZE - sizeof(uint16_t) -1)
-#define ACTIVE_FLAG    1
-#define OBSOLETE_FLAG  0
-
-#define ENVLIST_DELETE (1<<0)
-
-
 /*
  * Default Environment
  */
@@ -44,10 +37,17 @@ const FLASH char default_env[] = {
 };
 
 
+#define ENV_SIZE       (CONFIG_ENV_SIZE - sizeof(uint16_t) - sizeof(uint8_t))
+
+#define ENVLIST_DELETE (1<<0)
+
+
 /* EEPROM storage */
 typedef struct environment_s {
        uint16_t        crc;            /* CRC16 over data bytes        */
        uint8_t         flags;          /* active/obsolete flags        */
+#define ACTIVE_FLAG            1
+#define OBSOLETE_FLAG  0
        char            data[ENV_SIZE]; /* Environment data             */
 } env_t;
 
@@ -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 + len >= 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;
 }
@@ -662,7 +714,7 @@ command_ret_t do_env_print(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED,
                        return CMD_RET_FAILURE;
                if (mode == 0)
                        printf_P(PSTR("\nEnvironment size: %d/%d bytes\n"),
-                               size, ENV_SIZE);
+                               size, ENV_SIZE - 1);
                return CMD_RET_SUCCESS;
        }