require long command variant to be complete

master
Ondřej Hruška 9 years ago
parent 8e60e0d94a
commit 2e43307477
  1. 4
      main.c
  2. 2
      scpi.pro.user
  3. 37
      scpi_parser.c

@ -110,11 +110,13 @@ const SCPI_command_t scpi_cmd_lang[] = {
}; };
int main() int main()
{ {
// const char *inp = "*IDN?\n"; // const char *inp = "*IDN?\n";
// const char *inp = "FREQ 50\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 = "DATA:BLOB 13.456, #216AbcdEfghIjklMnop\nFREQ 50\r\n";
// const char *inp = "STAT:QUE:ENAB?;ENAB \t 1;ENAB?;:*IDN?\n"; // const char *inp = "STAT:QUE:ENAB?;ENAB \t 1;ENAB?;:*IDN?\n";

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.5.1, 2015-12-02T18:39:29. --> <!-- Written by QtCreator 3.5.1, 2015-12-03T15:53:38. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>

@ -49,7 +49,7 @@ static struct {
SCPI_argval_t args[MAX_PARAM_COUNT]; SCPI_argval_t args[MAX_PARAM_COUNT];
uint8_t arg_i; // next free argument slot index 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 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_LCASE_CHAR(c) INRANGE((c), 'a', 'z')
#define IS_UCASE_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_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_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_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) == '-') #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_LOWER(ucase) ((ucase) + 32)
#define CHAR_TO_UPPER(lcase) ((lcase) - 32) #define CHAR_TO_UPPER(lcase) ((lcase) - 32)
@ -353,7 +354,7 @@ static void pars_cmd_colon(void)
if (pars_match_cmd(true)) { if (pars_match_cmd(true)) {
// ok // ok
} else { } 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; 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) static bool level_str_matches(const char *test, const char *pattern)
{ {
const uint8_t testlen = strlen(test); const uint8_t testlen = strlen(test);
uint8_t pi, ti; uint8_t pat_i, tst_i;
for (pi = 0, ti = 0; pi < strlen(pattern); pi++) { bool long_started = false;
if (ti > testlen) return false; // not match 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 pat_c = pattern[pat_i];
const char tc = test[ti]; // may be at the \0 terminator 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 // optional char
if (char_equals_ci(pc, tc)) { if (char_equals_ci(pat_c, tst_c)) {
ti++; // advance test string 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 continue; // next pi - tc stays in place
} else { } else {
// require exact match (case insensitive) // require exact match (case insensitive)
if (char_equals_ci(pc, tc)) { if (char_equals_ci(pat_c, tst_c)) {
ti++; tst_i++;
} else { } else {
return false; return false;
} }
} }
} }
return (ti >= testlen); return (tst_i >= testlen);
} }
@ -740,7 +745,7 @@ static void pars_blob_preamble_char(uint8_t c)
return; return;
} }
if (!IS_INT_CHAR(c)) { if (!IS_NUMBER_CHAR(c)) {
printf("ERROR expected ASCII 0-9 after #n\n");//TODO error printf("ERROR expected ASCII 0-9 after #n\n");//TODO error
pst.state = PARS_DISCARD_LINE; pst.state = PARS_DISCARD_LINE;
return; return;

Loading…
Cancel
Save