summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo C2014-09-01 17:06:58 +0200
committerLeo C2014-09-02 14:01:01 +0200
commit507d25e2cdac7489ca8706f6582e271fd1689816 (patch)
tree24774662d51ff9f6185591fc4c3cc05032a02080
parentf76ca346168afe6cf68127934765a61bd477380e (diff)
downloadz180-stamp-507d25e2cdac7489ca8706f6582e271fd1689816.zip
process_macros: reduce heap usage and fragmentation
-rw-r--r--avr/cli.c196
-rw-r--r--avr/debug.c16
2 files changed, 103 insertions, 109 deletions
diff --git a/avr/cli.c b/avr/cli.c
index 08e7038..b310f79 100644
--- a/avr/cli.c
+++ b/avr/cli.c
@@ -43,114 +43,107 @@ static int cli_parse_line(char *line, char *argv[])
return nargs;
}
-static void process_macros(const char *input, char *output)
+static
+void append_char(uint_fast8_t pass, char **p, char c)
{
- char c, prev;
- const char *varname_start = NULL;
-#if 0 && (CONFIG_SYS_CBSIZE < __UINT_FAST8_MAX__)
- uint_fast8_t inputcnt = strlen(input);
- uint_fast8_t outputcnt = CONFIG_SYS_CBSIZE;
-#else
- int inputcnt = strlen(input);
- int outputcnt = CONFIG_SYS_CBSIZE;
-#endif
- uint_fast8_t state = 0; /* 0 = waiting for '$' */
-
- /* 1 = waiting for '{' */
- /* 2 = waiting for '}' */
- /* 3 = waiting for ''' */
- char *output_start = output;
-
- debug_parser("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen(input),
- input);
-
- prev = '\0'; /* previous character */
-
- while (inputcnt && outputcnt) {
- c = *input++;
- inputcnt--;
-
- if (state != 3) {
- /* remove one level of escape characters */
- if ((c == '\\') && (prev != '\\')) {
- if (inputcnt-- == 0)
- break;
- prev = c;
- c = *input++;
- }
+
+ if (pass) {
+ **p = c;
+ }
+ ++(*p);
+}
+
+static
+char *process_macros(char *input, char *output)
+{
+ char c, prev, *inp, *outp;
+ const char *varname = NULL;
+
+ for(uint_fast8_t pass = 0; pass < 2; pass++)
+ {
+ uint_fast8_t state = 0; /* 0 = waiting for '$' */
+ /* 1 = waiting for '{' */
+ /* 2 = waiting for '}' */
+ /* 3 = waiting for ''' */
+
+ if (pass == 0) {
+ outp = output;
+ } else {
+ int outputlen = outp - output;
+ outp = xrealloc(output, outputlen);
+ output = outp;
}
- switch (state) {
- case 0: /* Waiting for (unescaped) $ */
- if ((c == '\'') && (prev != '\\')) {
- state = 3;
- break;
- }
- if ((c == '$') && (prev != '\\')) {
- state++;
- } else {
- *(output++) = c;
- outputcnt--;
- }
- break;
- case 1: /* Waiting for ( */
- if (c == '{') {
- state++;
- varname_start = input;
- } else {
- state = 0;
- *(output++) = '$';
- outputcnt--;
-
- if (outputcnt) {
- *(output++) = c;
- outputcnt--;
+ inp = input;
+ prev = '\0'; /* previous character */
+
+ debug_parser("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen(inp),
+ inp);
+
+ while ((c = *inp++) != '\0') {
+
+ if (state != 3) {
+ /* remove one level of escape characters */
+ if ((c == '\\') && (prev != '\\')) {
+ if (*inp == '\0')
+ break;
+ prev = c;
+ c = *inp++;
}
}
- break;
- case 2: /* Waiting for ) */
- if (c == '}') {
- char envname[CONFIG_SYS_ENV_NAMELEN+1], *envval;
- /* Varname # of chars */
- uint_fast8_t envcnt = input - varname_start - 1;
- if (envcnt > CONFIG_SYS_ENV_NAMELEN)
- envcnt = CONFIG_SYS_ENV_NAMELEN;
-
- memcpy(envname, varname_start, envcnt);
- envname[envcnt] = '\0';
-
- /* Get its value */
- envval = getenv(envname);
-
- /* Copy into the line if it exists */
- if (envval != NULL)
- while ((*envval) && outputcnt) {
- *(output++) = *(envval++);
- outputcnt--;
- }
- /* Look for another '$' */
- state = 0;
- }
- break;
- case 3: /* Waiting for ' */
- if ((c == '\'') && (prev != '\\')) {
- state = 0;
- } else {
- *(output++) = c;
- outputcnt--;
+
+ switch (state) {
+ case 0: /* Waiting for (unescaped) $ */
+ if ((c == '\'') && (prev != '\\')) {
+ state = 3;
+ break;
+ }
+ if ((c == '$') && (prev != '\\'))
+ state++;
+ else
+ append_char(pass, &outp, c);
+ break;
+ case 1: /* Waiting for { */
+ if (c == '{') {
+ state++;
+ varname = inp;
+ } else {
+ state = 0;
+ append_char(pass, &outp, '$');
+ append_char(pass, &outp, c);
+ }
+ break;
+ case 2: /* Waiting for } */
+ if (c == '}') {
+ /* Terminate variable name */
+ *(inp-1) = '\0';
+ const char *envval = getenv(varname);
+ *(inp-1) = '}';
+ /* Copy into the line if it exists */
+ if (envval != NULL)
+ while (*envval)
+ append_char(pass, &outp, *(envval++));
+ /* Look for another '$' */
+ state = 0;
+ }
+ break;
+ case 3: /* Waiting for ' */
+ if ((c == '\'') && (prev != '\\'))
+ state = 0;
+ else
+ append_char(pass, &outp, c);
+ break;
}
- break;
+ prev = c;
}
- prev = c;
- }
- if (outputcnt)
- *output = 0;
- else
- *(output - 1) = 0;
+ append_char(pass, &outp, 0);
+ }
debug_parser("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
- strlen(output_start), output_start);
+ strlen(output), output);
+
+ return output;
}
/**
@@ -174,7 +167,7 @@ static int cli_run_command(const char *cmd, int flag)
char *cmdbuf; /* working copy of cmd */
char *token; /* start of token in cmdbuf */
char *sep; /* end of token (separator) in cmdbuf */
- char *finaltoken;
+ char *finaltoken = NULL; /* token after macro expansion */
char *str;
char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */
int argc;
@@ -190,8 +183,7 @@ static int cli_run_command(const char *cmd, int flag)
return -1; /* empty command */
cmdbuf = strdup(cmd);
- finaltoken = xmalloc(CONFIG_SYS_CBSIZE);
- if (!finaltoken)
+ if (!cmdbuf)
return -1; /* not enough memory */
str = cmdbuf;
@@ -231,7 +223,7 @@ static int cli_run_command(const char *cmd, int flag)
debug_parser("token: \"%s\"\n", token);
/* find macros in this token and replace them */
- process_macros(token, finaltoken);
+ finaltoken = process_macros(token, finaltoken);
/* Extract arguments */
argc = cli_parse_line(finaltoken, argv);
diff --git a/avr/debug.c b/avr/debug.c
index 16df702..47b11b0 100644
--- a/avr/debug.c
+++ b/avr/debug.c
@@ -23,7 +23,7 @@ static uint8_t ram_read_byte(const uint8_t *p)
return *p;
}
-void dump_mem(const uint8_t *startaddr, int len,
+void dump_mem(const uint8_t *startaddr, int len,
uint8_t (*readfkt)(const uint8_t *), char *title)
{
uint8_t buf[16];
@@ -33,12 +33,12 @@ void dump_mem(const uint8_t *startaddr, int len,
const uint8_t *addr = (uint8_t *) ((size_t) startaddr & ~0x0f);
len += pre;
uint8_t i;
-
+
if (title && *title) {
printf_P(PSTR("%s\n"),title);
indent = " ";
}
-
+
while (len) {
if (len < 16)
llen = len;
@@ -100,7 +100,7 @@ command_ret_t do_dump_mem(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg
// static const uint8_t *addr;
// static uint16_t length = 128;
uint8_t (*readhow)(const uint8_t *);
-
+
(void) cmdtp; (void) flag;
if (argc < 2)
@@ -108,7 +108,7 @@ command_ret_t do_dump_mem(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg
const uint8_t *addr;
uint16_t length = 128;
-
+
if (strchr(argv[0],'r') != NULL)
readhow = ram_read_byte;
else if (strchr(argv[0],'e') != NULL)
@@ -182,7 +182,7 @@ command_ret_t do_eep_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
/*------------------------------------------------------------------------------*/
-#if 0
+#if 1
struct __freelist {
size_t sz;
@@ -201,6 +201,8 @@ printfreelist(const char * title)
int i;
unsigned int freesum = 0;
+/* TODO: printf_P */
+
if (!__flp) {
printf("%s no free list\n", title ? title : "");
} else {
@@ -215,7 +217,7 @@ printfreelist(const char * title)
freesum += fp1->sz;
}
}
-
+
freesum += (size_t) STACK_POINTER() - __malloc_margin - (size_t) __brkval;
printf("SP: %04x, __brkval: %04x, Total free: %04u\n",