X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fmain.c;h=d97ccd7dd846185650ea632f7844b450e74a1b23;hb=3771c69d78cd1acbfd8c530fbd3b153487cdf70c;hp=758ef8d32b2ba15d025bbf311d539c0b82e4fd6a;hpb=b86d7622b33892b1dafe761a7a9eaeeab9f3816b;p=oweals%2Fu-boot.git diff --git a/common/main.c b/common/main.c index 758ef8d32b..d97ccd7dd8 100644 --- a/common/main.c +++ b/common/main.c @@ -2,6 +2,10 @@ * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * + * Add to readline cmdline-editing by + * (C) Copyright 2005 + * JinHua Luo, GuangDong Linux Center, + * * See file CREDITS for list of people who contributed to this * project. * @@ -30,35 +34,43 @@ #include /* for free() prototype */ #endif -#ifdef CFG_HUSH_PARSER +#ifdef CONFIG_SYS_HUSH_PARSER #include #endif #include -#ifdef CONFIG_SILENT_CONSOLE +#if defined(CONFIG_SILENT_CONSOLE) || defined(CONFIG_POST) || defined(CONFIG_CMDLINE_EDITING) DECLARE_GLOBAL_DATA_PTR; #endif +/* + * Board-specific Platform code can reimplement show_boot_progress () if needed + */ +void inline __show_boot_progress (int val) {} +void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress"))); + #if defined(CONFIG_BOOT_RETRY_TIME) && defined(CONFIG_RESET_TO_RETRY) -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* for do_reset() prototype */ +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); /* for do_reset() prototype */ #endif -extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +#if defined(CONFIG_UPDATE_TFTP) +void update_tftp (void); +#endif /* CONFIG_UPDATE_TFTP */ #define MAX_DELAY_STOP_STR 32 -static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen); -static int parse_line (char *, char *[]); #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) static int abortboot(int); #endif #undef DEBUG_PARSER -char console_buffer[CFG_CBSIZE]; /* console I/O buffer */ +char console_buffer[CONFIG_SYS_CBSIZE + 1]; /* console I/O buffer */ +static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen); static char erase_seq[] = "\b \b"; /* erase sequence */ static char tab_seq[] = " "; /* used to expand TABs */ @@ -89,14 +101,12 @@ static __inline__ int abortboot(int bootdelay) { int abort = 0; uint64_t etime = endtick(bootdelay); - struct - { + struct { char* str; u_int len; int retry; } - delaykey [] = - { + delaykey [] = { { str: getenv ("bootdelaykey"), retry: 1 }, { str: getenv ("bootdelaykey2"), retry: 1 }, { str: getenv ("bootstopkey"), retry: 0 }, @@ -108,16 +118,8 @@ static __inline__ int abortboot(int bootdelay) u_int presskey_max = 0; u_int i; -#ifdef CONFIG_SILENT_CONSOLE - if (gd->flags & GD_FLG_SILENT) { - /* Restore serial console */ - console_assign (stdout, "serial"); - console_assign (stderr, "serial"); - } -#endif - # ifdef CONFIG_AUTOBOOT_PROMPT - printf (CONFIG_AUTOBOOT_PROMPT, bootdelay); + printf(CONFIG_AUTOBOOT_PROMPT); # endif # ifdef CONFIG_AUTOBOOT_DELAY_STR @@ -156,7 +158,19 @@ static __inline__ int abortboot(int bootdelay) /* In order to keep up with incoming data, check timeout only * when catch up. */ - while (!abort && get_ticks() <= etime) { + do { + if (tstc()) { + if (presskey_len < presskey_max) { + presskey [presskey_len ++] = getc(); + } + else { + for (i = 0; i < presskey_max - 1; i ++) + presskey [i] = presskey [i + 1]; + + presskey [i] = getc(); + } + } + for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) { if (delaykey[i].len > 0 && presskey_len >= delaykey[i].len && @@ -176,33 +190,16 @@ static __inline__ int abortboot(int bootdelay) abort = 1; } } + } while (!abort && get_ticks() <= etime); - if (tstc()) { - if (presskey_len < presskey_max) { - presskey [presskey_len ++] = getc(); - } - else { - for (i = 0; i < presskey_max - 1; i ++) - presskey [i] = presskey [i + 1]; - - presskey [i] = getc(); - } - } - } # if DEBUG_BOOTKEYS if (!abort) - puts ("key timeout\n"); + puts("key timeout\n"); # endif #ifdef CONFIG_SILENT_CONSOLE - if (abort) { - /* permanently enable normal console output */ - gd->flags &= ~(GD_FLG_SILENT); - } else if (gd->flags & GD_FLG_SILENT) { - /* Restore silent console */ - console_assign (stdout, "nulldev"); - console_assign (stderr, "nulldev"); - } + if (abort) + gd->flags &= ~GD_FLG_SILENT; #endif return abort; @@ -218,16 +215,8 @@ static __inline__ int abortboot(int bootdelay) { int abort = 0; -#ifdef CONFIG_SILENT_CONSOLE - if (gd->flags & GD_FLG_SILENT) { - /* Restore serial console */ - console_assign (stdout, "serial"); - console_assign (stderr, "serial"); - } -#endif - #ifdef CONFIG_MENUPROMPT - printf(CONFIG_MENUPROMPT, bootdelay); + printf(CONFIG_MENUPROMPT); #else printf("Hit any key to stop autoboot: %2d ", bootdelay); #endif @@ -241,7 +230,7 @@ static __inline__ int abortboot(int bootdelay) if (tstc()) { /* we got a key press */ (void) getc(); /* consume input */ puts ("\b\b\b 0"); - abort = 1; /* don't auto boot */ + abort = 1; /* don't auto boot */ } } #endif @@ -262,23 +251,17 @@ static __inline__ int abortboot(int bootdelay) # endif break; } - udelay (10000); + udelay(10000); } - printf ("\b\b\b%2d ", bootdelay); + printf("\b\b\b%2d ", bootdelay); } - putc ('\n'); + putc('\n'); #ifdef CONFIG_SILENT_CONSOLE - if (abort) { - /* permanently enable normal console output */ - gd->flags &= ~(GD_FLG_SILENT); - } else if (gd->flags & GD_FLG_SILENT) { - /* Restore silent console */ - console_assign (stdout, "nulldev"); - console_assign (stderr, "nulldev"); - } + if (abort) + gd->flags &= ~GD_FLG_SILENT; #endif return abort; @@ -290,8 +273,8 @@ static __inline__ int abortboot(int bootdelay) void main_loop (void) { -#ifndef CFG_HUSH_PARSER - static char lastcommand[CFG_CBSIZE] = { 0, }; +#ifndef CONFIG_SYS_HUSH_PARSER + static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, }; int len; int rc = 1; int flag; @@ -351,10 +334,14 @@ void main_loop (void) } #endif /* CONFIG_VERSION_VARIABLE */ -#ifdef CFG_HUSH_PARSER +#ifdef CONFIG_SYS_HUSH_PARSER u_boot_hush_start (); #endif +#if defined(CONFIG_HUSH_INIT_VAR) + hush_init_var (); +#endif + #ifdef CONFIG_AUTO_COMPLETE install_auto_complete(); #endif @@ -365,7 +352,7 @@ void main_loop (void) int prev = disable_ctrlc(1); /* disable Control C checking */ # endif -# ifndef CFG_HUSH_PARSER +# ifndef CONFIG_SYS_HUSH_PARSER run_command (p, 0); # else parse_string_outer(p, FLAG_PARSE_SEMICOLON | @@ -378,6 +365,10 @@ void main_loop (void) } #endif /* CONFIG_PREBOOT */ +#if defined(CONFIG_UPDATE_TFTP) + update_tftp (); +#endif /* CONFIG_UPDATE_TFTP */ + #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) s = getenv ("bootdelay"); bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; @@ -388,6 +379,12 @@ void main_loop (void) init_cmd_timeout (); # endif /* CONFIG_BOOT_RETRY_TIME */ +#ifdef CONFIG_POST + if (gd->flags & GD_FLG_POSTFAIL) { + s = getenv("failbootcmd"); + } + else +#endif /* CONFIG_POST */ #ifdef CONFIG_BOOTCOUNT_LIMIT if (bootlimit && (bootcount > bootlimit)) { printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n", @@ -405,7 +402,7 @@ void main_loop (void) int prev = disable_ctrlc(1); /* disable Control C checking */ # endif -# ifndef CFG_HUSH_PARSER +# ifndef CONFIG_SYS_HUSH_PARSER run_command (s, 0); # else parse_string_outer(s, FLAG_PARSE_SEMICOLON | @@ -421,7 +418,7 @@ void main_loop (void) if (menukey == CONFIG_MENUKEY) { s = getenv("menucmd"); if (s) { -# ifndef CFG_HUSH_PARSER +# ifndef CONFIG_SYS_HUSH_PARSER run_command (s, 0); # else parse_string_outer(s, FLAG_PARSE_SEMICOLON | @@ -430,19 +427,12 @@ void main_loop (void) } } #endif /* CONFIG_MENUKEY */ -#endif /* CONFIG_BOOTDELAY */ - -#ifdef CONFIG_AMIGAONEG3SE - { - extern void video_banner(void); - video_banner(); - } -#endif +#endif /* CONFIG_BOOTDELAY */ /* * Main Loop for Monitor Command Processing */ -#ifdef CFG_HUSH_PARSER +#ifdef CONFIG_SYS_HUSH_PARSER parse_file_outer(); /* This point is never reached */ for (;;); @@ -456,7 +446,7 @@ void main_loop (void) reset_cmd_timeout(); } #endif - len = readline (CFG_PROMPT); + len = readline (CONFIG_SYS_PROMPT); flag = 0; /* assume no special flags for now */ if (len > 0) @@ -487,12 +477,12 @@ void main_loop (void) lastcommand[0] = 0; } } -#endif /*CFG_HUSH_PARSER*/ +#endif /*CONFIG_SYS_HUSH_PARSER*/ } #ifdef CONFIG_BOOT_RETRY_TIME /*************************************************************************** - * initialise command line timeout + * initialize command line timeout */ void init_cmd_timeout(void) { @@ -516,6 +506,418 @@ void reset_cmd_timeout(void) } #endif +#ifdef CONFIG_CMDLINE_EDITING + +/* + * cmdline-editing related codes from vivi. + * Author: Janghoon Lyu + */ + +#define putnstr(str,n) do { \ + printf ("%.*s", (int)n, str); \ + } while (0) + +#define CTL_CH(c) ((c) - 'a' + 1) +#define CTL_BACKSPACE ('\b') +#define DEL ((char)255) +#define DEL7 ((char)127) +#define CREAD_HIST_CHAR ('!') + +#define getcmd_putch(ch) putc(ch) +#define getcmd_getch() getc() +#define getcmd_cbeep() getcmd_putch('\a') + +#define HIST_MAX 20 +#define HIST_SIZE CONFIG_SYS_CBSIZE + +static int hist_max = 0; +static int hist_add_idx = 0; +static int hist_cur = -1; +unsigned hist_num = 0; + +char* hist_list[HIST_MAX]; +char hist_lines[HIST_MAX][HIST_SIZE + 1]; /* Save room for NULL */ + +#define add_idx_minus_one() ((hist_add_idx == 0) ? hist_max : hist_add_idx-1) + +static void hist_init(void) +{ + int i; + + hist_max = 0; + hist_add_idx = 0; + hist_cur = -1; + hist_num = 0; + + for (i = 0; i < HIST_MAX; i++) { + hist_list[i] = hist_lines[i]; + hist_list[i][0] = '\0'; + } +} + +static void cread_add_to_hist(char *line) +{ + strcpy(hist_list[hist_add_idx], line); + + if (++hist_add_idx >= HIST_MAX) + hist_add_idx = 0; + + if (hist_add_idx > hist_max) + hist_max = hist_add_idx; + + hist_num++; +} + +static char* hist_prev(void) +{ + char *ret; + int old_cur; + + if (hist_cur < 0) + return NULL; + + old_cur = hist_cur; + if (--hist_cur < 0) + hist_cur = hist_max; + + if (hist_cur == hist_add_idx) { + hist_cur = old_cur; + ret = NULL; + } else + ret = hist_list[hist_cur]; + + return (ret); +} + +static char* hist_next(void) +{ + char *ret; + + if (hist_cur < 0) + return NULL; + + if (hist_cur == hist_add_idx) + return NULL; + + if (++hist_cur > hist_max) + hist_cur = 0; + + if (hist_cur == hist_add_idx) { + ret = ""; + } else + ret = hist_list[hist_cur]; + + return (ret); +} + +#ifndef CONFIG_CMDLINE_EDITING +static void cread_print_hist_list(void) +{ + int i; + unsigned long n; + + n = hist_num - hist_max; + + i = hist_add_idx + 1; + while (1) { + if (i > hist_max) + i = 0; + if (i == hist_add_idx) + break; + printf("%s\n", hist_list[i]); + n++; + i++; + } +} +#endif /* CONFIG_CMDLINE_EDITING */ + +#define BEGINNING_OF_LINE() { \ + while (num) { \ + getcmd_putch(CTL_BACKSPACE); \ + num--; \ + } \ +} + +#define ERASE_TO_EOL() { \ + if (num < eol_num) { \ + printf("%*s", (int)(eol_num - num), ""); \ + do { \ + getcmd_putch(CTL_BACKSPACE); \ + } while (--eol_num > num); \ + } \ +} + +#define REFRESH_TO_EOL() { \ + if (num < eol_num) { \ + wlen = eol_num - num; \ + putnstr(buf + num, wlen); \ + num = eol_num; \ + } \ +} + +static void cread_add_char(char ichar, int insert, unsigned long *num, + unsigned long *eol_num, char *buf, unsigned long len) +{ + unsigned long wlen; + + /* room ??? */ + if (insert || *num == *eol_num) { + if (*eol_num > len - 1) { + getcmd_cbeep(); + return; + } + (*eol_num)++; + } + + if (insert) { + wlen = *eol_num - *num; + if (wlen > 1) { + memmove(&buf[*num+1], &buf[*num], wlen-1); + } + + buf[*num] = ichar; + putnstr(buf + *num, wlen); + (*num)++; + while (--wlen) { + getcmd_putch(CTL_BACKSPACE); + } + } else { + /* echo the character */ + wlen = 1; + buf[*num] = ichar; + putnstr(buf + *num, wlen); + (*num)++; + } +} + +static void cread_add_str(char *str, int strsize, int insert, unsigned long *num, + unsigned long *eol_num, char *buf, unsigned long len) +{ + while (strsize--) { + cread_add_char(*str, insert, num, eol_num, buf, len); + str++; + } +} + +static int cread_line(const char *const prompt, char *buf, unsigned int *len) +{ + unsigned long num = 0; + unsigned long eol_num = 0; + unsigned long wlen; + char ichar; + int insert = 1; + int esc_len = 0; + char esc_save[8]; + int init_len = strlen(buf); + + if (init_len) + cread_add_str(buf, init_len, 1, &num, &eol_num, buf, *len); + + while (1) { +#ifdef CONFIG_BOOT_RETRY_TIME + while (!tstc()) { /* while no incoming data */ + if (retry_time >= 0 && get_ticks() > endtime) + return (-2); /* timed out */ + WATCHDOG_RESET(); + } +#endif + + ichar = getcmd_getch(); + + if ((ichar == '\n') || (ichar == '\r')) { + putc('\n'); + break; + } + + /* + * handle standard linux xterm esc sequences for arrow key, etc. + */ + if (esc_len != 0) { + if (esc_len == 1) { + if (ichar == '[') { + esc_save[esc_len] = ichar; + esc_len = 2; + } else { + cread_add_str(esc_save, esc_len, insert, + &num, &eol_num, buf, *len); + esc_len = 0; + } + continue; + } + + switch (ichar) { + + case 'D': /* <- key */ + ichar = CTL_CH('b'); + esc_len = 0; + break; + case 'C': /* -> key */ + ichar = CTL_CH('f'); + esc_len = 0; + break; /* pass off to ^F handler */ + case 'H': /* Home key */ + ichar = CTL_CH('a'); + esc_len = 0; + break; /* pass off to ^A handler */ + case 'A': /* up arrow */ + ichar = CTL_CH('p'); + esc_len = 0; + break; /* pass off to ^P handler */ + case 'B': /* down arrow */ + ichar = CTL_CH('n'); + esc_len = 0; + break; /* pass off to ^N handler */ + default: + esc_save[esc_len++] = ichar; + cread_add_str(esc_save, esc_len, insert, + &num, &eol_num, buf, *len); + esc_len = 0; + continue; + } + } + + switch (ichar) { + case 0x1b: + if (esc_len == 0) { + esc_save[esc_len] = ichar; + esc_len = 1; + } else { + puts("impossible condition #876\n"); + esc_len = 0; + } + break; + + case CTL_CH('a'): + BEGINNING_OF_LINE(); + break; + case CTL_CH('c'): /* ^C - break */ + *buf = '\0'; /* discard input */ + return (-1); + case CTL_CH('f'): + if (num < eol_num) { + getcmd_putch(buf[num]); + num++; + } + break; + case CTL_CH('b'): + if (num) { + getcmd_putch(CTL_BACKSPACE); + num--; + } + break; + case CTL_CH('d'): + if (num < eol_num) { + wlen = eol_num - num - 1; + if (wlen) { + memmove(&buf[num], &buf[num+1], wlen); + putnstr(buf + num, wlen); + } + + getcmd_putch(' '); + do { + getcmd_putch(CTL_BACKSPACE); + } while (wlen--); + eol_num--; + } + break; + case CTL_CH('k'): + ERASE_TO_EOL(); + break; + case CTL_CH('e'): + REFRESH_TO_EOL(); + break; + case CTL_CH('o'): + insert = !insert; + break; + case CTL_CH('x'): + case CTL_CH('u'): + BEGINNING_OF_LINE(); + ERASE_TO_EOL(); + break; + case DEL: + case DEL7: + case 8: + if (num) { + wlen = eol_num - num; + num--; + memmove(&buf[num], &buf[num+1], wlen); + getcmd_putch(CTL_BACKSPACE); + putnstr(buf + num, wlen); + getcmd_putch(' '); + do { + getcmd_putch(CTL_BACKSPACE); + } while (wlen--); + eol_num--; + } + break; + case CTL_CH('p'): + case CTL_CH('n'): + { + char * hline; + + esc_len = 0; + + if (ichar == CTL_CH('p')) + hline = hist_prev(); + else + hline = hist_next(); + + if (!hline) { + getcmd_cbeep(); + continue; + } + + /* nuke the current line */ + /* first, go home */ + BEGINNING_OF_LINE(); + + /* erase to end of line */ + ERASE_TO_EOL(); + + /* copy new line into place and display */ + strcpy(buf, hline); + eol_num = strlen(buf); + REFRESH_TO_EOL(); + continue; + } +#ifdef CONFIG_AUTO_COMPLETE + case '\t': { + int num2, col; + + /* do not autocomplete when in the middle */ + if (num < eol_num) { + getcmd_cbeep(); + break; + } + + buf[num] = '\0'; + col = strlen(prompt) + eol_num; + num2 = num; + if (cmd_auto_complete(prompt, buf, &num2, &col)) { + col = num2 - num; + num += col; + eol_num += col; + } + break; + } +#endif + default: + cread_add_char(ichar, insert, &num, &eol_num, buf, *len); + break; + } + } + *len = eol_num; + buf[eol_num] = '\0'; /* lose the newline */ + + if (buf[0] && buf[0] != CREAD_HIST_CHAR) + cread_add_to_hist(buf); + hist_cur = hist_add_idx; + + return 0; +} + +#endif /* CONFIG_CMDLINE_EDITING */ + /****************************************************************************/ /* @@ -528,7 +930,45 @@ void reset_cmd_timeout(void) */ int readline (const char *const prompt) { - char *p = console_buffer; + /* + * If console_buffer isn't 0-length the user will be prompted to modify + * it instead of entering it from scratch as desired. + */ + console_buffer[0] = '\0'; + + return readline_into_buffer(prompt, console_buffer); +} + + +int readline_into_buffer (const char *const prompt, char * buffer) +{ + char *p = buffer; +#ifdef CONFIG_CMDLINE_EDITING + unsigned int len = CONFIG_SYS_CBSIZE; + int rc; + static int initted = 0; + + /* + * History uses a global array which is not + * writable until after relocation to RAM. + * Revert to non-history version if still + * running from flash. + */ + if (gd->flags & GD_FLG_RELOC) { + if (!initted) { + hist_init(); + initted = 1; + } + + if (prompt) + puts (prompt); + + rc = cread_line(prompt, p, &len); + return rc < 0 ? rc : len; + + } else { +#endif /* CONFIG_CMDLINE_EDITING */ + char * p_buf = p; int n = 0; /* buffer index */ int plen = 0; /* prompt length */ int col; /* output column cnt */ @@ -546,6 +986,7 @@ int readline (const char *const prompt) while (!tstc()) { /* while no incoming data */ if (retry_time >= 0 && get_ticks() > endtime) return (-2); /* timed out */ + WATCHDOG_RESET(); } #endif WATCHDOG_RESET(); /* Trigger watchdog, if needed */ @@ -554,6 +995,7 @@ int readline (const char *const prompt) while (!tstc()) { extern void show_activity(int arg); show_activity(0); + WATCHDOG_RESET(); } #endif c = getc(); @@ -566,13 +1008,13 @@ int readline (const char *const prompt) case '\n': *p = '\0'; puts ("\r\n"); - return (p - console_buffer); + return (p - p_buf); case '\0': /* nul */ continue; case 0x03: /* ^C - break */ - console_buffer[0] = '\0'; /* discard input */ + p_buf[0] = '\0'; /* discard input */ return (-1); case 0x15: /* ^U - erase line */ @@ -580,33 +1022,33 @@ int readline (const char *const prompt) puts (erase_seq); --col; } - p = console_buffer; + p = p_buf; n = 0; continue; - case 0x17: /* ^W - erase word */ - p=delete_char(console_buffer, p, &col, &n, plen); + case 0x17: /* ^W - erase word */ + p=delete_char(p_buf, p, &col, &n, plen); while ((n > 0) && (*p != ' ')) { - p=delete_char(console_buffer, p, &col, &n, plen); + p=delete_char(p_buf, p, &col, &n, plen); } continue; case 0x08: /* ^H - backspace */ case 0x7F: /* DEL - backspace */ - p=delete_char(console_buffer, p, &col, &n, plen); + p=delete_char(p_buf, p, &col, &n, plen); continue; default: /* * Must be a normal character then */ - if (n < CFG_CBSIZE-2) { + if (n < CONFIG_SYS_CBSIZE-2) { if (c == '\t') { /* expand TABs */ #ifdef CONFIG_AUTO_COMPLETE /* if auto completion triggered just continue */ *p = '\0'; if (cmd_auto_complete(prompt, console_buffer, &n, &col)) { - p = console_buffer + n; /* reset */ + p = p_buf + n; /* reset */ continue; } #endif @@ -623,6 +1065,9 @@ int readline (const char *const prompt) } } } +#ifdef CONFIG_CMDLINE_EDITING + } +#endif } /****************************************************************************/ @@ -666,7 +1111,7 @@ int parse_line (char *line, char *argv[]) #ifdef DEBUG_PARSER printf ("parse_line: \"%s\"\n", line); #endif - while (nargs < CFG_MAXARGS) { + while (nargs < CONFIG_SYS_MAXARGS) { /* skip any white space */ while ((*line == ' ') || (*line == '\t')) { @@ -699,7 +1144,7 @@ int parse_line (char *line, char *argv[]) *line++ = '\0'; /* terminate current arg */ } - printf ("** Too many args (max. %d) **\n", CFG_MAXARGS); + printf ("** Too many args (max. %d) **\n", CONFIG_SYS_MAXARGS); #ifdef DEBUG_PARSER printf ("parse_line: nargs=%d\n", nargs); @@ -713,105 +1158,109 @@ static void process_macros (const char *input, char *output) { char c, prev; const char *varname_start = NULL; - int inputcnt = strlen (input); - int outputcnt = CFG_CBSIZE; - int state = 0; /* 0 = waiting for '$' */ - /* 1 = waiting for '(' or '{' */ - /* 2 = waiting for ')' or '}' */ - /* 3 = waiting for ''' */ + int inputcnt = strlen (input); + int outputcnt = CONFIG_SYS_CBSIZE; + int state = 0; /* 0 = waiting for '$' */ + + /* 1 = waiting for '(' or '{' */ + /* 2 = waiting for ')' or '}' */ + /* 3 = waiting for ''' */ #ifdef DEBUG_PARSER char *output_start = output; - printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen(input), input); + printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input), + input); #endif - prev = '\0'; /* previous character */ + 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++; - } - } - - switch (state) { - case 0: /* Waiting for (unescaped) $ */ - if ((c == '\'') && (prev != '\\')) { - state = 3; - break; + inputcnt--; + + if (state != 3) { + /* remove one level of escape characters */ + if ((c == '\\') && (prev != '\\')) { + if (inputcnt-- == 0) + break; + prev = c; + c = *input++; + } } - if ((c == '$') && (prev != '\\')) { - state++; - } else { - *(output++) = c; - outputcnt--; - } - break; - case 1: /* Waiting for ( */ - if (c == '(' || c == '{') { - state++; - varname_start = input; - } else { - state = 0; - *(output++) = '$'; - outputcnt--; - - if (outputcnt) { + + switch (state) { + case 0: /* Waiting for (unescaped) $ */ + if ((c == '\'') && (prev != '\\')) { + state = 3; + break; + } + if ((c == '$') && (prev != '\\')) { + state++; + } else { *(output++) = c; outputcnt--; } - } - break; - case 2: /* Waiting for ) */ - if (c == ')' || c == '}') { - int i; - char envname[CFG_CBSIZE], *envval; - int envcnt = input-varname_start-1; /* Varname # of chars */ + break; + case 1: /* Waiting for ( */ + if (c == '(' || c == '{') { + state++; + varname_start = input; + } else { + state = 0; + *(output++) = '$'; + outputcnt--; - /* Get the varname */ - for (i = 0; i < envcnt; i++) { - envname[i] = varname_start[i]; + if (outputcnt) { + *(output++) = c; + outputcnt--; + } } - envname[i] = 0; + break; + case 2: /* Waiting for ) */ + if (c == ')' || c == '}') { + int i; + char envname[CONFIG_SYS_CBSIZE], *envval; + int envcnt = input - varname_start - 1; /* Varname # of chars */ + + /* Get the varname */ + for (i = 0; i < envcnt; i++) { + envname[i] = varname_start[i]; + } + envname[i] = 0; - /* Get its value */ - envval = getenv (envname); + /* 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--; - } - break; - } - prev = c; + /* 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--; + } + break; + } + prev = c; } if (outputcnt) *output = 0; + else + *(output - 1) = 0; #ifdef DEBUG_PARSER printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n", - strlen(output_start), output_start); + strlen (output_start), output_start); #endif } @@ -821,7 +1270,7 @@ static void process_macros (const char *input, char *output) * 0 - command executed but not repeatable, interrupted commands are * always considered not repeatable * -1 - not executed (unrecognized, bootd recursion or too many args) - * (If cmd is NULL or "" or longer than CFG_CBSIZE-1 it is + * (If cmd is NULL or "" or longer than CONFIG_SYS_CBSIZE-1 it is * considered unrecognized) * * WARNING: @@ -835,12 +1284,12 @@ static void process_macros (const char *input, char *output) int run_command (const char *cmd, int flag) { cmd_tbl_t *cmdtp; - char cmdbuf[CFG_CBSIZE]; /* working copy of cmd */ + char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd */ char *token; /* start of token in cmdbuf */ char *sep; /* end of token (separator) in cmdbuf */ - char finaltoken[CFG_CBSIZE]; + char finaltoken[CONFIG_SYS_CBSIZE]; char *str = cmdbuf; - char *argv[CFG_MAXARGS + 1]; /* NULL terminated */ + char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ int argc, inquotes; int repeatable = 1; int rc = 0; @@ -857,7 +1306,7 @@ int run_command (const char *cmd, int flag) return -1; /* empty command */ } - if (strlen(cmd) >= CFG_CBSIZE) { + if (strlen(cmd) >= CONFIG_SYS_CBSIZE) { puts ("## Command too long!\n"); return -1; } @@ -921,12 +1370,12 @@ int run_command (const char *cmd, int flag) /* found - check max args */ if (argc > cmdtp->maxargs) { - printf ("Usage:\n%s\n", cmdtp->usage); + cmd_usage(cmdtp); rc = -1; continue; } -#if (CONFIG_COMMANDS & CFG_CMD_BOOTD) +#if defined(CONFIG_CMD_BOOTD) /* avoid "bootd" recursion */ if (cmdtp->cmd == do_bootd) { #ifdef DEBUG_PARSER @@ -940,7 +1389,7 @@ int run_command (const char *cmd, int flag) flag |= CMD_FLAG_BOOTD; } } -#endif /* CFG_CMD_BOOTD */ +#endif /* OK - call function to do the command */ if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) { @@ -951,7 +1400,7 @@ int run_command (const char *cmd, int flag) /* Did the user stop this? */ if (had_ctrlc ()) - return 0; /* if stopped then not repeatable */ + return -1; /* if stopped then not repeatable */ } return rc ? rc : repeatable; @@ -959,15 +1408,13 @@ int run_command (const char *cmd, int flag) /****************************************************************************/ -#if (CONFIG_COMMANDS & CFG_CMD_RUN) -int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +#if defined(CONFIG_CMD_RUN) +int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { int i; - if (argc < 2) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } + if (argc < 2) + return cmd_usage(cmdtp); for (i=1; i