vt100: include pgmspace.h as we use PROGMEM macro
[aversive.git] / modules / ihm / rdline / test / main.c
1 /*  
2  *  Copyright Droids Corporation (2007)
3  *  Olivier MATZ <zer0@droids-corp.org>
4  * 
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  *  Revision : $Id: main.c,v 1.1.2.3 2007-11-15 11:18:00 zer0 Exp $
20  *
21  *
22  */
23
24 /* test program for rdline, works on AVR and HOST... but there are a
25  * lot of defines... ;) */
26
27 #include <stdio.h>
28 #include <string.h>
29
30 //#define DEBUG_SOCKET
31
32
33 #ifdef HOST_VERSION
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include <inttypes.h>
38 #include <termios.h>
39 #include <ctype.h>
40
41 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <sys/socket.h>
44 #include <sys/un.h>
45 #endif
46
47 #include <aversive/wait.h>
48 #include <uart.h>
49 #include "rdline.h"
50
51 /* globals */
52 struct rdline rdl;
53 char prompt[RDLINE_PROMPT_SIZE];
54 int cpt=0;
55
56
57 #ifdef DEBUG_SOCKET /* debug... keep it because it is nice */
58
59 int s = -1;
60
61 void sock_printf(const char * fmt, ...)
62 {
63         va_list ap;
64         char buf[BUFSIZ];
65         int n;
66
67         va_start(ap, fmt);
68         n=vsnprintf(buf, BUFSIZ, fmt, ap);
69         if (s>0) write(s, buf, n);
70         va_end(ap);
71 }
72
73 void dump_it(struct cirbuf * cbuf)
74 {
75         int i;
76         char e;
77
78         sock_printf("sta=%2.2d end=%2.2d len=%2.2d/%2.2d { ", 
79                  cbuf->start, cbuf->end,
80                  CIRBUF_GET_LEN(cbuf),
81                  CIRBUF_GET_MAXLEN(cbuf));
82
83         sock_printf("[ ");
84         CIRBUF_FOREACH(cbuf, i, e) {
85                 sock_printf("%2.2x, ", e&0xFF);
86         }
87         sock_printf("]\n");
88 }
89
90 #else
91
92 void sock_printf(const char * fmt, ...) {}
93 void dump_it(struct cirbuf * cbuf) {}
94
95 #endif /* DEBUG_SOCKET */
96
97
98 #ifdef HOST_VERSION
99 void
100 write_char(char c) {
101         write(1, &c, 1);
102 }
103 #else
104 void
105 write_char(char c) {
106         uart_send(0, c);
107 }
108
109 static void
110 rx(char c)
111 {
112         int8_t ret;
113         ret = rdline_char_in(&rdl, c);
114         if (ret == 1) {
115                 rdline_add_history(&rdl, rdline_get_buffer(&rdl));
116                 snprintf(prompt, sizeof(prompt), "toto[%d] > ", cpt++);
117                 rdline_newline(&rdl, prompt);
118         }
119         else if (ret == -2) {
120                 rdline_stop(&rdl);
121                 printf("END\n");
122         }
123 }
124
125 #endif
126
127
128 void display_buffer(const char * buf, uint8_t size) 
129 {
130         printf("**** GOT  (%d) >> %s", size, buf);
131 }
132
133 const char * dummy_complete[] = {
134         "toto",
135         "titi",
136         "pouet",
137         "coin",
138 };
139
140 #define TEST_COMPLETION 1
141 //#define TEST_COMPLETION 2
142 int8_t complete_buffer(const char *buf, char *dstbuf,
143         uint8_t dstsize, int *state)
144 {
145         sock_printf("complete -> %d\n", *state);
146 #if TEST_COMPLETION == 1
147         if (*state < (sizeof(dummy_complete)/sizeof(const char *))) {
148                 /* pourri mais bon c'est temporaire */
149                 strcpy(dstbuf, dummy_complete[*state]);
150                 (*state) ++;
151                 return 1;
152         }
153         return 0;
154 #else
155         dstbuf[0] = 'x';
156         dstbuf[1] = 'y';
157         dstbuf[2] = 'z';
158         dstbuf[3] = '\0';
159         return 2;
160 #endif
161 }
162
163
164
165 int main(void)
166 {
167 #ifdef HOST_VERSION
168         struct termios oldterm, term;
169         char buf[BUFSIZ];
170         int n, i;
171         int8_t ret;
172 #endif
173 #ifdef DEBUG_SOCKET
174         struct sockaddr_in sin_ci;
175
176
177         s = socket(PF_INET, SOCK_STREAM, 0);
178         if (s < 0) {
179                 printf("socket() failed\n");
180         }
181
182         memset(&sin_ci, 0, sizeof(sin_ci));
183         sin_ci.sin_family = AF_INET;
184         sin_ci.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
185         sin_ci.sin_port = htons(31337);
186 #ifndef __linux__
187         sin_ci.sin_len = sizeof(sin_ci);
188 #endif
189
190         if (s > 0 && connect(s, (struct sockaddr *)&sin_ci, sizeof(sin_ci)) < 0) {
191                 printf("connect() failed\n");
192                 s = -1;
193         }
194 #endif /* DEBUG_SOCKET */
195
196 #ifdef HOST_VERSION
197         tcgetattr(0, &oldterm);
198         memcpy(&term, &oldterm, sizeof(term));
199         term.c_lflag &= ~(ICANON | ECHO | ISIG);
200         tcsetattr(0, TCSANOW, &term);
201         setbuf(stdin, NULL);
202 #else
203         uart_init();
204         fdevopen(uart0_dev_send, uart0_dev_recv);
205
206         wait_ms(5000);
207         printf("Start\n");
208         uart_register_rx_event(0, rx);
209         
210         sei();
211 #endif
212
213
214         /* common init */
215         rdline_init(&rdl, write_char, display_buffer, complete_buffer);
216         snprintf(prompt, sizeof(prompt), "toto[%d] > ", cpt++); 
217         rdline_newline(&rdl, prompt);
218
219
220         /* loop to send chars on host */
221 #ifdef HOST_VERSION
222         while ((n=read(0, buf, BUFSIZ-1)) > 0) {
223                 buf[n] = 0;
224
225                 for (i=0 ; i<n ; i++) {
226                         sock_printf("%o ", buf[i]&0xff);
227                 }
228                 sock_printf(" RECV\n");
229                 for (i=0 ; i<n ; i++) {
230                         ret = rdline_char_in(&rdl, buf[i]);
231                         if (ret == 1) {
232                                 rdline_add_history(&rdl, rdline_get_buffer(&rdl));
233                                 snprintf(prompt, sizeof(prompt), "toto[%d] > ", cpt++);
234                                 rdline_newline(&rdl, prompt);
235                         }
236                         else if (ret == -2) {
237                                 tcsetattr(0, TCSANOW, &oldterm);
238                                 printf("\n");
239                                 return 0;
240                         }
241                 }
242         }
243
244         tcsetattr(0, TCSANOW, &oldterm);
245         printf("\n");
246
247         /* irq driven on avr, see rx() */
248 #else
249         while(1);
250 #endif
251
252         return 0;
253 }