Commit from zer0 on branch b_zer0 (2007-10-03 22:43 CEST) =================================
This version is working correctly. Need some cleaning now. aversive modules/ihm/parse/parse.c 1.1.2.4 aversive modules/ihm/parse/parse.h 1.1.2.4 aversive modules/ihm/parse/parse_num.c 1.1.2.3 aversive modules/ihm/parse/parse_num.h 1.1.2.4 aversive modules/ihm/parse/parse_string.c 1.1.2.4 aversive modules/ihm/parse/parse_string.h 1.1.2.4 + aversive modules/ihm/parse/test/commands.c 1.1.2.1 aversive modules/ihm/parse/test/main.c 1.1.2.4 aversive modules/ihm/rdline/rdline.c 1.1.2.3 aversive modules/ihm/rdline/rdline.h 1.1.2.2 ================================== aversive/modules/ihm/parse/parse.c (1.1.2.3 -> 1.1.2.4) ================================== @@ -10,8 +10,10 @@ #define BUFSIZ 64 #endif -#define CMDLINE_DEBUG -#define debug_printf printf +//#define CMDLINE_DEBUG +//#define debug_printf printf +#define debug_printf(args...) do {} while(0) + static int isendofline(char c) @@ -38,6 +40,18 @@ return 0; } +static uint8_t +nb_common_chars(const char * s1, const char * s2) +{ + uint8_t i=0; + + while (*s1==*s2 && *s1 && *s2) { + s1++; + s2++; + i++; + } + return i; +} /** * try to match the buffer with an instruction (only the first @@ -67,7 +81,7 @@ if ( isendofline(*buf) || iscomment(*buf) ) break; - n = token->parse(token, buf, (result_buf ? result_buf+token->offset : NULL)); + n = token->ops->parse(token, buf, (result_buf ? result_buf+token->offset : NULL)); if ( n < 0 ) break; debug_printf("TK parsed (len=%d)\n", n); @@ -79,24 +93,36 @@ } /* match the first token */ - if (nb_match_token && (i == nb_match_token)) - return 0; + if (nb_match_token) { + if (i == nb_match_token) { + return 0; + } + return -1; + } /* does not match */ if (token) return -1; - /* match all tokens */ - return 0; + /* are there are some tokens more */ + while (isblank(*buf)) { + buf++; + } + + /* end of buf */ + if ( isendofline(*buf) || iscomment(*buf) ) + return 0; + + return -1; } int8_t parse(struct ctx * ctx, const char * buf) { struct inst ** inst_list = (struct inst **) ctx->insts; - struct inst * inst = *inst_list; + struct inst * inst; const char * curbuf; - char result_buf[64]; /* XXX align, size */ + char result_buf[256]; /* XXX align, size zé in broblém */ void (*f)(void *, void *) = NULL; void * data = NULL; int comment = 0; @@ -144,9 +170,9 @@ #endif /* parse it !! */ + inst = *inst_list; while (inst) { debug_printf("INST\n"); - inst = *inst_list; /* fully parsed */ if (! match_inst(inst, buf, 0, result_buf)) { @@ -190,32 +216,39 @@ /* XXX */ /* return mes couilles */ debug_printf("No match\n"); + return -1; /* pas bien ça... */ } return linelen; } int8_t -complete(struct ctx * ctx, const char *buf, uint16_t *state, +complete(struct ctx * ctx, const char *buf, int16_t *state, char *dst, uint8_t size) { - const char * incomplete_token = NULL; + const char * incomplete_token = buf; struct inst ** inst_list = (struct inst **) ctx->insts; - struct inst * inst = *inst_list; + struct inst * inst; struct token_hdr * token; - char tmpbuf[64]; + char tmpbuf[64], completion_buf[64]; + uint8_t incomplete_token_len; + int8_t completion_len = -1; int8_t nb_token = -1; uint8_t buf_len = strlen(buf); - uint8_t i; - uint8_t total_choices, nb_choice; + uint8_t i, n; + int8_t l; + uint8_t nb_completable; + uint8_t nb_non_completable; + uint16_t local_state=0; - printf("try complete <%s>\n", buf); + debug_printf("%s called\n", __FUNCTION__); /* count the number of complete token to parse */ for (i=0 ; i<buf_len ; i++) { if (nb_token == -1) { if (!isblank(buf[i])) { nb_token = 0; } + incomplete_token = buf+i; } else { if (isblank(buf[i])) { @@ -227,38 +260,55 @@ } } - if (! incomplete_token) - return -1; - printf("%d %s\n", nb_token, incomplete_token); + if (nb_token == -1) + nb_token = 0; + + incomplete_token_len = strlen(incomplete_token); /* first call -> do a first pass */ - if (*state == 0) { - total_choices = 0; + if (*state <= 0) { + debug_printf("try complete <%s>\n", buf); + debug_printf("there is %d complete tokens, <%s> is incomplete\n", nb_token, incomplete_token); - /* parse the first tokens */ - while (inst) { - inst = *inst_list; + nb_completable = 0; + nb_non_completable = 0; - /* fully parsed */ - if (match_inst(inst, buf, nb_token, NULL)) + inst = *inst_list; + while (inst) { + /* parse the first tokens of the inst */ + if (nb_token && match_inst(inst, buf, nb_token, NULL)) goto next; - printf("match \n"); + debug_printf("instruction match \n"); token = inst->tokens[nb_token]; - if (!token) - goto next; - if (!token->complete_get_nb || !token->complete_get_elt) + + /* non completable */ + if (!token || + !token->ops->complete_get_nb || + !token->ops->complete_get_elt || + (n = token->ops->complete_get_nb(token)) == 0) { + nb_non_completable++; goto next; + } - nb_choice = token->complete_get_nb(token); - printf("%d choices\n", nb_choice); - for (i=0 ; i<nb_choice ; i++) { - if (token->complete_get_elt(token, i, tmpbuf, sizeof(tmpbuf)) < 0) + debug_printf("%d choices for this token\n", n); + for (i=0 ; i<n ; i++) { + if (token->ops->complete_get_elt(token, i, tmpbuf, sizeof(tmpbuf)) < 0) continue; - printf("choice <%s>\n", tmpbuf); - if (!strncmp(incomplete_token, tmpbuf, - strlen(incomplete_token))) { - total_choices++; + debug_printf(" choice <%s>\n", tmpbuf); + /* does the completion match the beginning of the word ? */ + if (!strncmp(incomplete_token, tmpbuf, incomplete_token_len)) { + if (completion_len == -1) { + strcpy(completion_buf, tmpbuf+incomplete_token_len); + completion_len = strlen(tmpbuf+incomplete_token_len); + + } + else { + completion_len = nb_common_chars(completion_buf, + tmpbuf+incomplete_token_len); + completion_buf[completion_len] = 0; + } + nb_completable++; } } next: @@ -266,18 +316,92 @@ inst = *inst_list; } - printf("total choices %d\n", total_choices); - } + debug_printf("total choices %d for this completion\n", nb_completable); - if (total_choices == 0) - return 0; - - if (total_choices == 1) { - if (strlen(tmpbuf+strlen(incomplete_token)) > size) + /* no possible completion */ + if (nb_completable == 0 && nb_non_completable == 0) return 0; - strcpy(dst, tmpbuf+strlen(incomplete_token)); - return 1; + /* if multichoice is not required */ + if (*state == 0 && incomplete_token_len > 0) { + /* one possible choice */ + if (nb_completable == 1) { + if (completion_len + 1 > size) //strlen(completion_buf)+1 > size) + return 0; + + strcpy(dst, completion_buf); + strcat(dst, " "); + return 2; + } + + /* several choices starting with the same chars */ + if (completion_len > 0) { // strlen(completion_buf) > 0) { + if (completion_len + 1 > size) //strlen(completion_buf) > size) + return 0; + + strcpy(dst, completion_buf); + return 2; + } + } + } + + /* init state correctly */ + if (*state == -1) + *state = 0; + + debug_printf("Multiple choice STATE=%d\n", *state); + + inst_list = (struct inst **) ctx->insts; + inst = *inst_list; + while (inst) { + inst = *inst_list; + + if (nb_token && match_inst(inst, buf, nb_token, NULL)) + goto next2; + + token = inst->tokens[nb_token]; + if (!token || + !token->ops->complete_get_nb || + !token->ops->complete_get_elt || + (n = token->ops->complete_get_nb(token)) == 0) { + if (local_state < *state) { + local_state++; + goto next2; + } + (*state)++; + if (token && token->ops->get_help) { + token->ops->get_help(token, tmpbuf, sizeof(tmpbuf)); + snprintf(dst, size, "[%s]: %s", tmpbuf, inst->help_str?:"No help"); + } + else { + snprintf(dst, size, "[RETURN]"); + } + return 1; + } + + for (i=0 ; i<n ; i++) { + if (token->ops->complete_get_elt(token, i, tmpbuf, sizeof(tmpbuf)) < 0) + continue; + debug_printf(" choice <%s>\n", tmpbuf); + /* does the completion match the beginning of the word ? */ + if (!strncmp(incomplete_token, tmpbuf, incomplete_token_len)) { + if (local_state < *state) { + local_state++; + continue; + } + (*state)++; + l=snprintf(dst, size, "%s", tmpbuf); + if (l>=0 && token->ops->get_help) { + token->ops->get_help(token, tmpbuf, sizeof(tmpbuf)); + snprintf(dst+l, size-l, " [%s]: %s", tmpbuf, inst->help_str?:"No help"); + } + + return 1; + } + } + next2: + inst_list ++; + inst = *inst_list; } return 0; ================================== aversive/modules/ihm/parse/parse.h (1.1.2.3 -> 1.1.2.4) ================================== @@ -19,24 +19,31 @@ * token if completion is possible. * * complete_get_elt() XXX - * - * help_str is the string that is displayed when we ask for help for - * this token. - * - * offset stores the place to write the parsed result in the - * destination structure. + * get_help() XXX */ -struct token_hdr { - /* parse(token ptr, buf, res pts) */ +struct token_ops { + /** parse(token ptr, buf, res pts) */ int8_t (*parse)(void *, const char *, void *); - /* return the num of possible choices for this token */ + /** return the num of possible choices for this token */ int8_t (*complete_get_nb)(void *); - /* return the elt x for this token (token, idx, dstbuf, size) */ + /** return the elt x for this token (token, idx, dstbuf, size) */ int8_t (*complete_get_elt)(void *, int8_t, char *, uint8_t); - char * help_str; + /** get help for this token (token, dstbuf, size) */ + int8_t (*get_help)(void *, char *, uint8_t); +}; + +/** + * Stores a pointer to the ops struct, and the offset: the place to + * write the parsed result in the destination structure. + */ +struct token_hdr { + struct token_ops *ops; uint8_t offset; }; +/** + * XXX + */ struct inst { /* f(parsed_struct, data) */ void (*f)(void *, void *); @@ -52,7 +59,7 @@ int8_t parse(struct ctx * ctx, const char * buf); -int8_t complete(struct ctx * ctx, const char *buf, uint16_t *state, +int8_t complete(struct ctx * ctx, const char *buf, int16_t *state, char *dst, uint8_t size); int isendoftoken(char c); ====================================== aversive/modules/ihm/parse/parse_num.c (1.1.2.2 -> 1.1.2.3) ====================================== @@ -1,6 +1,7 @@ #include <stdio.h> #include <inttypes.h> #include <ctype.h> +#include <string.h> #include "parse.h" #include "parse_num.h" @@ -23,7 +24,12 @@ #define S32_MAX 0x7FFFFFFF - +struct token_ops token_num_ops = { + .parse = parse_num, + .complete_get_nb = NULL, + .complete_get_elt = NULL, + .get_help = get_help_num, +}; enum num_parse_state_t { @@ -46,6 +52,16 @@ FLOAT_NEG_OK, }; +/* Keep it sync with enum in .h */ +static const char * num_help[] = { + "UINT8", + "UINT16", + "UINT32", + "INT8", + "INT16", + "INT32", + "FLOAT", +}; static inline int8_t add_to_res(uint8_t c, uint32_t * res, uint8_t base) @@ -66,7 +82,7 @@ { struct token_num * token = data; enum num_parse_state_t st = START; - char * buf = srcbuf; + const char * buf = srcbuf; char c = *buf; uint32_t res1=0, res2=0, res3=1; enum numtype type = token->type; @@ -376,3 +392,18 @@ } +/* parse an int or a float */ +int8_t +get_help_num(void * data, char * dstbuf, uint8_t size) +{ + struct token_num * token = data; + uint8_t type = (int)token->type; + + /* should not happen.... don't so this test */ +/* if (type >= (sizeof(num_help)/sizeof(const char *))) */ +/* return -1; */ + + strncpy(dstbuf, num_help[type], size); + dstbuf[size-1] = '\0'; + return 0; +} ====================================== aversive/modules/ihm/parse/parse_num.h (1.1.2.3 -> 1.1.2.4) ====================================== @@ -4,7 +4,7 @@ #include "parse.h" enum numtype { - UINT8, + UINT8 = 0, UINT16, UINT32, INT8, @@ -18,15 +18,15 @@ enum numtype type; }; +extern struct token_ops token_num_ops; + int8_t parse_num(void * token_ptr, const char * srcbuf, void * res); +int8_t get_help_num(void * data, char * dstbuf, uint8_t size); #define TOKEN_NUM_INITIALIZER(structure, field, numtype) \ { \ - { \ - .parse = parse_num, \ - .complete_get_nb = NULL, \ - .complete_get_elt = NULL, \ - .help_str = NULL, \ + .hdr = { \ + .ops = &token_num_ops, \ .offset = offsetof(structure, field), \ }, \ .type = numtype, \ ========================================= aversive/modules/ihm/parse/parse_string.c (1.1.2.3 -> 1.1.2.4) ========================================= @@ -6,6 +6,17 @@ #include "parse.h" #include "parse_string.h" +struct token_ops token_string_ops = { + .parse = parse_string, + .complete_get_nb = complete_get_nb_string, + .complete_get_elt = complete_get_elt_string, + .get_help = get_help_string, +}; + +#define MULTISTRING_HELP "Mul-choice STRING" +#define ANYSTRING_HELP "Any STRING" +#define FIXEDSTRING_HELP "Fixed STRING" + static uint8_t get_token_len(const char * s) { @@ -38,7 +49,7 @@ if (token->str) { str = token->str; do { - token_len = get_token_len(token->str); + token_len = get_token_len(str); /* if token is too big... */ if (token_len >= STR_TOKEN_SIZE - 1) { @@ -87,6 +98,9 @@ const char * str = token->str; int8_t ret=1; + if (!str) + return 0; + while( (str = strchr(str, '#')) != NULL ) { str++; ret++; @@ -116,3 +130,26 @@ return 0; } + + +int8_t get_help_string(void * data, char * dstbuf, uint8_t size) +{ + struct token_string * token = data; + const char * s = token->str; + + if (token->str) { + if (strchr(s, '#')) { + strncpy(dstbuf, MULTISTRING_HELP, size); + } + else { + strncpy(dstbuf, FIXEDSTRING_HELP, size); + } + } + else { + strncpy(dstbuf, ANYSTRING_HELP, size); + } + + dstbuf[size-1] = '\0'; + + return 0; +} ========================================= aversive/modules/ihm/parse/parse_string.h (1.1.2.3 -> 1.1.2.4) ========================================= @@ -12,21 +12,21 @@ const char * str; }; +extern struct token_ops token_string_ops; + int8_t parse_string(void * token_ptr, const char * srcbuf, void * res); int8_t complete_get_nb_string(void * token_ptr); int8_t complete_get_elt_string(void * token_ptr, int8_t idx, char * dstbuf, uint8_t size); +int8_t get_help_string(void * data, char * dstbuf, uint8_t size); -#define TOKEN_STRING_INITIALIZER(structure, field, string) \ -{ \ - { \ - .parse = parse_string, \ - .complete_get_nb = complete_get_nb_string, \ - .complete_get_elt = complete_get_elt_string, \ - .help_str = NULL, \ - .offset = offsetof(structure, field), \ - }, \ - .str = string, \ +#define TOKEN_STRING_INITIALIZER(structure, field, string) \ +{ \ + .hdr = { \ + .ops = &token_string_ops, \ + .offset = offsetof(structure, field), \ + }, \ + .str = string, \ } #endif /* _PARSE_STRING_H_ */ ========================================== aversive/modules/ihm/parse/test/commands.c (1.1.2.1) ========================================== @@ -0,0 +1,127 @@ +#include <stdio.h> +#include <string.h> + +#include <parse.h> +#include <parse_num.h> +#include <parse_string.h> + + +/****** CMD 1 */ + +/* this structure is filled when cmd1 is parsed successfully */ +struct cmd1_result { + fixed_string_t arg0; + fixed_string_t arg1; + uint32_t arg2; + fixed_string_t arg3; +}; + +/* function called when cmd1 is parsed successfully */ +void cmd1_parsed(void * parsed_result, void * data) +{ + struct cmd1_result * res = parsed_result; + printf("MATCH %s %s %d %s\n", res->arg0, res->arg1, res->arg2, res->arg3); +} + +struct token_string cmd1_arg0 = TOKEN_STRING_INITIALIZER(struct cmd1_result, arg0, "cmd1"); +struct token_string cmd1_arg1 = TOKEN_STRING_INITIALIZER(struct cmd1_result, arg1, "pouet#coin#mouarf#mouais"); +struct token_num cmd1_arg2 = TOKEN_NUM_INITIALIZER(struct cmd1_result, arg2, UINT32); +/* str == NULL means any string */ +struct token_string cmd1_arg3 = TOKEN_STRING_INITIALIZER(struct cmd1_result, arg3, NULL); + +struct inst cmd1 = { + .f = cmd1_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "This is help for cmd1", /* help string for instruction */ + .tokens = { /* token list, NULL terminated */ + &cmd1_arg0, &cmd1_arg1, &cmd1_arg2, &cmd1_arg3, NULL, + }, +}; + + +/****** CMD 2 */ + +struct cmd2_result { + fixed_string_t arg0; +}; + +void cmd2_parsed(void * parsed_result, void * data) +{ + struct cmd2_result * res = parsed_result; + + printf("MATCH %s\n", res->arg0); +} + +struct token_string cmd2_arg0 = TOKEN_STRING_INITIALIZER(struct cmd2_result, arg0, "toto"); + +struct inst cmd2 = { + .f = cmd2_parsed, + .data = NULL, + .help_str = "Help for toto instruction", + .tokens = { + &cmd2_arg0, NULL, + }, +}; + + +/****** CMD 3 */ + +struct cmd3_result { + fixed_string_t arg0; + float arg1; +}; + +void cmd3_parsed(void * parsed_result, void * data) +{ + struct cmd3_result * res = parsed_result; + + printf("MATCH %s %f\n", res->arg0, res->arg1); +} + +struct token_string cmd3_arg0 = TOKEN_STRING_INITIALIZER(struct cmd3_result, arg0, "toto#titi"); +struct token_num cmd3_arg1 = TOKEN_NUM_INITIALIZER(struct cmd3_result, arg1, FLOAT); + +struct inst cmd3 = { + .f = cmd3_parsed, + .data = NULL, + .tokens = { + &cmd3_arg0, &cmd3_arg1, NULL, + }, +}; + + +/****** CMD 4 */ + +struct cmd4_result { + fixed_string_t arg0; + fixed_string_t arg1; +}; + +void cmd4_parsed(void * parsed_result, void * data) +{ + struct cmd4_result * res = parsed_result; + + printf("MATCH %s %s\n", res->arg0, res->arg1); +} + +struct token_string cmd4_arg0 = TOKEN_STRING_INITIALIZER(struct cmd4_result, arg0, "titi"); +struct token_string cmd4_arg1 = TOKEN_STRING_INITIALIZER(struct cmd4_result, arg0, "tutu"); + +struct inst cmd4 = { + .f = cmd4_parsed, + .data = NULL, + .help_str = "Help for titi instruction", + .tokens = { + &cmd4_arg0, &cmd4_arg1, NULL, + }, +}; + + +/****** CONTEXT (list of instruction) */ + +struct ctx main_ctx = { + .name = "main", + .insts = { + &cmd1, &cmd2, &cmd3, &cmd4, NULL, + }, +}; ====================================== aversive/modules/ihm/parse/test/main.c (1.1.2.3 -> 1.1.2.4) ====================================== @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Revision : $Id: main.c,v 1.1.2.3 2007-09-22 18:15:55 zer0 Exp $ + * Revision : $Id: main.c,v 1.1.2.4 2007-10-03 20:43:16 zer0 Exp $ * * */ @@ -27,8 +27,6 @@ #include <stdio.h> #include <string.h> -//#define DEBUG_SOCKET - #ifdef HOST_VERSION #include <unistd.h> @@ -49,6 +47,7 @@ #include <rdline.h> #include <parse.h> #include <parse_string.h> +#include <parse_num.h> extern struct ctx main_ctx; @@ -58,47 +57,6 @@ int cpt=0; -#ifdef DEBUG_SOCKET /* debug... keep it because it is nice */ - -int s = -1; - -void sock_printf(const char * fmt, ...) -{ - va_list ap; - char buf[BUFSIZ]; - int n; - - va_start(ap, fmt); - n=vsnprintf(buf, BUFSIZ, fmt, ap); - if (s>0) write(s, buf, n); - va_end(ap); -} - -void dump_it(struct cirbuf * cbuf) -{ - int i; - char e; - - sock_printf("sta=%2.2d end=%2.2d len=%2.2d/%2.2d { ", - cbuf->start, cbuf->end, - CIRBUF_GET_LEN(cbuf), - CIRBUF_GET_MAXLEN(cbuf)); - - sock_printf("[ "); - CIRBUF_FOREACH(cbuf, i, e) { - sock_printf("%2.2x, ", e&0xFF); - } - sock_printf("]\n"); -} - -#else - -void sock_printf(const char * fmt, ...) {} -void dump_it(struct cirbuf * cbuf) {} - -#endif /* DEBUG_SOCKET */ - - #ifdef HOST_VERSION void write_char(char c) { @@ -128,41 +86,17 @@ #endif - void display_buffer(const char * buf, uint8_t size) { - printf("**** GOT (%d) >> %s", size, buf); + if (parse(&main_ctx, buf) < 0) + printf("Command not found\n"); } -const char * dummy_complete[] = { - "toto", - "titi", - "pouet", - "coin", -}; - -#define TEST_COMPLETION 1 -//#define TEST_COMPLETION 2 int8_t complete_buffer(const char * buf, uint8_t size, char * dstbuf, uint8_t dstsize, - int * state) + int16_t * state) { - sock_printf("complete -> %d\n", *state); -#if TEST_COMPLETION == 1 - if (*state < (sizeof(dummy_complete)/sizeof(const char *))) { - /* pourri mais bon c'est temporaire */ - strcpy(dstbuf, dummy_complete[*state]); - (*state) ++; - return 1; - } - return 0; -#else - dstbuf[0] = 'x'; - dstbuf[1] = 'y'; - dstbuf[2] = 'z'; - dstbuf[3] = '\0'; - return 2; -#endif + return complete(&main_ctx, buf, state, dstbuf, dstsize); } struct cmd_result { @@ -170,51 +104,24 @@ } result; struct token_string tok = TOKEN_STRING_INITIALIZER(struct cmd_result, arg0, "test1#test2#dd"); +struct cmd_result_num { + uint32_t arg0; +} result_num; +struct token_num tok_num = TOKEN_NUM_INITIALIZER(struct cmd_result_num, arg0, UINT32); int main(void) { #ifdef HOST_VERSION struct termios oldterm, term; - char buf[64]; + char buf[127]; int n, i; int8_t ret; #endif int err; - uint16_t state=0; - -#ifdef DEBUG_SOCKET - struct sockaddr_in sin_ci; - - - s = socket(PF_INET, SOCK_STREAM, 0); - if (s < 0) { - printf("socket() failed\n"); - } - - memset(&sin_ci, 0, sizeof(sin_ci)); - sin_ci.sin_family = AF_INET; - sin_ci.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - sin_ci.sin_port = htons(31337); -#ifndef __linux__ - sin_ci.sin_len = sizeof(sin_ci); -#endif - - if (s > 0 && connect(s, (struct sockaddr *)&sin_ci, sizeof(sin_ci)) < 0) { - printf("connect() failed\n"); - s = -1; - } -#endif /* DEBUG_SOCKET */ + int16_t state=0; -#ifdef HOST_VERSION -#if 0 - tcgetattr(0, &oldterm); - memcpy(&term, &oldterm, sizeof(term)); - term.c_lflag &= ~(ICANON | ECHO | ISIG); - tcsetattr(0, TCSANOW, &term); - setbuf(stdin, NULL); -#endif -#else +#ifndef HOST_VERSION uart_init(); fdevopen(uart0_dev_send, uart0_dev_recv); @@ -222,8 +129,8 @@ uart0_register_rx_event(rx); sei(); -#endif printf("Start\n"); +#endif err = parse_string(&tok, "test1", &result); if (err >= 0) @@ -241,6 +148,23 @@ if (err >= 0) printf("Match : <%s> (consumed %d)\n", result.arg0, err); + printf("\n"); + err = parse_num(&tok_num, "123", &result_num); + if (err >= 0) + printf("Match : <%d> (consumed %d)\n", result_num.arg0, err); + + err = parse_num(&tok_num, "0x55", &result_num); + if (err >= 0) + printf("Match : <%d> (consumed %d)\n", result_num.arg0, err); + + err = parse_num(&tok_num, "121321003115165 ", &result_num); + if (err >= 0) + printf("Match : <%d> (consumed %d)\n", result_num.arg0, err); + + if (parse(&main_ctx, "toto 3.3\n")) + printf("does not match... :'(\n"); + + printf("\n"); printf("complete nb = %d\n", complete_get_nb_string(&tok)); complete_get_elt_string(&tok, 0, buf, sizeof(buf)); @@ -252,43 +176,64 @@ if (complete_get_elt_string(&tok, 3, buf, sizeof(buf)) != -1) printf("complete 3 ????? : <%s>\n", buf); + printf("\n\n"); state=0; while ( (err = complete(&main_ctx, "cmd1 mo", &state, buf, sizeof(buf))) == 1) { printf("err = %d, buf = <%s>\n", err, buf); } - if (err == 2) + if (err <= 0) + printf("err = %d\n", err); + else printf("err = %d, buf = <%s>\n", err, buf); + printf("\n\n"); state=0; while ( (err = complete(&main_ctx, "cmd1 p", &state, buf, sizeof(buf))) == 1) { printf("err = %d, buf = <%s>\n", err, buf); } - if (err == 2) + if (err <= 0) + printf("err = %d\n", err); + else printf("err = %d, buf = <%s>\n", err, buf); + printf("\n\n"); state=0; while ( (err = complete(&main_ctx, "cmd1 ", &state, buf, sizeof(buf))) == 1) { printf("err = %d, buf = <%s>\n", err, buf); } - if (err == 2) + if (err <= 0) + printf("err = %d\n", err); + else printf("err = %d, buf = <%s>\n", err, buf); + printf("\n\n"); state=0; while ( (err = complete(&main_ctx, "toto", &state, buf, sizeof(buf))) == 1) { printf("err = %d, buf = <%s>\n", err, buf); } - if (err == 2) + if (err <= 0) + printf("err = %d\n", err); + else printf("err = %d, buf = <%s>\n", err, buf); + printf("\n\n"); state=0; while ( (err = complete(&main_ctx, "csdcds", &state, buf, sizeof(buf))) == 1) { printf("err = %d, buf = <%s>\n", err, buf); } - if (err == 2) + if (err <= 0) + printf("err = %d\n", err); + else printf("err = %d, buf = <%s>\n", err, buf); - return 0; +#ifdef HOST_VERSION + tcgetattr(0, &oldterm); + memcpy(&term, &oldterm, sizeof(term)); + term.c_lflag &= ~(ICANON | ECHO | ISIG); + tcsetattr(0, TCSANOW, &term); + setbuf(stdin, NULL); +#endif /* common init */ rdline_init(&rdl, write_char, display_buffer, complete_buffer); @@ -302,10 +247,6 @@ buf[n] = 0; for (i=0 ; i<n ; i++) { - sock_printf("%o ", buf[i]&0xff); - } - sock_printf(" RECV\n"); - for (i=0 ; i<n ; i++) { ret = rdline_char_in(&rdl, buf[i]); if (ret == 1) { rdline_add_history(&rdl, rdline_get_buffer(&rdl)); @@ -321,7 +262,7 @@ } tcsetattr(0, TCSANOW, &oldterm); - printf("\n"); + printf("\nEND n=%d\n", n); /* irq driven on avr, see rx() */ #else ==================================== aversive/modules/ihm/rdline/rdline.c (1.1.2.2 -> 1.1.2.3) ==================================== @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Revision : $Id: rdline.c,v 1.1.2.2 2007-09-12 19:03:08 zer0 Exp $ + * Revision : $Id: rdline.c,v 1.1.2.3 2007-10-03 20:43:16 zer0 Exp $ * * */ @@ -87,6 +87,19 @@ "\r", #define KEY_RETURN2 17 + "\033\177", +#define KEY_META_BKSPACE 18 + + vt100_word_left, +#define KEY_WLEFT 19 + + vt100_word_right, +#define KEY_WRIGHT 20 + + "?", +#define KEY_HELP 21 + + NULL, }; @@ -94,7 +107,6 @@ static uint8_t vt100_parser(struct rdline *rdl, char c); static int8_t match_command(char * buf, uint8_t size); static void rdline_printf(struct rdline * rdl, const char * fmt, ...); -static void rdline_write_str(struct rdline * rdl, const char * s); #ifdef CONFIG_MODULE_RDLINE_HISTORY static void rdline_remove_old_history_item(struct rdline * rdl); @@ -106,7 +118,7 @@ void rdline_init(struct rdline * rdl, void (*write_char)(char), void (*validate)(const char *, uint8_t size), int8_t (*complete)(const char *, uint8_t size, char * dstbuf, - uint8_t dstsize, int * state)) + uint8_t dstsize, int16_t * state)) { memset(rdl, 0, sizeof(*rdl)); rdl->validate = validate; @@ -218,7 +230,7 @@ switch (cmd) { case KEY_CTRL_B: case KEY_LEFT_ARR: - if (CIRBUF_IS_EMPTY(&rdl->left) || CIRBUF_IS_FULL(&rdl->right)) + if (CIRBUF_IS_EMPTY(&rdl->left)) break; tmp = cirbuf_get_tail(&rdl->left); cirbuf_del_tail(&rdl->left); @@ -228,7 +240,7 @@ case KEY_CTRL_F: case KEY_RIGHT_ARR: - if (CIRBUF_IS_EMPTY(&rdl->right) || CIRBUF_IS_FULL(&rdl->left)) + if (CIRBUF_IS_EMPTY(&rdl->right)) break; tmp = cirbuf_get_head(&rdl->right); cirbuf_del_head(&rdl->right); @@ -236,6 +248,40 @@ rdline_printf(rdl, vt100_right_arr); break; + case KEY_WLEFT: + while (! CIRBUF_IS_EMPTY(&rdl->left) && + (tmp = cirbuf_get_tail(&rdl->left)) && + isblank(tmp)) { + rdline_printf(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)) && + !isblank(tmp)) { + rdline_printf(rdl, vt100_left_arr); + cirbuf_del_tail(&rdl->left); + cirbuf_add_head(&rdl->right, tmp); + } + break; + + case KEY_WRIGHT: + while (! CIRBUF_IS_EMPTY(&rdl->right) && + (tmp = cirbuf_get_head(&rdl->right)) && + isblank(tmp)) { + rdline_printf(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)) && + !isblank(tmp)) { + rdline_printf(rdl, vt100_right_arr); + cirbuf_del_head(&rdl->right); + cirbuf_add_tail(&rdl->left, tmp); + } + break; + case KEY_BKSPACE: if(!cirbuf_del_tail_safe(&rdl->left)) { rdline_printf(rdl, vt100_bs); @@ -243,6 +289,18 @@ } break; + case KEY_META_BKSPACE: + while (! CIRBUF_IS_EMPTY(&rdl->left) && isblank(cirbuf_get_tail(&rdl->left))) { + rdline_printf(rdl, vt100_bs); + cirbuf_del_tail(&rdl->left); + } + while (! CIRBUF_IS_EMPTY(&rdl->left) && !isblank(cirbuf_get_tail(&rdl->left))) { + rdline_printf(rdl, vt100_bs); + cirbuf_del_tail(&rdl->left); + } + display_right_buffer(rdl); + break; + case KEY_SUPPR: case KEY_CTRL_D: if(!cirbuf_del_head_safe(&rdl->right)) { @@ -310,15 +368,22 @@ break; case KEY_TAB: + case KEY_HELP: cirbuf_align_left(&rdl->left); - rdl->left_buf[CIRBUF_GET_LEN(&rdl->left)] = '?'; /* XXX ? */ - rdl->left_buf[CIRBUF_GET_LEN(&rdl->left)+1] = '\0'; + // rdl->left_buf[CIRBUF_GET_LEN(&rdl->left)] = '?'; /* XXX ? */ + //rdl->left_buf[CIRBUF_GET_LEN(&rdl->left)+1] = '\0'; + rdl->left_buf[CIRBUF_GET_LEN(&rdl->left)] = '\0'; if (rdl->complete) { - char tmp_buf[32]; /* XXX*/ - int complete_state = 0; - int ret; + char tmp_buf[127]; /* XXX */ + int16_t complete_state; + int8_t ret; int tmp_size; + if (cmd == KEY_TAB) + complete_state = 0; + else + complete_state = -1; + /* complete() retourne < 0 en cas d'erreur * * 2 si ca complete (1 choix possible), dans ce cas les lettres * a ajouter sont dans le buffer dst @@ -568,9 +633,10 @@ /* STATIC USEFUL FUNCS */ static uint8_t -vt100_parser(struct rdline *rdl, char c) +vt100_parser(struct rdline *rdl, char ch) { uint8_t ret; + uint8_t c = (uint8_t) ch; if (rdl->bufpos > RDLINE_VT100_BUF_SIZE) { rdl->vt100_state = VT100_INIT; @@ -595,7 +661,7 @@ if (c == 0133) { rdl->vt100_state = VT100_ESCAPE_CSI; } - else if (c >= 060 && c <= 0160) { + else if (c >= 060 && c <= 0177) { /* XXX 0177 ? */ rdl->bufpos = 0; rdl->vt100_state = VT100_INIT; return ret; @@ -612,7 +678,6 @@ default: rdl->bufpos = 0; - rdl->vt100_state = VT100_INIT; break; } ==================================== aversive/modules/ihm/rdline/rdline.h (1.1.2.1 -> 1.1.2.2) ==================================== @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Revision : $Id: rdline.h,v 1.1.2.1 2007-09-12 17:52:21 zer0 Exp $ + * Revision : $Id: rdline.h,v 1.1.2.2 2007-10-03 20:43:16 zer0 Exp $ * * */ @@ -75,6 +75,8 @@ #define vt100_multi_left "\033\133%uD" #define vt100_suppr "\033\133\063\176" #define vt100_home "\033M\033E" +#define vt100_word_left "\033\142" +#define vt100_word_right "\033\146" /* configuration */ #define RDLINE_BUF_SIZE 32 @@ -117,7 +119,7 @@ void (*write_char)(char); void (*validate)(const char *, uint8_t size); int8_t (*complete)(const char *, uint8_t size, char * dstbuf, - uint8_t dstsize, int * state); + uint8_t dstsize, int16_t * state); /* vt100 parser */ uint8_t bufpos; @@ -138,7 +140,7 @@ void rdline_init(struct rdline * rdl, void (*write_char)(char), void (*validate)(const char *, uint8_t size), int8_t (*complete)(const char *, uint8_t size, char * dstbuf, - uint8_t dstsize, int * state)); + uint8_t dstsize, int16_t * state)); /**
_______________________________________________ Avr-list mailing list Avr-list@droids-corp.org CVSWEB : http://cvsweb.droids-corp.org/cgi-bin/viewcvs.cgi/aversive WIKI : http://wiki.droids-corp.org/index.php/Aversive DOXYGEN : http://zer0.droids-corp.org/doxygen_aversive/html/ BUGZILLA : http://bugzilla.droids-corp.org COMMIT LOGS : http://zer0.droids-corp.org/aversive_commitlog