X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=src%2Flib%2Fcmdline_rdline.c;h=d5eac3b42fda46f130e2e9d71473f87ed6b5b915;hb=c39d452741fe5b6c771bb655fa0c827a064f4460;hp=287c7d8d7b63ffa78175dc55664e5e9b4f526ea7;hpb=6f32a68393e01b4179592b9f48255179e8ad55f7;p=libcmdline.git diff --git a/src/lib/cmdline_rdline.c b/src/lib/cmdline_rdline.c index 287c7d8..d5eac3b 100644 --- a/src/lib/cmdline_rdline.c +++ b/src/lib/cmdline_rdline.c @@ -1,3 +1,37 @@ +/*- + * Copyright (c) <2010>, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * - Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + /* * Copyright (c) 2009, Olivier MATZ * All rights reserved. @@ -36,7 +70,7 @@ #include "cmdline_rdline.h" static void rdline_puts(struct rdline *rdl, const char *buf); -static void rdline_miniprintf(struct rdline *rdl, +static void rdline_miniprintf(struct rdline *rdl, const char *buf, unsigned int val); #ifndef NO_RDLINE_HISTORY @@ -51,13 +85,14 @@ static unsigned int rdline_get_history_size(struct rdline *rdl); static int isblank2(char c) { - if (c == ' ' || + if (c == ' ' || c == '\t' ) return 1; return 0; } -void rdline_init(struct rdline *rdl, +void +rdline_init(struct rdline *rdl, rdline_write_char_t *write_char, rdline_validate_t *validate, rdline_complete_t *complete) @@ -89,17 +124,23 @@ rdline_newline(struct rdline *rdl, const char *prompt) rdl->write_char(rdl, rdl->prompt[i]); rdl->status = RDLINE_RUNNING; -#ifndef NO_RDLINE_HISTORY +#ifndef NO_RDLINE_HISTORY rdl->history_cur_line = -1; #endif /* !NO_RDLINE_HISTORY */ } -void +void rdline_stop(struct rdline *rdl) { rdl->status = RDLINE_INIT; } +void +rdline_quit(struct rdline *rdl) +{ + rdl->status = RDLINE_EXITED; +} + void rdline_restart(struct rdline *rdl) { @@ -133,12 +174,13 @@ display_right_buffer(struct rdline *rdl) CIRBUF_FOREACH(&rdl->right, i, tmp) { rdl->write_char(rdl, tmp); } - rdline_miniprintf(rdl, vt100_multi_left, + rdline_miniprintf(rdl, vt100_multi_left, CIRBUF_GET_LEN(&rdl->right)); } } -void rdline_redisplay(struct rdline *rdl) +void +rdline_redisplay(struct rdline *rdl) { unsigned int i; char tmp; @@ -161,13 +203,15 @@ rdline_char_in(struct rdline *rdl, char c) #ifndef NO_RDLINE_HISTORY char *buf; #endif - + + if (rdl->status == RDLINE_EXITED) + return RDLINE_RES_EXITED; if (rdl->status != RDLINE_RUNNING) - return -1; + return RDLINE_RES_NOT_RUNNING; cmd = vt100_parser(&rdl->vt100, c); if (cmd == -2) - return 0; + return RDLINE_RES_SUCCESS; if (cmd >= 0) { switch (cmd) { @@ -192,37 +236,37 @@ rdline_char_in(struct rdline *rdl, char c) break; case CMDLINE_KEY_WLEFT: - while (! CIRBUF_IS_EMPTY(&rdl->left) && - (tmp = cirbuf_get_tail(&rdl->left)) && + while (! CIRBUF_IS_EMPTY(&rdl->left) && + (tmp = cirbuf_get_tail(&rdl->left)) && isblank2(tmp)) { rdline_puts(rdl, vt100_left_arr); cirbuf_del_tail(&rdl->left); cirbuf_add_head(&rdl->right, tmp); } - while (! CIRBUF_IS_EMPTY(&rdl->left) && - (tmp = cirbuf_get_tail(&rdl->left)) && + while (! CIRBUF_IS_EMPTY(&rdl->left) && + (tmp = cirbuf_get_tail(&rdl->left)) && !isblank2(tmp)) { rdline_puts(rdl, vt100_left_arr); cirbuf_del_tail(&rdl->left); cirbuf_add_head(&rdl->right, tmp); - } + } break; case CMDLINE_KEY_WRIGHT: - while (! CIRBUF_IS_EMPTY(&rdl->right) && - (tmp = cirbuf_get_head(&rdl->right)) && + while (! CIRBUF_IS_EMPTY(&rdl->right) && + (tmp = cirbuf_get_head(&rdl->right)) && isblank2(tmp)) { rdline_puts(rdl, vt100_right_arr); cirbuf_del_head(&rdl->right); cirbuf_add_tail(&rdl->left, tmp); } - while (! CIRBUF_IS_EMPTY(&rdl->right) && - (tmp = cirbuf_get_head(&rdl->right)) && + while (! CIRBUF_IS_EMPTY(&rdl->right) && + (tmp = cirbuf_get_head(&rdl->right)) && !isblank2(tmp)) { rdline_puts(rdl, vt100_right_arr); cirbuf_del_head(&rdl->right); cirbuf_add_tail(&rdl->left, tmp); - } + } break; case CMDLINE_KEY_BKSPACE: @@ -246,10 +290,10 @@ rdline_char_in(struct rdline *rdl, char c) case CMDLINE_KEY_SUPPR: case CMDLINE_KEY_CTRL_D: - if (cmd == CMDLINE_KEY_CTRL_D && + if (cmd == CMDLINE_KEY_CTRL_D && CIRBUF_IS_EMPTY(&rdl->left) && CIRBUF_IS_EMPTY(&rdl->right)) { - return -2; + return RDLINE_RES_EOF; } if (!cirbuf_del_head_safe(&rdl->right)) { display_right_buffer(rdl); @@ -259,7 +303,7 @@ rdline_char_in(struct rdline *rdl, char c) case CMDLINE_KEY_CTRL_A: if (CIRBUF_IS_EMPTY(&rdl->left)) break; - rdline_miniprintf(rdl, vt100_multi_left, + rdline_miniprintf(rdl, vt100_multi_left, CIRBUF_GET_LEN(&rdl->left)); while (! CIRBUF_IS_EMPTY(&rdl->left)) { tmp = cirbuf_get_tail(&rdl->left); @@ -271,7 +315,7 @@ rdline_char_in(struct rdline *rdl, char c) case CMDLINE_KEY_CTRL_E: if (CIRBUF_IS_EMPTY(&rdl->right)) break; - rdline_miniprintf(rdl, vt100_multi_right, + rdline_miniprintf(rdl, vt100_multi_right, CIRBUF_GET_LEN(&rdl->right)); while (! CIRBUF_IS_EMPTY(&rdl->right)) { tmp = cirbuf_get_head(&rdl->right); @@ -291,7 +335,7 @@ rdline_char_in(struct rdline *rdl, char c) case CMDLINE_KEY_CTRL_Y: i=0; while(CIRBUF_GET_LEN(&rdl->right) + CIRBUF_GET_LEN(&rdl->left) < - RDLINE_BUF_SIZE && + RDLINE_BUF_SIZE && i < rdl->kill_size) { cirbuf_add_tail(&rdl->left, rdl->kill_buf[i]); rdl->write_char(rdl, rdl->kill_buf[i]); @@ -313,12 +357,12 @@ rdline_char_in(struct rdline *rdl, char c) case CMDLINE_KEY_TAB: case CMDLINE_KEY_HELP: cirbuf_align_left(&rdl->left); - rdl->left_buf[CIRBUF_GET_LEN(&rdl->left)] = '\0'; + rdl->left_buf[CIRBUF_GET_LEN(&rdl->left)] = '\0'; if (rdl->complete) { char tmp_buf[BUFSIZ]; int complete_state; int ret; - int tmp_size; + unsigned int tmp_size; if (cmd == CMDLINE_KEY_TAB) complete_state = 0; @@ -331,22 +375,22 @@ rdline_char_in(struct rdline *rdl, char c) &complete_state); /* no completion or error */ if (ret <= 0) { - return 2; + return RDLINE_RES_COMPLETE; } tmp_size = strlen(tmp_buf); /* add chars */ - if (ret == 2) { + if (ret == RDLINE_RES_COMPLETE) { i=0; while(CIRBUF_GET_LEN(&rdl->right) + CIRBUF_GET_LEN(&rdl->left) < - RDLINE_BUF_SIZE && + RDLINE_BUF_SIZE && i < tmp_size) { cirbuf_add_tail(&rdl->left, tmp_buf[i]); rdl->write_char(rdl, tmp_buf[i]); i++; } display_right_buffer(rdl); - return 2; /* ?? */ + return RDLINE_RES_COMPLETE; /* ?? */ } /* choice */ @@ -363,7 +407,7 @@ rdline_char_in(struct rdline *rdl, char c) rdline_redisplay(rdl); } - return 2; + return RDLINE_RES_COMPLETE; case CMDLINE_KEY_RETURN: case CMDLINE_KEY_RETURN2: @@ -377,8 +421,11 @@ rdline_char_in(struct rdline *rdl, char c) if (rdl->validate) rdl->validate(rdl, rdl->left_buf, CIRBUF_GET_LEN(&rdl->left)+2); - return 1; - + /* user may have stopped rdline */ + if (rdl->status == RDLINE_EXITED) + return RDLINE_RES_EXITED; + return RDLINE_RES_VALIDATED; + #ifndef NO_RDLINE_HISTORY case CMDLINE_KEY_UP_ARR: if (rdl->history_cur_line == 0) { @@ -388,11 +435,11 @@ rdline_char_in(struct rdline *rdl, char c) rdline_add_history(rdl, rdline_get_buffer(rdl)); rdl->history_cur_line = 0; } - + buf = rdline_get_history_item(rdl, rdl->history_cur_line + 1); if (!buf) break; - + rdl->history_cur_line ++; vt100_init(&rdl->vt100); cirbuf_init(&rdl->left, rdl->left_buf, 0, RDLINE_BUF_SIZE); @@ -404,7 +451,7 @@ rdline_char_in(struct rdline *rdl, char c) case CMDLINE_KEY_DOWN_ARR: if (rdl->history_cur_line - 1 < 0) break; - + rdl->history_cur_line --; buf = rdline_get_history_item(rdl, rdl->history_cur_line); if (!buf) @@ -423,23 +470,23 @@ rdline_char_in(struct rdline *rdl, char c) break; } - return 0; + return RDLINE_RES_SUCCESS; } - - if (! isprint(c)) - return 0; + + if (!isprint((int)c)) + return RDLINE_RES_SUCCESS; /* standard chars */ if (CIRBUF_GET_LEN(&rdl->left) + CIRBUF_GET_LEN(&rdl->right) >= RDLINE_BUF_SIZE) - return 0; - + return RDLINE_RES_SUCCESS; + if (cirbuf_add_tail_safe(&rdl->left, c)) - return 0; + return RDLINE_RES_SUCCESS; rdl->write_char(rdl, c); display_right_buffer(rdl); - return 0; + return RDLINE_RES_SUCCESS; } @@ -515,7 +562,7 @@ rdline_get_history_item(struct rdline * rdl, unsigned int idx) return NULL; } -int +int rdline_add_history(struct rdline * rdl, const char * buf) { unsigned int len, i; @@ -537,7 +584,7 @@ rdline_add_history(struct rdline * rdl, const char * buf) cirbuf_add_buf_tail(&rdl->history, buf, len); cirbuf_add_tail(&rdl->history, 0); - + return 0; } @@ -559,7 +606,7 @@ char * rdline_get_history_item(struct rdline * rdl, unsigned int i) {return NULL /* STATIC USEFUL FUNCS */ -static void +static void rdline_puts(struct rdline * rdl, const char * buf) { char c; @@ -569,7 +616,7 @@ rdline_puts(struct rdline * rdl, const char * buf) } /* a very very basic printf with one arg and one format 'u' */ -static void +static void rdline_miniprintf(struct rdline *rdl, const char * buf, unsigned int val) { char c, started=0, div=100; @@ -587,9 +634,9 @@ rdline_miniprintf(struct rdline *rdl, const char * buf, unsigned int val) } /* val is never more than 255 */ while (div) { - c = val / div; + c = (char)(val / div); if (c || started) { - rdl->write_char(rdl, c+'0'); + rdl->write_char(rdl, (char)(c+'0')); started = 1; } val %= div;