From 2e43307477b7703aa01b72c6817c8b80a7ad2691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Thu, 3 Dec 2015 19:38:54 +0100 Subject: [PATCH] require long command variant to be complete --- main.c | 4 +++- scpi.pro.user | 2 +- scpi_parser.c | 37 +++++++++++++++++++++---------------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/main.c b/main.c index d11339a..76ee213 100644 --- a/main.c +++ b/main.c @@ -110,11 +110,13 @@ const SCPI_command_t scpi_cmd_lang[] = { }; + int main() { + // const char *inp = "*IDN?\n"; // const char *inp = "FREQ 50\n"; - const char *inp = "DISPlay:TEXT 'ban\\\\'ana', OFF\nDISP:TEXT \"dblquot!\", 1\r\nFREQ 50\r\n"; + const char *inp = "DISP:TEXT 'ban\\\\ana', OFF\nDISP:TEXT \"dblquot!\", 1\r\nFREQ 50\r\n"; // const char *inp = "DATA:BLOB 13.456, #216AbcdEfghIjklMnop\nFREQ 50\r\n"; // const char *inp = "STAT:QUE:ENAB?;ENAB \t 1;ENAB?;:*IDN?\n"; diff --git a/scpi.pro.user b/scpi.pro.user index 98926fa..35cb7cc 100644 --- a/scpi.pro.user +++ b/scpi.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/scpi_parser.c b/scpi_parser.c index bc155a9..a4fd813 100644 --- a/scpi_parser.c +++ b/scpi_parser.c @@ -49,7 +49,7 @@ static struct { SCPI_argval_t args[MAX_PARAM_COUNT]; uint8_t arg_i; // next free argument slot index -} pst; // initialized by all zeros +} pst = {0}; // initialized by all zeros static void pars_cmd_colon(void); // colon starting a command sub-segment @@ -79,10 +79,11 @@ static void arg_convert_value(void); #define IS_LCASE_CHAR(c) INRANGE((c), 'a', 'z') #define IS_UCASE_CHAR(c) INRANGE((c), 'A', 'Z') #define IS_NUMBER_CHAR(c) INRANGE((c), '0', '9') +#define IS_MULTIPLIER_CHAR(c) ((c) == 'k' || (c) == 'M' || (c) == 'G' || (c) == 'm' || (c) == 'u' || (c) == 'n' || (c) == 'p') #define IS_IDENT_CHAR(c) (IS_LCASE_CHAR((c)) || IS_UCASE_CHAR((c)) || IS_NUMBER_CHAR((c)) || (c) == '_' || (c) == '*' || (c) == '?') -#define IS_INT_CHAR(c) IS_NUMBER_CHAR((c)) -#define IS_FLOAT_CHAR(c) (IS_NUMBER_CHAR((c)) || (c) == '.' || (c) == 'e' || (c) == 'E' || (c) == '+' || (c) == '-') +#define IS_INT_CHAR(c) (IS_NUMBER_CHAR((c)) || (c) == '-' || (c) == '+' || IS_MULTIPLIER_CHAR((c))) +#define IS_FLOAT_CHAR(c) (IS_NUMBER_CHAR((c)) || (c) == '.' || (c) == 'e' || (c) == 'E' || (c) == '+' || (c) == '-' || IS_MULTIPLIER_CHAR((c))) #define CHAR_TO_LOWER(ucase) ((ucase) + 32) #define CHAR_TO_UPPER(lcase) ((lcase) - 32) @@ -353,7 +354,7 @@ static void pars_cmd_colon(void) if (pars_match_cmd(true)) { // ok } else { - printf("ERROR no such command (colon).\n");//TODO error + printf("ERROR no such command: %s\n", pst.charbuf);//TODO error pst.state = PARS_DISCARD_LINE; } } @@ -466,31 +467,35 @@ static bool char_equals_ci(char a, char b) static bool level_str_matches(const char *test, const char *pattern) { const uint8_t testlen = strlen(test); - uint8_t pi, ti; - for (pi = 0, ti = 0; pi < strlen(pattern); pi++) { - if (ti > testlen) return false; // not match + uint8_t pat_i, tst_i; + bool long_started = false; + for (pat_i = 0, tst_i = 0; pat_i < strlen(pattern); pat_i++) { + if (tst_i > testlen) return false; // not match - const char pc = pattern[pi]; - const char tc = test[ti]; // may be at the \0 terminator + const char pat_c = pattern[pat_i]; + const char tst_c = test[tst_i]; // may be at the \0 terminator - if (IS_LCASE_CHAR(pc)) { + if (IS_LCASE_CHAR(pat_c)) { // optional char - if (char_equals_ci(pc, tc)) { - ti++; // advance test string + if (char_equals_ci(pat_c, tst_c)) { + tst_i++; // advance test string + long_started = true; + } else { + if (long_started) return false; // once long variant started, it must be completed. } continue; // next pi - tc stays in place } else { // require exact match (case insensitive) - if (char_equals_ci(pc, tc)) { - ti++; + if (char_equals_ci(pat_c, tst_c)) { + tst_i++; } else { return false; } } } - return (ti >= testlen); + return (tst_i >= testlen); } @@ -740,7 +745,7 @@ static void pars_blob_preamble_char(uint8_t c) return; } - if (!IS_INT_CHAR(c)) { + if (!IS_NUMBER_CHAR(c)) { printf("ERROR expected ASCII 0-9 after #n\n");//TODO error pst.state = PARS_DISCARD_LINE; return;