X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/dd2c2ec080fbb9b9d0d3145887d05347934dddba..f1e16f884308e8ef720a4ecbcdcc97af97dce4bd:/avr/env.c diff --git a/avr/env.c b/avr/env.c index 1ec0c8e..671d1c4 100644 --- a/avr/env.c +++ b/avr/env.c @@ -14,17 +14,10 @@ #define DEBUG_ENV 0 /* set to 1 to debug */ -#define debug_env(fmt, args...) \ +#define debug_env(fmt, args...) \ 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 */ @@ -32,22 +25,28 @@ #define DELIM "\0" const FLASH char default_env[] = { - ENV_BAUDRATE "=" "115200" DELIM - ENV_BOOTDELAY "=" "3" DELIM + ENV_BAUDRATE "=" stringify(CONFIG_BAUDRATE) DELIM + ENV_BOOTDELAY "=" stringify(CONFIG_BOOTDELAY) DELIM ENV_BOOTCMD "=" "pin ${pins};loadcpm3;go ${startaddress}" DELIM ENV_CPM3_SYSFILE "=" CONFIG_CPM3_SYSFILE DELIM ENV_PINALIAS "=" "0:PG5,1:PG4,2:PB4,3:PB5,4:PB6,5:PB7," "6:PG3,7:PG2,8:PG1,9:PG0,10:PE7" DELIM - //ENV_STARTADDRESS "=" "0" DELIM "pins" "=" "2,8 low 9 high 3 2" DELIM DELIM }; +#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 +131,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 +196,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 +223,7 @@ static char *envlist_enter(const char *ep) return lp; } - +#endif static int envlist_delete(const MEMX char *name) @@ -194,31 +239,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 +533,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; } @@ -641,9 +692,6 @@ command_ret_t do_env_print(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, bool mode = 0; command_ret_t rc = CMD_RET_SUCCESS; - /* reset getopt() */ - optind = 0; - int opt; while ((opt = getopt(argc, argv, PSTR("s"))) != -1) { switch (opt) { @@ -662,14 +710,14 @@ 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; } /* print selected env vars */ while (optind < argc) { - int rc = env_print(argv[optind], mode); - if (rc < 0) { + int len = env_print(argv[optind], mode); + if (len < 0) { printf_P(PSTR("## Error: \"%s\" not defined\n"), argv[optind]); rc = CMD_RET_FAILURE; } @@ -743,3 +791,91 @@ int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf) return found; } #endif + +cmd_tbl_t cmd_tbl_env[] = { +CMD_TBL_ITEM_COMPLETE( + printenv, CONFIG_SYS_MAXARGS, 1|CTBL_SUBCMDAUTO, do_env_print, + "print environment variables", + "[-s] [name ...]\n" + " Print value of environment variable(s) 'name'\n" + " If no names are given, print values of all environment variables\n" + " -s Print in setenv form", + var_complete +), +CMD_TBL_ITEM_COMPLETE( + setenv, CONFIG_SYS_MAXARGS, CTBL_SUBCMDAUTO, do_env_set, + "set environment variables", + "name value ...\n" + " - set environment variable 'name' to 'value ...'\n" + "setenv name\n" + " - delete environment variable 'name'", + var_complete +), +CMD_TBL_ITEM( + saveenv, 1, CTBL_SUBCMDAUTO, do_env_save, + "save environment variables to persistent storage", + "" +), +CMD_TBL_ITEM( + defaultenv, 1, CTBL_SUBCMDAUTO, do_env_default, + "set all environment variables to their default values", + "" +), + +CMD_TBL_ITEM_COMPLETE( + print, CONFIG_SYS_MAXARGS, 1, do_env_print, + "print environment variables", + "[-s] [name ...]\n" + " Print value of environment variable(s) 'name'\n" + " If no names are given, print values of all environment variables\n" + " -s Print in setenv form", + var_complete +), +CMD_TBL_ITEM_COMPLETE( + set, CONFIG_SYS_MAXARGS, 0, do_env_set, + "set environment variables", + "name value ...\n" + " - set environment variable 'name' to 'value ...'\n" + "setenv name\n" + " - delete environment variable 'name'", + var_complete +), +CMD_TBL_ITEM( + save, 1, 0, do_env_save, + "save environment variables to persistent storage", + "" +), +CMD_TBL_ITEM( + default, 1, 0, do_env_default, + "set all environment variables to their default values", + "" +), + +CMD_TBL_ITEM( + help, CONFIG_SYS_MAXARGS, CTBL_RPT, do_help, + "Print sub command description/usage", + "\n" + " - print brief description of all sub commands\n" + "env help command ...\n" + " - print detailed usage of sub cmd 'command'" +), + +/* This does not use the CMD_TBL_ITEM macro as ? can't be used in symbol names */ + {FSTR("?"), CONFIG_SYS_MAXARGS, 1, do_help, + NULL, +#ifdef CONFIG_SYS_LONGHELP + FSTR(""), +#endif /* CONFIG_SYS_LONGHELP */ + NULL, +#ifdef CONFIG_AUTO_COMPLETE + NULL, +#endif +}, +/* Mark end of table */ +CMD_TBL_END(cmd_tbl_env) +}; + +command_ret_t do_env(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED) +{ + return CMD_RET_USAGE; +}