Created
March 19, 2016 04:57
-
-
Save fenrir-naru/90f1a308ab98477c7cd0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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