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

Répondre à