From f62cd8df28d6e57a675c4ddce9d9f9e1b49ee42a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sun, 6 Dec 2015 00:04:51 +0100 Subject: [PATCH] chardata --- main.c | 14 ++++++++++++++ source/scpi_builtins.c | 2 +- source/scpi_parser.c | 39 +++++++++++++++++++++++++++++++++------ source/scpi_parser.h | 13 +++++++++---- 4 files changed, 57 insertions(+), 11 deletions(-) diff --git a/main.c b/main.c index c3003b7..f6f2c02 100644 --- a/main.c +++ b/main.c @@ -29,6 +29,9 @@ int main(void) send_cmd("USERERROR\n"); // string send_cmd("SYST:ERR:COUNT?\n"); send_cmd("SYST:ERR:NEXT?\n"); + + // test chardata + send_cmd("CHARD FOOBAR123_MOO_abcdef_HELLO, 12\n"); } @@ -100,6 +103,12 @@ void cmd_USRERR_cb(const SCPI_argval_t *args) } +void cmd_CHARD_cb(const SCPI_argval_t *args) +{ + printf("CHARData cb: %s, arg2 = %d", args[0].CHARDATA, args[1].INT); +} + + // Command definition (mandatory commands are built-in) const SCPI_command_t scpi_commands[] = { { @@ -123,5 +132,10 @@ const SCPI_command_t scpi_commands[] = { .levels = {"USeRERRor"}, .callback = cmd_USRERR_cb }, + { + .levels = {"CHARData"}, + .params = {SCPI_DT_CHARDATA, SCPI_DT_INT}, + .callback = cmd_CHARD_cb + }, {/*END*/} }; diff --git a/source/scpi_builtins.c b/source/scpi_builtins.c index e988758..4f2c113 100644 --- a/source/scpi_builtins.c +++ b/source/scpi_builtins.c @@ -9,7 +9,7 @@ #include "scpi_regs.h" // response buffer -static char sbuf[256]; +static char sbuf[256]; // must be long enough to contain an error message // ---------------- BUILTIN SCPI COMMANDS ------------------ diff --git a/source/scpi_parser.c b/source/scpi_parser.c index 8bb1758..42c2ca4 100644 --- a/source/scpi_parser.c +++ b/source/scpi_parser.c @@ -21,11 +21,16 @@ #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_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)) || (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))) +// A-Z a-z 0-9 _ +#define IS_CHARDATA_CHAR(c) (IS_LCASE_CHAR((c)) || IS_UCASE_CHAR((c)) || IS_NUMBER_CHAR((c)) || (c) == '_') +// A-Z a-z 0-9 _ * ? +#define IS_IDENT_CHAR(c) (IS_CHARDATA_CHAR((c)) || (c) == '*' || (c) == '?') +// 0-9 - + +#define IS_INT_CHAR(c) (IS_NUMBER_CHAR((c)) || (c) == '-' || (c) == '+') +// 0-9 . + - eE +#define IS_FLOAT_CHAR(c) (IS_NUMBER_CHAR((c)) || (c) == '.' || (c) == 'e' || (c) == 'E' || (c) == '+' || (c) == '-') #define CHAR_TO_LOWER(ucase) ((ucase) + 32) #define CHAR_TO_UPPER(lcase) ((lcase) - 32) @@ -77,7 +82,7 @@ static struct { // buffer for error messages -static char ebuf[256]; +static char ebuf[100]; // ---------------- PRIVATE PROTOTYPES ------------------ @@ -718,6 +723,17 @@ static void pars_arg_char(char c) } break; + case SCPI_DT_CHARDATA: + if (!IS_CHARDATA_CHAR(c)) { + sprintf(ebuf, "'%c' not allowed in CHARDATA.", c); + scpi_add_error(E_CMD_INVALID_CHARACTER_DATA, ebuf); + + pst.state = PARS_DISCARD_LINE; + } else { + charbuf_append(c); + } + break; + case SCPI_DT_STRING: if (c == '\'' || c == '"') { pst.state = PARS_ARG_STRING; @@ -857,7 +873,7 @@ static void arg_convert_value(void) case SCPI_DT_STRING: if (strlen(pst.charbuf) > SCPI_MAX_STRING_LEN) { - scpi_add_error(E_CMD_INVALID_STRING_DATA, "String too long."); + scpi_add_error(E_CMD_STRING_DATA_ERROR, "String too long."); pst.state = PARS_DISCARD_LINE; } else { @@ -866,6 +882,17 @@ static void arg_convert_value(void) break; + case SCPI_DT_CHARDATA: + if (strlen(pst.charbuf) > SCPI_MAX_STRING_LEN) { // using common buffer + scpi_add_error(E_CMD_CHARACTER_DATA_TOO_LONG, NULL); + + pst.state = PARS_DISCARD_LINE; + } else { + strcpy(dest->CHARDATA, pst.charbuf); // copy the character data text + } + + break; + default: // impossible scpi_add_error(E_DEV_SYSTEM_ERROR, "Unexpected argument data type."); diff --git a/source/scpi_parser.h b/source/scpi_parser.h index 7f3954c..ec0c392 100644 --- a/source/scpi_parser.h +++ b/source/scpi_parser.h @@ -6,8 +6,8 @@ #include "scpi_builtins.h" #include "scpi_regs.h" -#define SCPI_MAX_CMD_LEN 12 -#define SCPI_MAX_STRING_LEN 12 +#define SCPI_MAX_CMD_LEN 16 // 12 according to spec +#define SCPI_MAX_STRING_LEN 64 // 12 according to spec #define SCPI_MAX_LEVEL_COUNT 4 #define SCPI_MAX_PARAM_COUNT 4 @@ -17,6 +17,7 @@ typedef enum { SCPI_DT_FLOAT, // float with support for scientific notation SCPI_DT_INT, // integer (may be signed) SCPI_DT_BOOL, // 0, 1, ON, OFF + SCPI_DT_CHARDATA, // string without quotes - [A-Za-z0-9_] SCPI_DT_STRING, // quoted string, max 12 chars; no escapes. SCPI_DT_BLOB, // binary block, callback: uint32_t holding number of bytes } SCPI_datatype_t; @@ -25,10 +26,14 @@ typedef enum { /** Arguemnt value (union) */ typedef union { float FLOAT; + int32_t INT; - bool BOOL; - char STRING[SCPI_MAX_STRING_LEN + 1]; // terminator uint32_t BLOB_LEN; + + bool BOOL; + + char STRING[SCPI_MAX_STRING_LEN + 1]; + char CHARDATA[SCPI_MAX_STRING_LEN + 1]; } SCPI_argval_t;