Skip to content

Instantly share code, notes, and snippets.

@fenrir-naru
Created March 19, 2016 04:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fenrir-naru/90f1a308ab98477c7cd0 to your computer and use it in GitHub Desktop.
Save fenrir-naru/90f1a308ab98477c7cd0 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char cmd_str[] = \
"$ te\\x4Ast\\r\\n\r\n"
"> OK\r\n"
"$ hoge\\r\\n\r\n"
"> ERROR\r\n"
"$ error\\r\\n\r\n";
char read_cmd(){
static char *cmd_p = cmd_str;
return *(cmd_p++);
}
char read_res(){
return (char)getchar();
}
void send_char(char c){
putchar(c);
}
void run(){
enum {
INIT,
BEFORE_SEND,
SENDING,
SENDING_ESCAPE,
SENDING_ESCAPE_HEX1,
SENDING_ESCAPE_HEX2,
BEFORE_EXPECT,
EXPECTING,
EXPECT_FAILED,
IGNORE_LINE,
} state = INIT;
char c;
char buf[8];
unsigned char buf_length, expect_index;
while(c = read_cmd()){
unsigned char is_endline = ((c == '\r') || (c == '\n'));
switch(state){
case INIT:
if(c == '$'){
state = BEFORE_SEND;
}else if(c == '>'){
state = BEFORE_EXPECT;
buf_length = expect_index = 0;
while(c = read_res()){
if(c == '\r' || c == '\n'){
if(buf_length > 0){break;}
}else if(buf_length < sizeof(buf)){
buf[buf_length++] = c;
}
}
}else if(!isspace(c)){
state = IGNORE_LINE;
}
break;
case BEFORE_SEND:
if(is_endline){
state = INIT;
break;
}else if(isspace(c)){break;}
state = SENDING;
case SENDING:
if(is_endline){
state = INIT;
}else if(c == '\\'){ // escape char
state = SENDING_ESCAPE;
}else{
send_char(c);
}
break;
case SENDING_ESCAPE:
if(c == 'x'){
state = SENDING_ESCAPE_HEX1;
break;
}
switch(c){
case 'n': c = '\r'; break;
case 'r': c = '\n'; break;
case '\\': c = '\\'; break;
}
send_char(c);
state = SENDING;
break;
case SENDING_ESCAPE_HEX1:
buf[0] = ((c & 0x0F) + (c >= 'A' ? 10 : 0)) << 4;
state = SENDING_ESCAPE_HEX2;
break;
case SENDING_ESCAPE_HEX2:
buf[0] += ((c & 0x0F) + (c >= 'A' ? 10 : 0));
send_char(buf[0]);
state = SENDING;
break;
case BEFORE_EXPECT:
if(is_endline){ // match any
state = INIT;
break;
}else if(isspace(c)){break;}
state = EXPECTING;
case EXPECTING:
if(is_endline){
state = INIT;
}else if((expect_index < buf_length) && (c == buf[expect_index])){
expect_index++;
}else{
state = EXPECT_FAILED;
}
break;
case IGNORE_LINE:
if(is_endline){state = INIT;}
break;
}
}
}
int main(){
printf("%s\r\n", cmd_str);
run();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment