forked from tinkerspy/Automaton
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAtm_command.cpp
More file actions
executable file
·107 lines (97 loc) · 2.37 KB
/
Atm_command.cpp
File metadata and controls
executable file
·107 lines (97 loc) · 2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <Automaton.h>
#include "Atm_command.h"
Atm_command & Atm_command::begin( Stream * stream, char buffer[], int size )
{
const static state_t state_table[] PROGMEM = {
/* ON_ENTER ON_LOOP ON_EXIT EVT_INPUT EVT_EOL ELSE */
/* IDLE */ -1, -1, -1, READCHAR, -1, -1,
/* READCHAR */ ACT_READCHAR, -1, -1, READCHAR, SEND, -1,
/* SEND */ ACT_SEND, -1, -1, -1, -1, IDLE,
};
Machine::begin( state_table, ELSE );
_stream = stream;
_buffer = buffer;
_bufsize = size;
_bufptr = 0;
_separator = " ";
_eol = '\n';
_lastch = '\0';
return *this;
}
Atm_command & Atm_command::onCommand(void (*callback)( int idx ), const char * cmds )
{
_callback = callback;
_commands = cmds;
return *this;
}
Atm_command & Atm_command::separator( const char sep[] )
{
_separator = sep;
return *this;
}
char * Atm_command::arg( int id ) {
int cnt = 0;
int i;
if ( id == 0 ) return _buffer;
for ( i = 0; i < _bufptr; i++ ) {
if ( _buffer[i] == '\0' ) {
if ( ++cnt == id ) {
i++;
break;
}
}
}
return &_buffer[i];
}
int Atm_command::lookup( int id, const char * cmdlist ) {
int cnt = 0;
char * arg = this->arg( id );
char * a = arg;
while ( cmdlist[0] != '\0' ) {
while ( cmdlist[0] != '\0' && toupper( cmdlist[0] ) == toupper( a[0] ) ) {
cmdlist++;
a++;
}
if ( a[0] == '\0' )
return cnt;
if ( cmdlist[0] == ' ' )
cnt++;
cmdlist++;
a = arg;
}
return -1;
}
int Atm_command::event( int id )
{
switch ( id ) {
case EVT_INPUT :
return _stream->available();
case EVT_EOL :
return _buffer[_bufptr-1] == _eol || _bufptr >= _bufsize;
}
return 0;
}
void Atm_command::action( int id )
{
switch ( id ) {
case ACT_READCHAR :
if ( _stream->available() ) {
char ch = _stream->read();
if ( strchr( _separator, ch ) == NULL ) {
_buffer[_bufptr++] = ch;
_lastch = ch;
} else {
if ( _lastch != '\0' )
_buffer[_bufptr++] = '\0';
_lastch = '\0';
}
}
return;
case ACT_SEND :
_buffer[--_bufptr] = '\0';
(*_callback)( lookup( 0, _commands ) );
_lastch = '\0';
_bufptr = 0;
return;
}
}