command: replace printf printf_P
[protos/xbee-avr.git] / vt100.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: vt100.c,v 1.1.2.1 2008-01-05 22:46:28 zer0 Exp $
20  *
21  *
22  */
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #include <ctype.h>
29
30 #include <aversive/pgmspace.h>
31
32 #include "vt100.h"
33
34 static const prog_char cmd0[] = vt100_up_arr;
35 static const prog_char cmd1[] = vt100_down_arr;
36 static const prog_char cmd2[] = vt100_right_arr;
37 static const prog_char cmd3[] = vt100_left_arr;
38 static const prog_char cmd4[] = "\177";
39 static const prog_char cmd5[] = "\n";
40 static const prog_char cmd6[] = "\001";
41 static const prog_char cmd7[] = "\005";
42 static const prog_char cmd8[] = "\013";
43 static const prog_char cmd9[] = "\031";
44 static const prog_char cmd10[] = "\003";
45 static const prog_char cmd11[] = "\006";
46 static const prog_char cmd12[] = "\002";
47 static const prog_char cmd13[] = vt100_suppr;
48 static const prog_char cmd14[] = vt100_tab;
49 static const prog_char cmd15[] = "\004";
50 static const prog_char cmd16[] = "\014";
51 static const prog_char cmd17[] = "\r";
52 static const prog_char cmd18[] = "\033\177";
53 static const prog_char cmd19[] = vt100_word_left;
54 static const prog_char cmd20[] = vt100_word_right;
55 static const prog_char cmd21[] = "?";
56
57 const prog_char * vt100_commands[] PROGMEM = {
58         cmd0, cmd1, cmd2, cmd3, cmd4, cmd5, cmd6, cmd7,
59         cmd8, cmd9, cmd10, cmd11, cmd12, cmd13, cmd14,
60         cmd15, cmd16, cmd17, cmd18, cmd19, cmd20,
61         cmd21,
62 };
63
64 void
65 vt100_init(struct vt100 * vt)
66 {
67         vt->state = VT100_INIT;
68 }
69
70
71 static int8_t
72 match_command(char * buf, uint8_t size)
73 {
74         const prog_char * cmd;
75         uint8_t i = 0;
76         
77         for (i=0 ; i<sizeof(vt100_commands)/sizeof(const prog_char *) ; i++) {
78 #ifdef HOST_VERSION
79                 cmd = *(vt100_commands + i);
80 #else
81                 cmd = (const prog_char *) pgm_read_word (vt100_commands + i);
82 #endif
83
84                 if (size == strlen_P(cmd) &&
85                     !strncmp_P(buf, cmd, strlen_P(cmd))) {
86                         return i;
87                 }
88         }
89
90         return -1;
91 }
92
93 int8_t
94 vt100_parser(struct vt100 *vt, char ch)
95 {
96         uint8_t size;
97         uint8_t c = (uint8_t) ch;
98
99         if (vt->bufpos > VT100_BUF_SIZE) {
100                 vt->state = VT100_INIT;
101                 vt->bufpos = 0;
102         }
103
104         vt->buf[vt->bufpos++] = c;
105         size = vt->bufpos;
106
107         switch (vt->state) {
108         case VT100_INIT:
109                 if (c == 033) {
110                         vt->state = VT100_ESCAPE;
111                 }
112                 else {
113                         vt->bufpos = 0;
114                         goto match_command;
115                 }
116                 break;
117
118         case VT100_ESCAPE:
119                 if (c == 0133) {
120                         vt->state = VT100_ESCAPE_CSI;
121                 }
122                 else if (c >= 060 && c <= 0177) { /* XXX 0177 ? */
123                         vt->bufpos = 0;
124                         vt->state = VT100_INIT;
125                         goto match_command;
126                 }
127                 break;
128
129         case VT100_ESCAPE_CSI:
130                 if (c >= 0100 && c <= 0176) {
131                         vt->bufpos = 0;
132                         vt->state = VT100_INIT;
133                         goto match_command;
134                 }
135                 break;
136                 
137         default:
138                 vt->bufpos = 0;
139                 break;
140         }
141
142         return -2;
143         
144  match_command:
145         return match_command(vt->buf, size);
146 }