diff --git a/ChangeLog b/ChangeLog index 9e9d35ab0..89b0bb3fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-07 Vladimir Serbinenko + + * grub-core/normal/cmdline.c (grub_cmdline_get): + Remove nested functions. + 2013-11-07 Vladimir Serbinenko * tests/test_sha512sum.in: Make it work on emu. diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c index f7cd115d7..2ef500ffb 100644 --- a/grub-core/normal/cmdline.c +++ b/grub-core/normal/cmdline.c @@ -212,6 +212,128 @@ struct cmdline_term struct grub_term_output *term; }; +static inline void +cl_set_pos (struct cmdline_term *cl_term, grub_size_t lpos) +{ + cl_term->pos.x = (cl_term->prompt_len + lpos) % cl_term->width; + cl_term->pos.y = cl_term->ystart + + (cl_term->prompt_len + lpos) / cl_term->width; + grub_term_gotoxy (cl_term->term, cl_term->pos); +} + +static void +cl_set_pos_all (struct cmdline_term *cl_terms, unsigned nterms, + grub_size_t lpos) +{ + unsigned i; + for (i = 0; i < nterms; i++) + cl_set_pos (&cl_terms[i], lpos); +} + +static inline void __attribute__ ((always_inline)) +cl_print (struct cmdline_term *cl_term, grub_uint32_t c, + grub_uint32_t *start, grub_uint32_t *end) +{ + grub_uint32_t *p; + + for (p = start; p < end; p++) + { + if (c) + grub_putcode (c, cl_term->term); + else + grub_putcode (*p, cl_term->term); + cl_term->pos.x++; + if (cl_term->pos.x >= cl_term->width - 1) + { + cl_term->pos.x = 0; + if (cl_term->pos.y >= (unsigned) (cl_term->height - 1)) + cl_term->ystart--; + else + cl_term->pos.y++; + grub_putcode ('\n', cl_term->term); + } + } +} + +static void +cl_print_all (struct cmdline_term *cl_terms, unsigned nterms, + grub_uint32_t c, grub_uint32_t *start, grub_uint32_t *end) +{ + unsigned i; + for (i = 0; i < nterms; i++) + cl_print (&cl_terms[i], c, start, end); +} + +static void +init_clterm (struct cmdline_term *cl_term_cur) +{ + cl_term_cur->pos.x = cl_term_cur->prompt_len; + cl_term_cur->pos.y = grub_term_getxy (cl_term_cur->term).y; + cl_term_cur->ystart = cl_term_cur->pos.y; + cl_term_cur->width = grub_term_width (cl_term_cur->term); + cl_term_cur->height = grub_term_height (cl_term_cur->term); +} + + +static void +cl_delete (struct cmdline_term *cl_terms, unsigned nterms, + grub_uint32_t *buf, + grub_size_t lpos, grub_size_t *llen, unsigned len) +{ + if (lpos + len <= (*llen)) + { + cl_set_pos_all (cl_terms, nterms, (*llen) - len); + cl_print_all (cl_terms, nterms, ' ', buf + (*llen) - len, buf + (*llen)); + + cl_set_pos_all (cl_terms, nterms, lpos); + + grub_memmove (buf + lpos, buf + lpos + len, + sizeof (grub_uint32_t) * ((*llen) - lpos + 1)); + (*llen) -= len; + cl_print_all (cl_terms, nterms, 0, buf + lpos, buf + (*llen)); + cl_set_pos_all (cl_terms, nterms, lpos); + } +} + + +static void +cl_insert (struct cmdline_term *cl_terms, unsigned nterms, + grub_size_t *lpos, grub_size_t *llen, + grub_size_t *max_len, grub_uint32_t **buf, + const grub_uint32_t *str) +{ + grub_size_t len = strlen_ucs4 (str); + + if (len + (*llen) >= (*max_len)) + { + grub_uint32_t *nbuf; + (*max_len) *= 2; + nbuf = grub_realloc ((*buf), sizeof (grub_uint32_t) * (*max_len)); + if (nbuf) + (*buf) = nbuf; + else + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + (*max_len) /= 2; + } + } + + if (len + (*llen) < (*max_len)) + { + grub_memmove ((*buf) + (*lpos) + len, (*buf) + (*lpos), + ((*llen) - (*lpos) + 1) * sizeof (grub_uint32_t)); + grub_memmove ((*buf) + (*lpos), str, len * sizeof (grub_uint32_t)); + + (*llen) += len; + cl_set_pos_all (cl_terms, nterms, (*lpos)); + cl_print_all (cl_terms, nterms, 0, *buf + (*lpos), *buf + (*llen)); + (*lpos) += len; + cl_set_pos_all (cl_terms, nterms, (*lpos)); + } +} + + /* Get a command-line. If ESC is pushed, return zero, otherwise return command line. */ /* FIXME: The dumb interface is not supported yet. */ @@ -223,133 +345,10 @@ grub_cmdline_get (const char *prompt_translated) grub_size_t max_len = 256; int key; int histpos = 0; - auto void cl_insert (const grub_uint32_t *str); - auto void cl_delete (unsigned len); - auto inline void __attribute__ ((always_inline)) cl_print (struct cmdline_term *cl_term, int pos, - grub_uint32_t c); - auto void cl_set_pos (struct cmdline_term *cl_term); - auto void cl_print_all (int pos, grub_uint32_t c); - auto void cl_set_pos_all (void); - auto void init_clterm (struct cmdline_term *cl_term_cur); - auto void init_clterm_all (void); struct cmdline_term *cl_terms; char *ret; unsigned nterms; - void cl_set_pos (struct cmdline_term *cl_term) - { - cl_term->pos.x = (cl_term->prompt_len + lpos) % cl_term->width; - cl_term->pos.y = cl_term->ystart - + (cl_term->prompt_len + lpos) / cl_term->width; - grub_term_gotoxy (cl_term->term, cl_term->pos); - } - - void cl_set_pos_all (void) - { - unsigned i; - for (i = 0; i < nterms; i++) - cl_set_pos (&cl_terms[i]); - } - - inline void __attribute__ ((always_inline)) cl_print (struct cmdline_term *cl_term, int pos, grub_uint32_t c) - { - grub_uint32_t *p; - - for (p = buf + pos; p < buf + llen; p++) - { - if (c) - grub_putcode (c, cl_term->term); - else - grub_putcode (*p, cl_term->term); - cl_term->pos.x++; - if (cl_term->pos.x >= cl_term->width - 1) - { - cl_term->pos.x = 0; - if (cl_term->pos.y >= (unsigned) (cl_term->height - 1)) - cl_term->ystart--; - else - cl_term->pos.y++; - grub_putcode ('\n', cl_term->term); - } - } - } - - void cl_print_all (int pos, grub_uint32_t c) - { - unsigned i; - for (i = 0; i < nterms; i++) - cl_print (&cl_terms[i], pos, c); - } - - void cl_insert (const grub_uint32_t *str) - { - grub_size_t len = strlen_ucs4 (str); - - if (len + llen >= max_len) - { - grub_uint32_t *nbuf; - max_len *= 2; - nbuf = grub_realloc (buf, sizeof (grub_uint32_t) * max_len); - if (nbuf) - buf = nbuf; - else - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - max_len /= 2; - } - } - - if (len + llen < max_len) - { - grub_memmove (buf + lpos + len, buf + lpos, - (llen - lpos + 1) * sizeof (grub_uint32_t)); - grub_memmove (buf + lpos, str, len * sizeof (grub_uint32_t)); - - llen += len; - cl_set_pos_all (); - cl_print_all (lpos, 0); - lpos += len; - cl_set_pos_all (); - } - } - - void cl_delete (unsigned len) - { - if (lpos + len <= llen) - { - grub_size_t saved_lpos = lpos; - - lpos = llen - len; - cl_set_pos_all (); - cl_print_all (lpos, ' '); - lpos = saved_lpos; - cl_set_pos_all (); - - grub_memmove (buf + lpos, buf + lpos + len, - sizeof (grub_uint32_t) * (llen - lpos + 1)); - llen -= len; - cl_print_all (lpos, 0); - cl_set_pos_all (); - } - } - - void init_clterm (struct cmdline_term *cl_term_cur) - { - cl_term_cur->pos.x = cl_term_cur->prompt_len; - cl_term_cur->pos.y = grub_term_getxy (cl_term_cur->term).y; - cl_term_cur->ystart = cl_term_cur->pos.y; - cl_term_cur->width = grub_term_width (cl_term_cur->term); - cl_term_cur->height = grub_term_height (cl_term_cur->term); - } - - void init_clterm_all (void) - { - unsigned i; - for (i = 0; i < nterms; i++) - init_clterm (&cl_terms[i]); - } - buf = grub_malloc (max_len * sizeof (grub_uint32_t)); if (!buf) return 0; @@ -414,7 +413,7 @@ grub_cmdline_get (const char *prompt_translated) case GRUB_TERM_CTRL | 'a': case GRUB_TERM_KEY_HOME: lpos = 0; - cl_set_pos_all (); + cl_set_pos_all (cl_terms, nterms, lpos); break; case GRUB_TERM_CTRL | 'b': @@ -422,14 +421,14 @@ grub_cmdline_get (const char *prompt_translated) if (lpos > 0) { lpos--; - cl_set_pos_all (); + cl_set_pos_all (cl_terms, nterms, lpos); } break; case GRUB_TERM_CTRL | 'e': case GRUB_TERM_KEY_END: lpos = llen; - cl_set_pos_all (); + cl_set_pos_all (cl_terms, nterms, lpos); break; case GRUB_TERM_CTRL | 'f': @@ -437,7 +436,7 @@ grub_cmdline_get (const char *prompt_translated) if (lpos < llen) { lpos++; - cl_set_pos_all (); + cl_set_pos_all (cl_terms, nterms, lpos); } break; @@ -469,12 +468,17 @@ grub_cmdline_get (const char *prompt_translated) if (restore) { + unsigned i; + /* Restore the prompt. */ grub_xputs ("\n"); grub_xputs (prompt_translated); grub_xputs (" "); - init_clterm_all (); - cl_print_all (0, 0); + + for (i = 0; i < nterms; i++) + init_clterm (&cl_terms[i]); + + cl_print_all (cl_terms, nterms, 0, buf, buf + llen); } if (insertu8) @@ -501,20 +505,20 @@ grub_cmdline_get (const char *prompt_translated) { insert[t-1] = 0; if (t != 1) - cl_insert (insert); + cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, insert); lpos++; } else { insert[t] = 0; - cl_insert (insert); + cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, insert); } } grub_free (insertu8); grub_free (insert); } - cl_set_pos_all (); + cl_set_pos_all (cl_terms, nterms, lpos); } break; @@ -537,7 +541,8 @@ grub_cmdline_get (const char *prompt_translated) kill_buf[llen - lpos] = 0; } - cl_delete (llen - lpos); + cl_delete (cl_terms, nterms, + buf, lpos, &llen, llen - lpos); } break; @@ -554,9 +559,10 @@ grub_cmdline_get (const char *prompt_translated) histpos--; } - cl_delete (llen); + cl_delete (cl_terms, nterms, + buf, lpos, &llen, llen); hist = grub_history_get (histpos); - cl_insert (hist); + cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, hist); break; } @@ -574,10 +580,11 @@ grub_cmdline_get (const char *prompt_translated) histpos++; } - cl_delete (llen); + cl_delete (cl_terms, nterms, + buf, lpos, &llen, llen); hist = grub_history_get (histpos); - cl_insert (hist); + cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, hist); } break; @@ -601,14 +608,15 @@ grub_cmdline_get (const char *prompt_translated) } lpos = 0; - cl_set_pos_all (); - cl_delete (n); + cl_set_pos_all (cl_terms, nterms, lpos); + cl_delete (cl_terms, nterms, + buf, lpos, &llen, n); } break; case GRUB_TERM_CTRL | 'y': if (kill_buf) - cl_insert (kill_buf); + cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, kill_buf); break; case '\e': @@ -619,7 +627,7 @@ grub_cmdline_get (const char *prompt_translated) if (lpos > 0) { lpos--; - cl_set_pos_all (); + cl_set_pos_all (cl_terms, nterms, lpos); } else break; @@ -628,7 +636,8 @@ grub_cmdline_get (const char *prompt_translated) case GRUB_TERM_CTRL | 'd': case GRUB_TERM_KEY_DC: if (lpos < llen) - cl_delete (1); + cl_delete (cl_terms, nterms, + buf, lpos, &llen, 1); break; default: @@ -638,7 +647,7 @@ grub_cmdline_get (const char *prompt_translated) str[0] = key; str[1] = '\0'; - cl_insert (str); + cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, str); } break; }