func for matching level strings

master
Ondřej Hruška 9 years ago
parent 3bef041547
commit 588bb22270
  1. 6
      Makefile
  2. 20
      main.c
  3. BIN
      main.elf
  4. 86
      scpi_parser.c
  5. 4
      scpi_parser.h

@ -0,0 +1,6 @@
all: main.c scpi_parser.c scpi_parser.h
gcc main.c scpi_parser.c -o main.elf
run: all
./main.elf

@ -7,8 +7,8 @@ void cmd_APPL_SIN_cb(const SCPI_argval_t *args);
void cmd_APPL_TRI_cb(const SCPI_argval_t *args);
void cmd_FREQ_cb(const SCPI_argval_t *args);
const SCPI_command_t scpi_cmd_lang[] = {
const uint16_t scpi_cmd_lang_len = 4;
const SCPI_command_t scpi_cmd_lang[4] = {
{
.level_cnt = 1, .levels = {"*IDN?"},
.param_cnt = 0, .params = {},
@ -60,5 +60,19 @@ void cmd_FREQ_cb(const SCPI_argval_t *args)
int main(int argc, const char**argv)
{
const char *inp = argv[1];
printf("cmd lang len = %d\n", (int) sizeof(scpi_cmd_lang)/sizeof(SCPI_command_t));
// printf("%d\n", char_equals_ci('a','A'));
// printf("%d\n", char_equals_ci('z','z'));
// printf("%d\n", char_equals_ci('z','Z'));
// printf("%d\n", char_equals_ci('M','M'));
// printf("%d\n", char_equals_ci('M','q'));
// printf("%d\n", char_equals_ci('*','*'));
// printf("%d\n", char_equals_ci('a',' '));
// printf("%d\n", level_str_matches("A","A"));
// printf("%d\n", level_str_matches("AbCdE","ABCDE"));
// printf("%d\n", level_str_matches("*IDN?","*IDN?"));
// printf("%d\n", level_str_matches("*IDN?","*IDN"));
// printf("%d\n", level_str_matches("MEAS","MEASure"));
//printf("%d\n", level_str_matches("*FBAZ?","*FxyzBAZ?"));
}

Binary file not shown.

@ -6,7 +6,6 @@
#include <stdio.h>
#include <stdlib.h>
typedef enum {
PARS_COMMAND,
PARS_ARG, // collect generic arg, terminated with comma or newline. Leading and trailing whitespace ignored.
@ -60,9 +59,14 @@ static void pars_match_level(void); // match charbuf content to a level, advance
// char matching
#define INRANGE(c, a, b) ((c) >= (a) && (c) <= (b))
#define IS_WHITESPACE(c) (INRANGE((c), 0, 9) || INRANGE((c), 11, 32))
#define IS_IDENT_CHAR(c) (INRANGE((c), 'a', 'z') || INRANGE((c), 'A', 'Z') || INRANGE((c), '0', '9') || (c) == '_')
#define IS_INT_CHAR(c) INRANGE((c), '0', '9')
#define IS_FLOAT_CHAR(c) (IS_INT_CHAR((c)) || (c) == '.' || (c) == 'e' || (c) == 'E' || (e) == '+' || (e) == '-')
#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_IDENT_CHAR(c) (IS_LCASE_CHAR((c)) || IS_UCASE_CHAR((c)) || IS_NUMBER_CHAR((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' || (e) == '+' || (e) == '-')
static void pars_reset_cmd(void)
@ -123,7 +127,7 @@ void scpi_receive_byte(const uint8_t b)
// invalid or delimiter
if (IS_WHITESPACE(c)) {
pars_cmd_space(); // whitespace in command - end of command?
// pars_cmd_space(); // whitespace in command - end of command?
break;
}
@ -133,11 +137,11 @@ void scpi_receive_byte(const uint8_t b)
break;
case '\n': // line terminator
pars_cmd_newline();
// pars_cmd_newline();
break;
case ';': // ends a command, does not reset cmd path.
pars_cmd_semicolon();
// pars_cmd_semicolon();
break;
default:
@ -159,9 +163,6 @@ void scpi_receive_byte(const uint8_t b)
}
// whitespace (INRANGE(c, 0, 9) || INRANGE(c, 11, 32))
static void pars_cmd_colon(void)
{
if (pstate.charbuf_ptr == 0) {
@ -182,6 +183,71 @@ static void pars_cmd_colon(void)
}
}
#define CHAR_TO_LOWER(ucase) ((ucase) + 32)
#define CHAR_TO_UPPER(lcase) ((lcase) - 32)
/** Check if chars equal, ignore case */
static bool char_equals_ci(char a, char b)
{
if (IS_LCASE_CHAR(a)) {
if (IS_LCASE_CHAR(b)) {
return a == b;
} else if (IS_UCASE_CHAR(b)) {
return a == CHAR_TO_LOWER(b);
} else {
return false;
}
} else if (IS_UCASE_CHAR(a)) {
if (IS_UCASE_CHAR(b)) {
return a == b;
} else if (IS_LCASE_CHAR(b)) {
return a == CHAR_TO_UPPER(b);
} else {
return false;
}
} else {
return a == b; // exact match, not letters
}
}
/** Check if command matches a pattern */
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
const char pc = pattern[pi];
const char tc = test[ti]; // may be at the \0 terminator
if (IS_LCASE_CHAR(pc)) {
// optional char
if (char_equals_ci(pc, tc)) {
ti++; // advance test string
}
continue; // next pi - tc stays in place
} else {
// require exact match (case insensitive)
if (char_equals_ci(pc, tc)) {
ti++;
} else {
return false;
}
}
}
return (ti >= testlen);
}
static void pars_match_level(void)
{

@ -45,4 +45,8 @@ typedef struct {
} SCPI_command_t;
extern const uint16_t scpi_cmd_lang_len; // number of commands
extern const SCPI_command_t scpi_cmd_lang[];
// --------------- functions --------------------

Loading…
Cancel
Save