From 28b17f7935b446edec4dfa85974ea1bf6fcfa1ed Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 1 Feb 2022 18:48:16 +0100 Subject: [PATCH 01/22] output block data with delimiter scpi-99 6.2.3.4 and 6.2.6 suggest returning multiple blocks is valid, so SCPI_ResultArbitraryBlockHeader() needs to insert a delimiter, other changes are: accepting _GLIBCXX_HAVE_STDBOOL_H, testing for non-NULL data in writeData(), and some spelling fixes. --- libscpi/inc/scpi/types.h | 6 +++--- libscpi/src/parser.c | 25 ++++++++++++++----------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/libscpi/inc/scpi/types.h b/libscpi/inc/scpi/types.h index ce238dc1..f0b9249c 100644 --- a/libscpi/inc/scpi/types.h +++ b/libscpi/inc/scpi/types.h @@ -50,7 +50,7 @@ extern "C" { #endif -#if !HAVE_STDBOOL +#if (!HAVE_STDBOOL) && (!_GLIBCXX_HAVE_STDBOOL_H) typedef unsigned char bool; #endif @@ -354,7 +354,7 @@ extern "C" { #if USE_COMMAND_TAGS int32_t tag; #endif /* USE_COMMAND_TAGS */ - }; +}; struct _scpi_interface_t { scpi_error_callback_t error; @@ -381,7 +381,7 @@ extern "C" { void * user_context; scpi_parser_state_t parser_state; const char * idn[4]; - size_t arbitrary_reminding; + size_t arbitrary_remaining; }; enum _scpi_array_format_t { diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c index 058cde7b..18aa889c 100644 --- a/libscpi/src/parser.c +++ b/libscpi/src/parser.c @@ -50,11 +50,11 @@ * Write data to SCPI output * @param context * @param data - * @param len - lenght of data to be written + * @param len - length of data to be written * @return number of bytes written */ static size_t writeData(scpi_t * context, const char * data, size_t len) { - if (len > 0) { + if ((len > 0) && (data != NULL)) { return context->interface->write(context, data, len); } else { return 0; @@ -134,7 +134,7 @@ static scpi_bool_t processCommand(scpi_t * context) { context->cmd_error = FALSE; context->output_count = 0; context->input_count = 0; - context->arbitrary_reminding = 0; + context->arbitrary_remaining = 0; /* if callback exists - call command callback */ if (cmd->callback != NULL) { @@ -221,7 +221,7 @@ scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len) { cmd_prev = state->programHeader; } else { /* place undefined header with error */ - /* calculate length of errornouse header and trim \r\n */ + /* calculate length of errorenous header and trim \r\n */ size_t r2 = r; while (r2 > 0 && (data[r2 - 1] == '\r' || data[r2 - 1] == '\n')) r2--; SCPI_ErrorPushEx(context, SCPI_ERROR_UNDEFINED_HEADER, data, r2); @@ -238,7 +238,7 @@ scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len) { } - /* conditionaly write new line */ + /* conditionally write new line */ writeNewLine(context); return result; @@ -506,7 +506,7 @@ size_t SCPI_ResultDouble(scpi_t * context, double val) { } /** - * Write string withn " to the result + * Write string within "" to the result * @param context * @param data * @return @@ -606,6 +606,7 @@ size_t SCPI_ResultError(scpi_t * context, scpi_error_t * error) { * @return */ size_t SCPI_ResultArbitraryBlockHeader(scpi_t * context, size_t len) { + size_t result = 0; char block_header[12]; size_t header_len; block_header[0] = '#'; @@ -614,8 +615,10 @@ size_t SCPI_ResultArbitraryBlockHeader(scpi_t * context, size_t len) { header_len = strlen(block_header + 2); block_header[1] = (char) (header_len + '0'); - context->arbitrary_reminding = len; - return writeData(context, block_header, header_len + 2); + context->arbitrary_remaining = len; + result = writeDelimiter(context); + result += writeData(context, block_header, header_len + 2); + return result; } /** @@ -627,14 +630,14 @@ size_t SCPI_ResultArbitraryBlockHeader(scpi_t * context, size_t len) { */ size_t SCPI_ResultArbitraryBlockData(scpi_t * context, const void * data, size_t len) { - if (context->arbitrary_reminding < len) { + if (context->arbitrary_remaining < len) { SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); return 0; } - context->arbitrary_reminding -= len; + context->arbitrary_remaining -= len; - if (context->arbitrary_reminding == 0) { + if (context->arbitrary_remaining == 0) { context->output_count++; } From 8ed26233d7cb833337434f4e02ad1cb531722310 Mon Sep 17 00:00:00 2001 From: helge Date: Wed, 2 Feb 2022 22:33:22 +0100 Subject: [PATCH 02/22] fix typos --- libscpi/inc/scpi/config.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libscpi/inc/scpi/config.h b/libscpi/inc/scpi/config.h index c391e120..ce376efb 100644 --- a/libscpi/inc/scpi/config.h +++ b/libscpi/inc/scpi/config.h @@ -49,9 +49,9 @@ extern "C" { #endif /* set the termination character(s) */ -#define LINE_ENDING_CR "\r" /* use a carriage return as termination charcter */ -#define LINE_ENDING_LF "\n" /* use a line feed as termination charcter */ -#define LINE_ENDING_CRLF "\r\n" /* use carriage return + line feed as termination charcters */ +#define LINE_ENDING_CR "\r" /* use a carriage return as termination character */ +#define LINE_ENDING_LF "\n" /* use a line feed as termination character */ +#define LINE_ENDING_CRLF "\r\n" /* use carriage return + line feed as termination characters */ #ifndef SCPI_LINE_ENDING #define SCPI_LINE_ENDING LINE_ENDING_CRLF @@ -59,7 +59,7 @@ extern "C" { /** * Detect, if it has limited resources or it is running on a full blown operating system. - * All values can be overiden by scpi_user_config.h + * All values can be overridden by scpi_user_config.h */ #define SYSTEM_BARE_METAL 0 #define SYSTEM_FULL_BLOWN 1 @@ -76,8 +76,8 @@ extern "C" { * 0 = Minimal set of errors * 1 = Full set of errors * - * For small systems, full set of errors will occupy large ammount of data - * It is enabled by default on full blown systems and disabled on limited bare metal systems + * For small systems, full set of errors will occupy large amount of data. + * It is enabled by default on full blown systems and disabled on limited bare metal systems. */ #ifndef USE_FULL_ERROR_LIST #define USE_FULL_ERROR_LIST SYSTEM_TYPE @@ -174,14 +174,14 @@ extern "C" { #define USE_UNITS_ELECTRIC_CHARGE_CONDUCTANCE SYSTEM_TYPE #endif -/* define local macros depending on existance of strnlen */ +/* define local macros depending on existence of strnlen */ #if HAVE_STRNLEN #define SCPIDEFINE_strnlen(s, l) strnlen((s), (l)) #else #define SCPIDEFINE_strnlen(s, l) BSD_strnlen((s), (l)) #endif -/* define local macros depending on existance of strncasecmp and strnicmp */ +/* define local macros depending on existence of strncasecmp and strnicmp */ #if HAVE_STRNCASECMP #define SCPIDEFINE_strncasecmp(s1, s2, l) strncasecmp((s1), (s2), (l)) #elif HAVE_STRNICMP From bc4f1d5069655e9166f09d84030f538a2c114cdb Mon Sep 17 00:00:00 2001 From: helge Date: Thu, 3 Feb 2022 14:24:57 +0100 Subject: [PATCH 03/22] introduce SCPI_HelpQ add SCPI_HelpQ callback , optional .description strings and provide conditional initializer macros dependent on config settings for USE_COMMAND_TAGS and USE_COMMAND_DESCRIPTIONS. --- examples/common/scpi-def.c | 15 +++++ examples/common/scpi-def.cpp | 105 ++++++++++++++++++++--------------- libscpi/inc/scpi/config.h | 4 ++ libscpi/inc/scpi/minimal.h | 2 +- libscpi/inc/scpi/types.h | 13 ++++- libscpi/src/minimal.c | 33 +++++++++++ 6 files changed, 123 insertions(+), 49 deletions(-) diff --git a/examples/common/scpi-def.c b/examples/common/scpi-def.c index 50216210..67c37755 100644 --- a/examples/common/scpi-def.c +++ b/examples/common/scpi-def.c @@ -353,7 +353,22 @@ static scpi_result_t My_CoreTstQ(scpi_t * context) { return SCPI_RES_OK; } +#if USE_COMMAND_DESCRIPTIONS +#define SCPI_CMD_DESC(S) .description=(S), +#else +#define SCPI_CMD_DESC(S) +#endif + +#if USE_COMMAND_TAGS +#define SCPI_CMD_TAG(T) .tag=(T), +#else +#define SCPI_CMD_TAG(T) +#endif + const scpi_command_t scpi_commands[] = { + /* Optional help commmand */ + {.pattern = "HELP?", .callback = SCPI_HelpQ, SCPI_CMD_DESC("\t - list supported commands")}, + /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1) */ { .pattern = "*CLS", .callback = SCPI_CoreCls,}, { .pattern = "*ESE", .callback = SCPI_CoreEse,}, diff --git a/examples/common/scpi-def.cpp b/examples/common/scpi-def.cpp index abbc80a6..f8940468 100644 --- a/examples/common/scpi-def.cpp +++ b/examples/common/scpi-def.cpp @@ -353,60 +353,75 @@ static scpi_result_t My_CoreTstQ(scpi_t * context) { return SCPI_RES_OK; } +#if USE_COMMAND_DESCRIPTIONS +#define SCPI_CMD_DESC(S) (S), +#else +#define SCPI_CMD_DESC(S) +#endif + +#if USE_COMMAND_TAGS +#define SCPI_CMD_TAG(T) (T), +#else +#define SCPI_CMD_TAG(T) +#endif + const scpi_command_t scpi_commands[] = { + /* Optional help command */ + {"HELP?", SCPI_HelpQ, SCPI_CMD_DESC("\t - list supported commands") SCPI_CMD_TAG(0)}, + /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1) */ - {"*CLS", SCPI_CoreCls, 0}, - {"*ESE", SCPI_CoreEse, 0}, - {"*ESE?", SCPI_CoreEseQ, 0}, - {"*ESR?", SCPI_CoreEsrQ, 0}, - {"*IDN?", SCPI_CoreIdnQ, 0}, - {"*OPC", SCPI_CoreOpc, 0}, - {"*OPC?", SCPI_CoreOpcQ, 0}, - {"*RST", SCPI_CoreRst, 0}, - {"*SRE", SCPI_CoreSre, 0}, - {"*SRE?", SCPI_CoreSreQ, 0}, - {"*STB?", SCPI_CoreStbQ, 0}, - {"*TST?", My_CoreTstQ, 0}, - {"*WAI", SCPI_CoreWai, 0}, + {"*CLS", SCPI_CoreCls, SCPI_CMD_TAG(0)}, + {"*ESE", SCPI_CoreEse, SCPI_CMD_TAG(0)}, + {"*ESE?", SCPI_CoreEseQ, SCPI_CMD_TAG(0)}, + {"*ESR?", SCPI_CoreEsrQ, SCPI_CMD_TAG(0)}, + {"*IDN?", SCPI_CoreIdnQ, SCPI_CMD_TAG(0)}, + {"*OPC", SCPI_CoreOpc, SCPI_CMD_TAG(0)}, + {"*OPC?", SCPI_CoreOpcQ, SCPI_CMD_TAG(0)}, + {"*RST", SCPI_CoreRst, SCPI_CMD_TAG(0)}, + {"*SRE", SCPI_CoreSre, SCPI_CMD_TAG(0)}, + {"*SRE?", SCPI_CoreSreQ, SCPI_CMD_TAG(0)}, + {"*STB?", SCPI_CoreStbQ, SCPI_CMD_TAG(0)}, + {"*TST?", My_CoreTstQ, SCPI_CMD_TAG(0)}, + {"*WAI", SCPI_CoreWai, SCPI_CMD_TAG(0)}, /* Required SCPI commands (SCPI std V1999.0 4.2.1) */ - {"SYSTem:ERRor[:NEXT]?", SCPI_SystemErrorNextQ, 0}, - {"SYSTem:ERRor:COUNt?", SCPI_SystemErrorCountQ, 0}, - {"SYSTem:VERSion?", SCPI_SystemVersionQ, 0}, + {"SYSTem:ERRor[:NEXT]?", SCPI_SystemErrorNextQ, SCPI_CMD_TAG(0)}, + {"SYSTem:ERRor:COUNt?", SCPI_SystemErrorCountQ, SCPI_CMD_TAG(0)}, + {"SYSTem:VERSion?", SCPI_SystemVersionQ, SCPI_CMD_TAG(0)}, - //{"STATus:OPERation?", scpi_stub_callback, 0}, - //{"STATus:OPERation:EVENt?", scpi_stub_callback, 0}, - //{"STATus:OPERation:CONDition?", scpi_stub_callback, 0}, - //{"STATus:OPERation:ENABle", scpi_stub_callback, 0}, - //{"STATus:OPERation:ENABle?", scpi_stub_callback, 0}, + //{"STATus:OPERation?", scpi_stub_callback, SCPI_CMD_TAG(0)}, + //{"STATus:OPERation:EVENt?", scpi_stub_callback, SCPI_CMD_TAG(0)}, + //{"STATus:OPERation:CONDition?", scpi_stub_callback, SCPI_CMD_TAG(0)}, + //{"STATus:OPERation:ENABle", scpi_stub_callback, SCPI_CMD_TAG(0)}, + //{"STATus:OPERation:ENABle?", scpi_stub_callback, SCPI_CMD_TAG(0)}, - {"STATus:QUEStionable[:EVENt]?", SCPI_StatusQuestionableEventQ, 0}, - //{"STATus:QUEStionable:CONDition?", scpi_stub_callback, 0}, - {"STATus:QUEStionable:ENABle", SCPI_StatusQuestionableEnable, 0}, - {"STATus:QUEStionable:ENABle?", SCPI_StatusQuestionableEnableQ, 0}, + {"STATus:QUEStionable[:EVENt]?", SCPI_StatusQuestionableEventQ, SCPI_CMD_TAG(0)}, + //{"STATus:QUEStionable:CONDition?", scpi_stub_callback, SCPI_CMD_TAG(0)}, + {"STATus:QUEStionable:ENABle", SCPI_StatusQuestionableEnable, SCPI_CMD_TAG(0)}, + {"STATus:QUEStionable:ENABle?", SCPI_StatusQuestionableEnableQ, SCPI_CMD_TAG(0)}, - {"STATus:PRESet", SCPI_StatusPreset, 0}, + {"STATus:PRESet", SCPI_StatusPreset, SCPI_CMD_TAG(0)}, /* DMM */ - {"MEASure:VOLTage:DC?", DMM_MeasureVoltageDcQ, 0}, - {"CONFigure:VOLTage:DC", DMM_ConfigureVoltageDc, 0}, - {"MEASure:VOLTage:DC:RATio?", SCPI_StubQ, 0}, - {"MEASure:VOLTage:AC?", DMM_MeasureVoltageAcQ, 0}, - {"MEASure:CURRent:DC?", SCPI_StubQ, 0}, - {"MEASure:CURRent:AC?", SCPI_StubQ, 0}, - {"MEASure:RESistance?", SCPI_StubQ, 0}, - {"MEASure:FRESistance?", SCPI_StubQ, 0}, - {"MEASure:FREQuency?", SCPI_StubQ, 0}, - {"MEASure:PERiod?", SCPI_StubQ, 0}, - - {"SYSTem:COMMunication:TCPIP:CONTROL?", SCPI_SystemCommTcpipControlQ, 0}, - - {"TEST:BOOL", TEST_Bool, 0}, - {"TEST:CHOice?", TEST_ChoiceQ, 0}, - {"TEST#:NUMbers#", TEST_Numbers, 0}, - {"TEST:TEXT", TEST_Text, 0}, - {"TEST:ARBitrary?", TEST_ArbQ, 0}, - {"TEST:CHANnellist", TEST_Chanlst, 0}, + {"MEASure:VOLTage:DC?", DMM_MeasureVoltageDcQ, SCPI_CMD_TAG(0)}, + {"CONFigure:VOLTage:DC", DMM_ConfigureVoltageDc, SCPI_CMD_TAG(0)}, + {"MEASure:VOLTage:DC:RATio?", SCPI_StubQ, SCPI_CMD_TAG(0)}, + {"MEASure:VOLTage:AC?", DMM_MeasureVoltageAcQ, SCPI_CMD_TAG(0)}, + {"MEASure:CURRent:DC?", SCPI_StubQ, SCPI_CMD_TAG(0)}, + {"MEASure:CURRent:AC?", SCPI_StubQ, SCPI_CMD_TAG(0)}, + {"MEASure:RESistance?", SCPI_StubQ, SCPI_CMD_TAG(0)}, + {"MEASure:FRESistance?", SCPI_StubQ, SCPI_CMD_TAG(0)}, + {"MEASure:FREQuency?", SCPI_StubQ, SCPI_CMD_TAG(0)}, + {"MEASure:PERiod?", SCPI_StubQ, SCPI_CMD_TAG(0)}, + + {"SYSTem:COMMunication:TCPIP:CONTROL?", SCPI_SystemCommTcpipControlQ, SCPI_CMD_TAG(0)}, + + {"TEST:BOOL", TEST_Bool, SCPI_CMD_TAG(0)}, + {"TEST:CHOice?", TEST_ChoiceQ, SCPI_CMD_TAG(0)}, + {"TEST#:NUMbers#", TEST_Numbers, SCPI_CMD_TAG(0)}, + {"TEST:TEXT", TEST_Text, SCPI_CMD_TAG(0)}, + {"TEST:ARBitrary?", TEST_ArbQ, SCPI_CMD_TAG(0)}, + {"TEST:CHANnellist", TEST_Chanlst, SCPI_CMD_TAG(0)}, SCPI_CMD_LIST_END }; diff --git a/libscpi/inc/scpi/config.h b/libscpi/inc/scpi/config.h index ce376efb..2f9583a1 100644 --- a/libscpi/inc/scpi/config.h +++ b/libscpi/inc/scpi/config.h @@ -110,6 +110,10 @@ extern "C" { #define USE_COMMAND_TAGS 1 #endif +#ifndef USE_COMMAND_DESCRIPTIONS +#define USE_COMMAND_DESCRIPTIONS 1 +#endif + #ifndef USE_DEPRECATED_FUNCTIONS #define USE_DEPRECATED_FUNCTIONS 1 #endif diff --git a/libscpi/inc/scpi/minimal.h b/libscpi/inc/scpi/minimal.h index e14f1ed6..8b87b777 100644 --- a/libscpi/inc/scpi/minimal.h +++ b/libscpi/inc/scpi/minimal.h @@ -59,7 +59,7 @@ extern "C" { scpi_result_t SCPI_StatusOperationEnableQ(scpi_t * context); scpi_result_t SCPI_StatusOperationEnable(scpi_t * context); scpi_result_t SCPI_StatusPreset(scpi_t * context); - + scpi_result_t SCPI_HelpQ(scpi_t * context); #ifdef __cplusplus } diff --git a/libscpi/inc/scpi/types.h b/libscpi/inc/scpi/types.h index f0b9249c..a79e4fc7 100644 --- a/libscpi/inc/scpi/types.h +++ b/libscpi/inc/scpi/types.h @@ -114,10 +114,14 @@ extern "C" { typedef struct _scpi_command_t scpi_command_t; -#if USE_COMMAND_TAGS - #define SCPI_CMD_LIST_END {NULL, NULL, 0} +#if USE_COMMAND_DESCRIPTIONS && USE_COMMAND_TAGS +#define SCPI_CMD_LIST_END {NULL, NULL, NULL, 0} +#elif USE_COMMAND_DESCRIPTIONS +#define SCPI_CMD_LIST_END {NULL, NULL, NULL} +#elif USE_COMMAND_TAGS +#define SCPI_CMD_LIST_END {NULL, NULL, 0} #else - #define SCPI_CMD_LIST_END {NULL, NULL} +#define SCPI_CMD_LIST_END {NULL, NULL} #endif @@ -351,6 +355,9 @@ extern "C" { struct _scpi_command_t { const char * pattern; scpi_command_callback_t callback; +#if USE_COMMAND_DESCRIPTIONS + const char * description; +#endif /* USE_COMMAND_DESCRIPTIONS */ #if USE_COMMAND_TAGS int32_t tag; #endif /* USE_COMMAND_TAGS */ diff --git a/libscpi/src/minimal.c b/libscpi/src/minimal.c index 29dff824..c06a05a4 100644 --- a/libscpi/src/minimal.c +++ b/libscpi/src/minimal.c @@ -213,3 +213,36 @@ scpi_result_t SCPI_StatusPreset(scpi_t * context) { SCPI_RegSet(context, SCPI_REG_QUES, 0); return SCPI_RES_OK; } + +/** + * HELP? + * @param context + * @return + */ +scpi_result_t SCPI_HelpQ(scpi_t * context) { + int i = 0; + for(;;) { + size_t pattern_len = strlen(context->cmdlist[i].pattern); + size_t block_len = 1 + pattern_len + strlen(SCPI_LINE_ENDING); +#if USE_COMMAND_DESCRIPTIONS + size_t description_len = context->cmdlist[i].description ? strlen(context->cmdlist[i].description) : 0; + if(description_len > 0){ + block_len = 1 + pattern_len + 1 + description_len + strlen(SCPI_LINE_ENDING); + } +#endif + SCPI_ResultArbitraryBlockHeader(context, block_len); + SCPI_ResultArbitraryBlockData(context, "\t", 1); + SCPI_ResultArbitraryBlockData(context, context->cmdlist[i].pattern, pattern_len); +#if USE_COMMAND_DESCRIPTIONS + if(description_len > 0){ + SCPI_ResultArbitraryBlockData(context, " ", 1); + SCPI_ResultArbitraryBlockData(context, context->cmdlist[i].description, description_len); + } +#endif + SCPI_ResultArbitraryBlockData(context, SCPI_LINE_ENDING, strlen(SCPI_LINE_ENDING)); + if (context->cmdlist[++i].pattern == NULL) { + break; + } + } + return SCPI_RES_OK; +} From 315f20dfb62992f22dcc55a661dbac7152dcaae7 Mon Sep 17 00:00:00 2001 From: helge Date: Mon, 7 Feb 2022 17:15:28 +0100 Subject: [PATCH 04/22] introduce help search introduce search string to narrow down help output --- libscpi/inc/scpi/config.h | 4 +++ libscpi/src/minimal.c | 21 ++++++++----- libscpi/src/utils.c | 60 +++++++++++++++++++++++++++++++++++++ libscpi/src/utils_private.h | 7 +++++ 4 files changed, 85 insertions(+), 7 deletions(-) diff --git a/libscpi/inc/scpi/config.h b/libscpi/inc/scpi/config.h index 2f9583a1..29c50498 100644 --- a/libscpi/inc/scpi/config.h +++ b/libscpi/inc/scpi/config.h @@ -118,6 +118,10 @@ extern "C" { #define USE_DEPRECATED_FUNCTIONS 1 #endif +#ifndef USE_HELP_SEARCH +#define USE_HELP_SEARCH 1 +#endif + #ifndef USE_CUSTOM_DTOSTRE #define USE_CUSTOM_DTOSTRE 0 #endif diff --git a/libscpi/src/minimal.c b/libscpi/src/minimal.c index c06a05a4..0488289f 100644 --- a/libscpi/src/minimal.c +++ b/libscpi/src/minimal.c @@ -215,20 +215,30 @@ scpi_result_t SCPI_StatusPreset(scpi_t * context) { } /** - * HELP? + * HELP? [] * @param context * @return */ scpi_result_t SCPI_HelpQ(scpi_t * context) { - int i = 0; - for(;;) { +#if USE_HELP_SEARCH + size_t search_string_len = 0; + const char * search_string = NULL; + scpi_bool_t narrowed_down = SCPI_ParamCharacters(context, &search_string, &search_string_len, false); +#endif + + for(int i = 0; context->cmdlist[i].pattern != NULL; i++) { size_t pattern_len = strlen(context->cmdlist[i].pattern); +#if USE_HELP_SEARCH + if(narrowed_down && not strncasestrn(context->cmdlist[i].pattern, pattern_len, search_string, search_string_len)){ + continue; + } +#endif size_t block_len = 1 + pattern_len + strlen(SCPI_LINE_ENDING); #if USE_COMMAND_DESCRIPTIONS size_t description_len = context->cmdlist[i].description ? strlen(context->cmdlist[i].description) : 0; if(description_len > 0){ block_len = 1 + pattern_len + 1 + description_len + strlen(SCPI_LINE_ENDING); - } + } #endif SCPI_ResultArbitraryBlockHeader(context, block_len); SCPI_ResultArbitraryBlockData(context, "\t", 1); @@ -240,9 +250,6 @@ scpi_result_t SCPI_HelpQ(scpi_t * context) { } #endif SCPI_ResultArbitraryBlockData(context, SCPI_LINE_ENDING, strlen(SCPI_LINE_ENDING)); - if (context->cmdlist[++i].pattern == NULL) { - break; - } } return SCPI_RES_OK; } diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c index 328f8be7..c5b3c8a3 100644 --- a/libscpi/src/utils.c +++ b/libscpi/src/utils.c @@ -1140,3 +1140,63 @@ uint64_t SCPI_Swap64(uint64_t val) { ((val & 0x00FF000000000000ull) >> 40) | ((val & 0xFF00000000000000ull) >> 56); } + + +/* Cherokee: strncasestrn() and strncasestr() + * + * Authors: + * Alvaro Lopez Ortega + * + * Copyright (C) 2001-2014 Alvaro Lopez Ortega + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#define CHEROKEE_CHAR_TO_LOWER(_ch) ((_ch) | 32) +#define CHEROKEE_CHAR_TO_UPPER(_ch) ((_ch) & ~32) + +char * strncasestrn (const char *s, size_t slen, const char *find, size_t findlen) +{ + char c; + char sc; + + if (unlikely (find == NULL) || (findlen == 0)) + return (char *)s; + + if (unlikely (*find == '\0')) + return (char *)s; + + c = *find; + find++; + findlen--; + + do { + do { + if (slen-- < 1 || (sc = *s++) == '\0') + return NULL; + } while (CHEROKEE_CHAR_TO_LOWER(sc) != CHEROKEE_CHAR_TO_LOWER(c)); + if (findlen > slen) { + return NULL; + } + } while (strncasecmp (s, find, findlen) != 0); + + s--; + return (char *)s; +} + +char * strncasestr (const char *s, const char *find, size_t slen) +{ + return strncasestrn (s, slen, find, strlen(find)); +} diff --git a/libscpi/src/utils_private.h b/libscpi/src/utils_private.h index 6ae1616a..05d39cb9 100644 --- a/libscpi/src/utils_private.h +++ b/libscpi/src/utils_private.h @@ -99,6 +99,13 @@ extern "C" { char *OUR_strndup(const char *s, size_t n); #endif + char * strncasestr (const char *s, const char *find, size_t slen); + char * strncasestrn (const char *s, size_t slen, const char *find, size_t findlen); + +#ifndef strncasestrn_s +#define strncasestrn_s(s,s_len,lit) strncasestrn(s, s_len, lit, sizeof(lit)-1) +#endif + #ifndef min #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif From 159fe833c6530793e0f67ac7501a6b8949d0a650 Mon Sep 17 00:00:00 2001 From: helge Date: Mon, 7 Feb 2022 17:31:28 +0100 Subject: [PATCH 05/22] drop C++20 keyword --- libscpi/src/utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c index c5b3c8a3..5c72d7d0 100644 --- a/libscpi/src/utils.c +++ b/libscpi/src/utils.c @@ -1172,10 +1172,10 @@ char * strncasestrn (const char *s, size_t slen, const char *find, size_t findle char c; char sc; - if (unlikely (find == NULL) || (findlen == 0)) + if ((find == NULL) || (findlen == 0)) return (char *)s; - if (unlikely (*find == '\0')) + if ((*find == '\0')) return (char *)s; c = *find; From d099d9ad37b56569f1f0d54868dc4c2a02c4c5b7 Mon Sep 17 00:00:00 2001 From: helge Date: Mon, 7 Feb 2022 17:55:43 +0100 Subject: [PATCH 06/22] rename to USE_HELP_FILTER --- libscpi/inc/scpi/config.h | 4 ++-- libscpi/src/minimal.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libscpi/inc/scpi/config.h b/libscpi/inc/scpi/config.h index 29c50498..a42b6f1d 100644 --- a/libscpi/inc/scpi/config.h +++ b/libscpi/inc/scpi/config.h @@ -118,8 +118,8 @@ extern "C" { #define USE_DEPRECATED_FUNCTIONS 1 #endif -#ifndef USE_HELP_SEARCH -#define USE_HELP_SEARCH 1 +#ifndef USE_HELP_FILTER +#define USE_HELP_FILTER 1 #endif #ifndef USE_CUSTOM_DTOSTRE diff --git a/libscpi/src/minimal.c b/libscpi/src/minimal.c index 0488289f..27e7fb51 100644 --- a/libscpi/src/minimal.c +++ b/libscpi/src/minimal.c @@ -220,7 +220,7 @@ scpi_result_t SCPI_StatusPreset(scpi_t * context) { * @return */ scpi_result_t SCPI_HelpQ(scpi_t * context) { -#if USE_HELP_SEARCH +#if USE_HELP_FILTER size_t search_string_len = 0; const char * search_string = NULL; scpi_bool_t narrowed_down = SCPI_ParamCharacters(context, &search_string, &search_string_len, false); @@ -228,7 +228,7 @@ scpi_result_t SCPI_HelpQ(scpi_t * context) { for(int i = 0; context->cmdlist[i].pattern != NULL; i++) { size_t pattern_len = strlen(context->cmdlist[i].pattern); -#if USE_HELP_SEARCH +#if USE_HELP_FILTER if(narrowed_down && not strncasestrn(context->cmdlist[i].pattern, pattern_len, search_string, search_string_len)){ continue; } From aa660db7dad99ea3cea5cdc9c2229b82bdddd6ef Mon Sep 17 00:00:00 2001 From: helge Date: Mon, 7 Feb 2022 18:08:49 +0100 Subject: [PATCH 07/22] fix expression --- libscpi/src/minimal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libscpi/src/minimal.c b/libscpi/src/minimal.c index 27e7fb51..4ead96b3 100644 --- a/libscpi/src/minimal.c +++ b/libscpi/src/minimal.c @@ -229,7 +229,7 @@ scpi_result_t SCPI_HelpQ(scpi_t * context) { for(int i = 0; context->cmdlist[i].pattern != NULL; i++) { size_t pattern_len = strlen(context->cmdlist[i].pattern); #if USE_HELP_FILTER - if(narrowed_down && not strncasestrn(context->cmdlist[i].pattern, pattern_len, search_string, search_string_len)){ + if(narrowed_down && (NULL == strncasestrn(context->cmdlist[i].pattern, pattern_len, search_string, search_string_len))){ continue; } #endif From 1460793f75ba66721718b604ac2d5f4baa308a2a Mon Sep 17 00:00:00 2001 From: helge Date: Fri, 6 Jan 2023 17:12:46 +0100 Subject: [PATCH 08/22] add full command descriptions to examples common def, set desc. default disabled * Properly integrate command descriptions into examples. Preliminary descriptions added after consulting scpi-99 standard, as well as looking at the DMM and TEST handler source. Command paramater types hinted as where appropriate. Return values or ranges given at the end of each description in round brackets. * Default changed to USE_COMMAND_DESCRIPTIONS 0 to avoid unexpected impact on code side. Set to 1 to use. * scpi_command_t defintion helper macros moves to types.h --- examples/common/scpi-def.c | 134 ++++++++++++++++------------------- examples/common/scpi-def.cpp | 130 ++++++++++++++++----------------- libscpi/inc/scpi/config.h | 2 +- libscpi/inc/scpi/types.h | 17 ++++- 4 files changed, 138 insertions(+), 145 deletions(-) diff --git a/examples/common/scpi-def.c b/examples/common/scpi-def.c index 67c37755..010e1cd2 100644 --- a/examples/common/scpi-def.c +++ b/examples/common/scpi-def.c @@ -353,85 +353,75 @@ static scpi_result_t My_CoreTstQ(scpi_t * context) { return SCPI_RES_OK; } -#if USE_COMMAND_DESCRIPTIONS -#define SCPI_CMD_DESC(S) .description=(S), -#else -#define SCPI_CMD_DESC(S) -#endif - -#if USE_COMMAND_TAGS -#define SCPI_CMD_TAG(T) .tag=(T), -#else -#define SCPI_CMD_TAG(T) -#endif +#define pp_xstr(s) pp_str(s) +#define pp_str(s) #s +#define SCPI_ERROR_QUEUE_SIZE_STR pp_xstr(SCPI_ERROR_QUEUE_SIZE) const scpi_command_t scpi_commands[] = { - /* Optional help commmand */ - {.pattern = "HELP?", .callback = SCPI_HelpQ, SCPI_CMD_DESC("\t - list supported commands")}, - - /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1) */ - { .pattern = "*CLS", .callback = SCPI_CoreCls,}, - { .pattern = "*ESE", .callback = SCPI_CoreEse,}, - { .pattern = "*ESE?", .callback = SCPI_CoreEseQ,}, - { .pattern = "*ESR?", .callback = SCPI_CoreEsrQ,}, - { .pattern = "*IDN?", .callback = SCPI_CoreIdnQ,}, - { .pattern = "*OPC", .callback = SCPI_CoreOpc,}, - { .pattern = "*OPC?", .callback = SCPI_CoreOpcQ,}, - { .pattern = "*RST", .callback = SCPI_CoreRst,}, - { .pattern = "*SRE", .callback = SCPI_CoreSre,}, - { .pattern = "*SRE?", .callback = SCPI_CoreSreQ,}, - { .pattern = "*STB?", .callback = SCPI_CoreStbQ,}, - { .pattern = "*TST?", .callback = My_CoreTstQ,}, - { .pattern = "*WAI", .callback = SCPI_CoreWai,}, - - /* Required SCPI commands (SCPI std V1999.0 4.2.1) */ - {.pattern = "SYSTem:ERRor[:NEXT]?", .callback = SCPI_SystemErrorNextQ,}, - {.pattern = "SYSTem:ERRor:COUNt?", .callback = SCPI_SystemErrorCountQ,}, - {.pattern = "SYSTem:VERSion?", .callback = SCPI_SystemVersionQ,}, - - /* {.pattern = "STATus:OPERation?", .callback = scpi_stub_callback,}, */ - /* {.pattern = "STATus:OPERation:EVENt?", .callback = scpi_stub_callback,}, */ - /* {.pattern = "STATus:OPERation:CONDition?", .callback = scpi_stub_callback,}, */ - /* {.pattern = "STATus:OPERation:ENABle", .callback = scpi_stub_callback,}, */ - /* {.pattern = "STATus:OPERation:ENABle?", .callback = scpi_stub_callback,}, */ - - {.pattern = "STATus:QUEStionable[:EVENt]?", .callback = SCPI_StatusQuestionableEventQ,}, - /* {.pattern = "STATus:QUEStionable:CONDition?", .callback = scpi_stub_callback,}, */ - {.pattern = "STATus:QUEStionable:ENABle", .callback = SCPI_StatusQuestionableEnable,}, - {.pattern = "STATus:QUEStionable:ENABle?", .callback = SCPI_StatusQuestionableEnableQ,}, - - {.pattern = "STATus:PRESet", .callback = SCPI_StatusPreset,}, - - /* DMM */ - {.pattern = "MEASure:VOLTage:DC?", .callback = DMM_MeasureVoltageDcQ,}, - {.pattern = "CONFigure:VOLTage:DC", .callback = DMM_ConfigureVoltageDc,}, - {.pattern = "MEASure:VOLTage:DC:RATio?", .callback = SCPI_StubQ,}, - {.pattern = "MEASure:VOLTage:AC?", .callback = DMM_MeasureVoltageAcQ,}, - {.pattern = "MEASure:CURRent:DC?", .callback = SCPI_StubQ,}, - {.pattern = "MEASure:CURRent:AC?", .callback = SCPI_StubQ,}, - {.pattern = "MEASure:RESistance?", .callback = SCPI_StubQ,}, - {.pattern = "MEASure:FRESistance?", .callback = SCPI_StubQ,}, - {.pattern = "MEASure:FREQuency?", .callback = SCPI_StubQ,}, - {.pattern = "MEASure:PERiod?", .callback = SCPI_StubQ,}, - - {.pattern = "SYSTem:COMMunication:TCPIP:CONTROL?", .callback = SCPI_SystemCommTcpipControlQ,}, - - {.pattern = "TEST:BOOL", .callback = TEST_Bool,}, - {.pattern = "TEST:CHOice?", .callback = TEST_ChoiceQ,}, - {.pattern = "TEST#:NUMbers#", .callback = TEST_Numbers,}, - {.pattern = "TEST:TEXT", .callback = TEST_Text,}, - {.pattern = "TEST:ARBitrary?", .callback = TEST_ArbQ,}, - {.pattern = "TEST:CHANnellist", .callback = TEST_Chanlst,}, - + /* Optional help command */ + {"HELP?", SCPI_HelpQ, SCPI_CMD_DESC("\t - list supported commands") SCPI_CMD_TAG(0)}, + + /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1): *CLS *ESE *ESE? *ESR? *IDN? *OPC *OPC? *RST *SRE *SRE? *STB? *TST? *WAI */ + {"*CLS", SCPI_CoreCls, SCPI_CMD_DESC("\t - clear all Event Status registers, errors, output queue") SCPI_CMD_TAG(0)}, + // -- Standard Event Status Group [EVENT]-[ENABLE] + {"*ESE", SCPI_CoreEse, SCPI_CMD_DESC("<0..255> - set Standard Event Status Enable (event mask)") SCPI_CMD_TAG(0)}, + {"*ESE?", SCPI_CoreEseQ, SCPI_CMD_DESC("\t - read ESE (0..255)") SCPI_CMD_TAG(0)}, + {"*ESR?", SCPI_CoreEsrQ, SCPI_CMD_DESC("\t - read+clear Standard Event Status register") SCPI_CMD_TAG(0)}, + // -- IEEE Mandated Commands (continued ...) + {"*IDN?", SCPI_CoreIdnQ, SCPI_CMD_DESC("\t - read device identifier (multi-line string)") SCPI_CMD_TAG(0)}, + {"*OPC", SCPI_CoreOpc, SCPI_CMD_DESC("\t - complete ops preceding Operation Complete Command, set ESR.OPC 1") SCPI_CMD_TAG(0)}, + {"*OPC?", SCPI_CoreOpcQ, SCPI_CMD_DESC("\t - read ESR.OPC (0:ongoing ops, 1:done)") SCPI_CMD_TAG(0)}, + {"*RST", SCPI_CoreRst, SCPI_CMD_DESC("\t - reset instrument and interface") SCPI_CMD_TAG(0)}, + {"*SRE", SCPI_CoreSre, SCPI_CMD_DESC("<0..255> - set Service Request Enable (event mask over STB)") SCPI_CMD_TAG(0)}, + {"*SRE?", SCPI_CoreSreQ, SCPI_CMD_DESC("\t - read SRE (0..255)") SCPI_CMD_TAG(0)}, + {"*STB?", SCPI_CoreStbQ, SCPI_CMD_DESC("\t - read STatus Byte (0..255)") SCPI_CMD_TAG(0)}, + {"*TST?", My_CoreTstQ, SCPI_CMD_DESC("\t - read self-test result (0:no failures)") SCPI_CMD_TAG(0)}, + {"*WAI", SCPI_CoreWai, SCPI_CMD_DESC("\t - halt cmd execution until pending operations complete") SCPI_CMD_TAG(0)}, + + /* Required SCPI commands (SCPI std V1999.0 4.2.1) : SYSTem:ERRor, STATus:OPERation, STATus:QUEStionable and STATus:PRESet */ + {"SYSTem:ERRor[:NEXT]?", SCPI_SystemErrorNextQ, SCPI_CMD_DESC("\t - get next error in queue (int error,string)") SCPI_CMD_TAG(0)}, + {"SYSTem:ERRor:COUNt?", SCPI_SystemErrorCountQ, SCPI_CMD_DESC("\t - queued error count (0.." SCPI_ERROR_QUEUE_SIZE_STR ")") SCPI_CMD_TAG(0)}, + {"SYSTem:VERSion?", SCPI_SystemVersionQ, SCPI_CMD_DESC("\t - query system version (version expr)") SCPI_CMD_TAG(0)}, + // -- Operation Status Group [CONDITION]-[EVENT]-[ENABLE] + {"STATus:OPERation:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"STATus:OPERation[:EVENt]?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"STATus:OPERation:ENABle", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"STATus:OPERation:ENABle?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + // -- Questionable Status Group [CONDITION]-[EVENT]-[ENABLE] + {"STATus:QUEStionable:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented") SCPI_CMD_TAG(0)}, // "\t - read momentary Questionable Condition register (0..65535)" + {"STATus:QUEStionable[:EVENt]?", SCPI_StatusQuestionableEventQ, SCPI_CMD_DESC("\t - read Questionable Event register (0..65535)") SCPI_CMD_TAG(0)}, + {"STATus:QUEStionable:ENABle", SCPI_StatusQuestionableEnable, SCPI_CMD_DESC("<0..65535> - set Questionable Enable (event mask)") SCPI_CMD_TAG(0)}, + {"STATus:QUEStionable:ENABle?", SCPI_StatusQuestionableEnableQ, SCPI_CMD_DESC("\t - Questionable Status Enable (0..65535)") SCPI_CMD_TAG(0)}, + {"STATus:PRESet", SCPI_StatusPreset, SCPI_CMD_DESC("\t - load Status sub-system register defaults") SCPI_CMD_TAG(0)}, + + /* commands specific to DMM example with TEST sub-system */ + {"SYSTem:COMMunication:TCPIP:CONTROL?", SCPI_SystemCommTcpipControlQ, SCPI_CMD_DESC("\t - read TCPIP control port") SCPI_CMD_TAG(0)}, + {"CONFigure:VOLTage:DC", DMM_ConfigureVoltageDc, SCPI_CMD_DESC("[,] - test command") SCPI_CMD_TAG(0)}, + {"MEASure:VOLTage:DC?", DMM_MeasureVoltageDcQ, SCPI_CMD_DESC("[[,]] - test command (0)") SCPI_CMD_TAG(0)}, + {"MEASure:VOLTage:DC:RATio?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"MEASure:VOLTage:AC?", DMM_MeasureVoltageAcQ, SCPI_CMD_DESC("[[,]] - test command (0)") SCPI_CMD_TAG(0)}, + {"MEASure:CURRent:DC?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"MEASure:CURRent:AC?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"MEASure:RESistance?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"MEASure:FRESistance?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"MEASure:FREQuency?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"MEASure:PERiod?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"TEST:BOOL", TEST_Bool, SCPI_CMD_DESC(" - test command") SCPI_CMD_TAG(0)}, + {"TEST:CHOice?", TEST_ChoiceQ, SCPI_CMD_DESC(" - test command (\"BUS\":5,\"IMMediate\":6,\"EXTernal\",7)") SCPI_CMD_TAG(0)}, + {"TEST#:NUMbers#", TEST_Numbers, SCPI_CMD_DESC("\t - test command with numbers - default 1") SCPI_CMD_TAG(0)}, + {"TEST:TEXT", TEST_Text, SCPI_CMD_DESC("[, ...] - debug print as received") SCPI_CMD_TAG(0)}, + {"TEST:ARBitrary?", TEST_ArbQ, SCPI_CMD_DESC(" - receive and return block data (block data)") SCPI_CMD_TAG(0)}, + {"TEST:CHANnellist", TEST_Chanlst, SCPI_CMD_DESC(" - test channel list parsing") SCPI_CMD_TAG(0)}, + SCPI_CMD_LIST_END }; scpi_interface_t scpi_interface = { - .error = SCPI_Error, - .write = SCPI_Write, + .error = SCPI_Error, + .write = SCPI_Write, .control = SCPI_Control, - .flush = SCPI_Flush, - .reset = SCPI_Reset, + .flush = SCPI_Flush, + .reset = SCPI_Reset, }; char scpi_input_buffer[SCPI_INPUT_BUFFER_LENGTH]; diff --git a/examples/common/scpi-def.cpp b/examples/common/scpi-def.cpp index f8940468..df852a6d 100644 --- a/examples/common/scpi-def.cpp +++ b/examples/common/scpi-def.cpp @@ -353,85 +353,75 @@ static scpi_result_t My_CoreTstQ(scpi_t * context) { return SCPI_RES_OK; } -#if USE_COMMAND_DESCRIPTIONS -#define SCPI_CMD_DESC(S) (S), -#else -#define SCPI_CMD_DESC(S) -#endif - -#if USE_COMMAND_TAGS -#define SCPI_CMD_TAG(T) (T), -#else -#define SCPI_CMD_TAG(T) -#endif +#define pp_xstr(s) pp_str(s) +#define pp_str(s) #s +#define SCPI_ERROR_QUEUE_SIZE_STR pp_xstr(SCPI_ERROR_QUEUE_SIZE) const scpi_command_t scpi_commands[] = { /* Optional help command */ {"HELP?", SCPI_HelpQ, SCPI_CMD_DESC("\t - list supported commands") SCPI_CMD_TAG(0)}, - - /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1) */ - {"*CLS", SCPI_CoreCls, SCPI_CMD_TAG(0)}, - {"*ESE", SCPI_CoreEse, SCPI_CMD_TAG(0)}, - {"*ESE?", SCPI_CoreEseQ, SCPI_CMD_TAG(0)}, - {"*ESR?", SCPI_CoreEsrQ, SCPI_CMD_TAG(0)}, - {"*IDN?", SCPI_CoreIdnQ, SCPI_CMD_TAG(0)}, - {"*OPC", SCPI_CoreOpc, SCPI_CMD_TAG(0)}, - {"*OPC?", SCPI_CoreOpcQ, SCPI_CMD_TAG(0)}, - {"*RST", SCPI_CoreRst, SCPI_CMD_TAG(0)}, - {"*SRE", SCPI_CoreSre, SCPI_CMD_TAG(0)}, - {"*SRE?", SCPI_CoreSreQ, SCPI_CMD_TAG(0)}, - {"*STB?", SCPI_CoreStbQ, SCPI_CMD_TAG(0)}, - {"*TST?", My_CoreTstQ, SCPI_CMD_TAG(0)}, - {"*WAI", SCPI_CoreWai, SCPI_CMD_TAG(0)}, - - /* Required SCPI commands (SCPI std V1999.0 4.2.1) */ - {"SYSTem:ERRor[:NEXT]?", SCPI_SystemErrorNextQ, SCPI_CMD_TAG(0)}, - {"SYSTem:ERRor:COUNt?", SCPI_SystemErrorCountQ, SCPI_CMD_TAG(0)}, - {"SYSTem:VERSion?", SCPI_SystemVersionQ, SCPI_CMD_TAG(0)}, - - //{"STATus:OPERation?", scpi_stub_callback, SCPI_CMD_TAG(0)}, - //{"STATus:OPERation:EVENt?", scpi_stub_callback, SCPI_CMD_TAG(0)}, - //{"STATus:OPERation:CONDition?", scpi_stub_callback, SCPI_CMD_TAG(0)}, - //{"STATus:OPERation:ENABle", scpi_stub_callback, SCPI_CMD_TAG(0)}, - //{"STATus:OPERation:ENABle?", scpi_stub_callback, SCPI_CMD_TAG(0)}, - - {"STATus:QUEStionable[:EVENt]?", SCPI_StatusQuestionableEventQ, SCPI_CMD_TAG(0)}, - //{"STATus:QUEStionable:CONDition?", scpi_stub_callback, SCPI_CMD_TAG(0)}, - {"STATus:QUEStionable:ENABle", SCPI_StatusQuestionableEnable, SCPI_CMD_TAG(0)}, - {"STATus:QUEStionable:ENABle?", SCPI_StatusQuestionableEnableQ, SCPI_CMD_TAG(0)}, - - {"STATus:PRESet", SCPI_StatusPreset, SCPI_CMD_TAG(0)}, - - /* DMM */ - {"MEASure:VOLTage:DC?", DMM_MeasureVoltageDcQ, SCPI_CMD_TAG(0)}, - {"CONFigure:VOLTage:DC", DMM_ConfigureVoltageDc, SCPI_CMD_TAG(0)}, - {"MEASure:VOLTage:DC:RATio?", SCPI_StubQ, SCPI_CMD_TAG(0)}, - {"MEASure:VOLTage:AC?", DMM_MeasureVoltageAcQ, SCPI_CMD_TAG(0)}, - {"MEASure:CURRent:DC?", SCPI_StubQ, SCPI_CMD_TAG(0)}, - {"MEASure:CURRent:AC?", SCPI_StubQ, SCPI_CMD_TAG(0)}, - {"MEASure:RESistance?", SCPI_StubQ, SCPI_CMD_TAG(0)}, - {"MEASure:FRESistance?", SCPI_StubQ, SCPI_CMD_TAG(0)}, - {"MEASure:FREQuency?", SCPI_StubQ, SCPI_CMD_TAG(0)}, - {"MEASure:PERiod?", SCPI_StubQ, SCPI_CMD_TAG(0)}, - - {"SYSTem:COMMunication:TCPIP:CONTROL?", SCPI_SystemCommTcpipControlQ, SCPI_CMD_TAG(0)}, - - {"TEST:BOOL", TEST_Bool, SCPI_CMD_TAG(0)}, - {"TEST:CHOice?", TEST_ChoiceQ, SCPI_CMD_TAG(0)}, - {"TEST#:NUMbers#", TEST_Numbers, SCPI_CMD_TAG(0)}, - {"TEST:TEXT", TEST_Text, SCPI_CMD_TAG(0)}, - {"TEST:ARBitrary?", TEST_ArbQ, SCPI_CMD_TAG(0)}, - {"TEST:CHANnellist", TEST_Chanlst, SCPI_CMD_TAG(0)}, - + + /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1): *CLS *ESE *ESE? *ESR? *IDN? *OPC *OPC? *RST *SRE *SRE? *STB? *TST? *WAI */ + {"*CLS", SCPI_CoreCls, SCPI_CMD_DESC("\t - clear all Event Status registers, errors, output queue") SCPI_CMD_TAG(0)}, + // -- Standard Event Status Group [EVENT]-[ENABLE] + {"*ESE", SCPI_CoreEse, SCPI_CMD_DESC("<0..255> - set Standard Event Status Enable (event mask)") SCPI_CMD_TAG(0)}, + {"*ESE?", SCPI_CoreEseQ, SCPI_CMD_DESC("\t - read ESE (0..255)") SCPI_CMD_TAG(0)}, + {"*ESR?", SCPI_CoreEsrQ, SCPI_CMD_DESC("\t - read+clear Standard Event Status register") SCPI_CMD_TAG(0)}, + // -- IEEE Mandated Commands (continued ...) + {"*IDN?", SCPI_CoreIdnQ, SCPI_CMD_DESC("\t - read device identifier (multi-line string)") SCPI_CMD_TAG(0)}, + {"*OPC", SCPI_CoreOpc, SCPI_CMD_DESC("\t - complete ops preceding Operation Complete Command, set ESR.OPC 1") SCPI_CMD_TAG(0)}, + {"*OPC?", SCPI_CoreOpcQ, SCPI_CMD_DESC("\t - read ESR.OPC (0:ongoing ops, 1:done)") SCPI_CMD_TAG(0)}, + {"*RST", SCPI_CoreRst, SCPI_CMD_DESC("\t - reset instrument and interface") SCPI_CMD_TAG(0)}, + {"*SRE", SCPI_CoreSre, SCPI_CMD_DESC("<0..255> - set Service Request Enable (event mask over STB)") SCPI_CMD_TAG(0)}, + {"*SRE?", SCPI_CoreSreQ, SCPI_CMD_DESC("\t - read SRE (0..255)") SCPI_CMD_TAG(0)}, + {"*STB?", SCPI_CoreStbQ, SCPI_CMD_DESC("\t - read STatus Byte (0..255)") SCPI_CMD_TAG(0)}, + {"*TST?", My_CoreTstQ, SCPI_CMD_DESC("\t - read self-test result (0:no failures)") SCPI_CMD_TAG(0)}, + {"*WAI", SCPI_CoreWai, SCPI_CMD_DESC("\t - halt cmd execution until pending operations complete") SCPI_CMD_TAG(0)}, + + /* Required SCPI commands (SCPI std V1999.0 4.2.1) : SYSTem:ERRor, STATus:OPERation, STATus:QUEStionable and STATus:PRESet */ + {"SYSTem:ERRor[:NEXT]?", SCPI_SystemErrorNextQ, SCPI_CMD_DESC("\t - get next error in queue (int error,string)") SCPI_CMD_TAG(0)}, + {"SYSTem:ERRor:COUNt?", SCPI_SystemErrorCountQ, SCPI_CMD_DESC("\t - queued error count (0.." SCPI_ERROR_QUEUE_SIZE_STR ")") SCPI_CMD_TAG(0)}, + {"SYSTem:VERSion?", SCPI_SystemVersionQ, SCPI_CMD_DESC("\t - query system version (version expr)") SCPI_CMD_TAG(0)}, + // -- Operation Status Group [CONDITION]-[EVENT]-[ENABLE] + {"STATus:OPERation:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"STATus:OPERation[:EVENt]?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"STATus:OPERation:ENABle", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"STATus:OPERation:ENABle?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + // -- Questionable Status Group [CONDITION]-[EVENT]-[ENABLE] + {"STATus:QUEStionable:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented") SCPI_CMD_TAG(0)}, // "\t - read momentary Questionable Condition register (0..65535)" + {"STATus:QUEStionable[:EVENt]?", SCPI_StatusQuestionableEventQ, SCPI_CMD_DESC("\t - read Questionable Event register (0..65535)") SCPI_CMD_TAG(0)}, + {"STATus:QUEStionable:ENABle", SCPI_StatusQuestionableEnable, SCPI_CMD_DESC("<0..65535> - set Questionable Enable (event mask)") SCPI_CMD_TAG(0)}, + {"STATus:QUEStionable:ENABle?", SCPI_StatusQuestionableEnableQ, SCPI_CMD_DESC("\t - Questionable Status Enable (0..65535)") SCPI_CMD_TAG(0)}, + {"STATus:PRESet", SCPI_StatusPreset, SCPI_CMD_DESC("\t - load Status sub-system register defaults") SCPI_CMD_TAG(0)}, + + /* commands specific to DMM example with TEST sub-system */ + {"SYSTem:COMMunication:TCPIP:CONTROL?", SCPI_SystemCommTcpipControlQ, SCPI_CMD_DESC("\t - read TCPIP control port") SCPI_CMD_TAG(0)}, + {"CONFigure:VOLTage:DC", DMM_ConfigureVoltageDc, SCPI_CMD_DESC("[,] - test command") SCPI_CMD_TAG(0)}, + {"MEASure:VOLTage:DC?", DMM_MeasureVoltageDcQ, SCPI_CMD_DESC("[[,]] - test command (0)") SCPI_CMD_TAG(0)}, + {"MEASure:VOLTage:DC:RATio?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"MEASure:VOLTage:AC?", DMM_MeasureVoltageAcQ, SCPI_CMD_DESC("[[,]] - test command (0)") SCPI_CMD_TAG(0)}, + {"MEASure:CURRent:DC?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"MEASure:CURRent:AC?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"MEASure:RESistance?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"MEASure:FRESistance?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"MEASure:FREQuency?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"MEASure:PERiod?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"TEST:BOOL", TEST_Bool, SCPI_CMD_DESC(" - test command") SCPI_CMD_TAG(0)}, + {"TEST:CHOice?", TEST_ChoiceQ, SCPI_CMD_DESC(" - test command (\"BUS\":5,\"IMMediate\":6,\"EXTernal\",7)") SCPI_CMD_TAG(0)}, + {"TEST#:NUMbers#", TEST_Numbers, SCPI_CMD_DESC("\t - test command with numbers - default 1") SCPI_CMD_TAG(0)}, + {"TEST:TEXT", TEST_Text, SCPI_CMD_DESC("[, ...] - debug print as received") SCPI_CMD_TAG(0)}, + {"TEST:ARBitrary?", TEST_ArbQ, SCPI_CMD_DESC(" - receive and return block data (block data)") SCPI_CMD_TAG(0)}, + {"TEST:CHANnellist", TEST_Chanlst, SCPI_CMD_DESC(" - test channel list parsing") SCPI_CMD_TAG(0)}, + SCPI_CMD_LIST_END }; scpi_interface_t scpi_interface = { - /*.error = */ SCPI_Error, - /*.write = */ SCPI_Write, + /*.error = */ SCPI_Error, + /*.write = */ SCPI_Write, /*.control = */ SCPI_Control, - /*.flush = */ SCPI_Flush, - /*.reset = */ SCPI_Reset, + /*.flush = */ SCPI_Flush, + /*.reset = */ SCPI_Reset, }; char scpi_input_buffer[SCPI_INPUT_BUFFER_LENGTH]; diff --git a/libscpi/inc/scpi/config.h b/libscpi/inc/scpi/config.h index a42b6f1d..41495a81 100644 --- a/libscpi/inc/scpi/config.h +++ b/libscpi/inc/scpi/config.h @@ -111,7 +111,7 @@ extern "C" { #endif #ifndef USE_COMMAND_DESCRIPTIONS -#define USE_COMMAND_DESCRIPTIONS 1 +#define USE_COMMAND_DESCRIPTIONS 0 #endif #ifndef USE_DEPRECATED_FUNCTIONS diff --git a/libscpi/inc/scpi/types.h b/libscpi/inc/scpi/types.h index a79e4fc7..785a1be7 100644 --- a/libscpi/inc/scpi/types.h +++ b/libscpi/inc/scpi/types.h @@ -351,7 +351,7 @@ extern "C" { typedef struct _scpi_data_parameter_t scpi_data_parameter_t; typedef scpi_token_t scpi_parameter_t; - + struct _scpi_command_t { const char * pattern; scpi_command_callback_t callback; @@ -363,6 +363,20 @@ extern "C" { #endif /* USE_COMMAND_TAGS */ }; +/* Helper macros for _scpi_command_t items. Usage: + _scpi_command_t cmd = {.pattern=":SOME:PATTern", .callback=SCPI_StubQ, SCPI_CMD_DESC("\t - a command") SCPI_CMD_TAG(0)}; +*/ +#if USE_COMMAND_DESCRIPTIONS +#define SCPI_CMD_DESC(S) (S), +#else +#define SCPI_CMD_DESC(S) +#endif +#if USE_COMMAND_TAGS +#define SCPI_CMD_TAG(T) (T), +#else +#define SCPI_CMD_TAG(T) +#endif + struct _scpi_interface_t { scpi_error_callback_t error; scpi_write_t write; @@ -405,4 +419,3 @@ extern "C" { #endif #endif /* SCPI_TYPES_H */ - From 7d0c83d7c5f7fdaf3ead0aae947a0c0b2823aeb5 Mon Sep 17 00:00:00 2001 From: helge Date: Sat, 7 Jan 2023 17:13:58 +0100 Subject: [PATCH 09/22] clean-up * fixes some inaccuracies in scpi-def * clean-up in utils.c * add documentation to introduced functions * correct CHAR_TO_LOWER --- examples/common/scpi-def.c | 30 ++++++++++---------- examples/common/scpi-def.cpp | 30 ++++++++++---------- libscpi/src/utils.c | 53 ++++++++++++++++-------------------- 3 files changed, 53 insertions(+), 60 deletions(-) diff --git a/examples/common/scpi-def.c b/examples/common/scpi-def.c index 010e1cd2..38fa5e4d 100644 --- a/examples/common/scpi-def.c +++ b/examples/common/scpi-def.c @@ -364,38 +364,38 @@ const scpi_command_t scpi_commands[] = { /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1): *CLS *ESE *ESE? *ESR? *IDN? *OPC *OPC? *RST *SRE *SRE? *STB? *TST? *WAI */ {"*CLS", SCPI_CoreCls, SCPI_CMD_DESC("\t - clear all Event Status registers, errors, output queue") SCPI_CMD_TAG(0)}, // -- Standard Event Status Group [EVENT]-[ENABLE] - {"*ESE", SCPI_CoreEse, SCPI_CMD_DESC("<0..255> - set Standard Event Status Enable (event mask)") SCPI_CMD_TAG(0)}, + {"*ESE", SCPI_CoreEse, SCPI_CMD_DESC("<0..255> - set Standard Event Status Enable / event mask") SCPI_CMD_TAG(0)}, {"*ESE?", SCPI_CoreEseQ, SCPI_CMD_DESC("\t - read ESE (0..255)") SCPI_CMD_TAG(0)}, - {"*ESR?", SCPI_CoreEsrQ, SCPI_CMD_DESC("\t - read+clear Standard Event Status register") SCPI_CMD_TAG(0)}, + {"*ESR?", SCPI_CoreEsrQ, SCPI_CMD_DESC("\t - read+clear Standard Event Status register (0..255)") SCPI_CMD_TAG(0)}, // -- IEEE Mandated Commands (continued ...) - {"*IDN?", SCPI_CoreIdnQ, SCPI_CMD_DESC("\t - read device identifier (multi-line string)") SCPI_CMD_TAG(0)}, + {"*IDN?", SCPI_CoreIdnQ, SCPI_CMD_DESC("\t - read device identifier (str,str,str,str)") SCPI_CMD_TAG(0)}, {"*OPC", SCPI_CoreOpc, SCPI_CMD_DESC("\t - complete ops preceding Operation Complete Command, set ESR.OPC 1") SCPI_CMD_TAG(0)}, - {"*OPC?", SCPI_CoreOpcQ, SCPI_CMD_DESC("\t - read ESR.OPC (0:ongoing ops, 1:done)") SCPI_CMD_TAG(0)}, + {"*OPC?", SCPI_CoreOpcQ, SCPI_CMD_DESC("\t - read ESR.OPC (0:ongoing-ops 1:done)") SCPI_CMD_TAG(0)}, {"*RST", SCPI_CoreRst, SCPI_CMD_DESC("\t - reset instrument and interface") SCPI_CMD_TAG(0)}, - {"*SRE", SCPI_CoreSre, SCPI_CMD_DESC("<0..255> - set Service Request Enable (event mask over STB)") SCPI_CMD_TAG(0)}, + {"*SRE", SCPI_CoreSre, SCPI_CMD_DESC("<0..255> - set Service Request Enable / event mask over STB") SCPI_CMD_TAG(0)}, {"*SRE?", SCPI_CoreSreQ, SCPI_CMD_DESC("\t - read SRE (0..255)") SCPI_CMD_TAG(0)}, {"*STB?", SCPI_CoreStbQ, SCPI_CMD_DESC("\t - read STatus Byte (0..255)") SCPI_CMD_TAG(0)}, - {"*TST?", My_CoreTstQ, SCPI_CMD_DESC("\t - read self-test result (0:no failures)") SCPI_CMD_TAG(0)}, + {"*TST?", My_CoreTstQ, SCPI_CMD_DESC("\t - read self-test result (0:no-failures)") SCPI_CMD_TAG(0)}, {"*WAI", SCPI_CoreWai, SCPI_CMD_DESC("\t - halt cmd execution until pending operations complete") SCPI_CMD_TAG(0)}, /* Required SCPI commands (SCPI std V1999.0 4.2.1) : SYSTem:ERRor, STATus:OPERation, STATus:QUEStionable and STATus:PRESet */ - {"SYSTem:ERRor[:NEXT]?", SCPI_SystemErrorNextQ, SCPI_CMD_DESC("\t - get next error in queue (int error,string)") SCPI_CMD_TAG(0)}, + {"SYSTem:ERRor[:NEXT]?", SCPI_SystemErrorNextQ, SCPI_CMD_DESC("\t - get next error in queue (int-errno,str)") SCPI_CMD_TAG(0)}, {"SYSTem:ERRor:COUNt?", SCPI_SystemErrorCountQ, SCPI_CMD_DESC("\t - queued error count (0.." SCPI_ERROR_QUEUE_SIZE_STR ")") SCPI_CMD_TAG(0)}, - {"SYSTem:VERSion?", SCPI_SystemVersionQ, SCPI_CMD_DESC("\t - query system version (version expr)") SCPI_CMD_TAG(0)}, + {"SYSTem:VERSion?", SCPI_SystemVersionQ, SCPI_CMD_DESC("\t - query system version (str)") SCPI_CMD_TAG(0)}, // -- Operation Status Group [CONDITION]-[EVENT]-[ENABLE] {"STATus:OPERation:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, {"STATus:OPERation[:EVENt]?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, - {"STATus:OPERation:ENABle", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"STATus:OPERation:ENABle", SCPI_Stub, SCPI_CMD_DESC("\t - not implemented") SCPI_CMD_TAG(0)}, {"STATus:OPERation:ENABle?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, // -- Questionable Status Group [CONDITION]-[EVENT]-[ENABLE] - {"STATus:QUEStionable:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented") SCPI_CMD_TAG(0)}, // "\t - read momentary Questionable Condition register (0..65535)" + {"STATus:QUEStionable:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, // "\t - read momentary Questionable Condition register (0..65535)" {"STATus:QUEStionable[:EVENt]?", SCPI_StatusQuestionableEventQ, SCPI_CMD_DESC("\t - read Questionable Event register (0..65535)") SCPI_CMD_TAG(0)}, - {"STATus:QUEStionable:ENABle", SCPI_StatusQuestionableEnable, SCPI_CMD_DESC("<0..65535> - set Questionable Enable (event mask)") SCPI_CMD_TAG(0)}, + {"STATus:QUEStionable:ENABle", SCPI_StatusQuestionableEnable, SCPI_CMD_DESC("<0..65535> - set Questionable Enable / event mask") SCPI_CMD_TAG(0)}, {"STATus:QUEStionable:ENABle?", SCPI_StatusQuestionableEnableQ, SCPI_CMD_DESC("\t - Questionable Status Enable (0..65535)") SCPI_CMD_TAG(0)}, {"STATus:PRESet", SCPI_StatusPreset, SCPI_CMD_DESC("\t - load Status sub-system register defaults") SCPI_CMD_TAG(0)}, /* commands specific to DMM example with TEST sub-system */ - {"SYSTem:COMMunication:TCPIP:CONTROL?", SCPI_SystemCommTcpipControlQ, SCPI_CMD_DESC("\t - read TCPIP control port") SCPI_CMD_TAG(0)}, + {"SYSTem:COMMunication:TCPIP:CONTROL?", SCPI_SystemCommTcpipControlQ, SCPI_CMD_DESC("\t - read TCPIP control port (int)") SCPI_CMD_TAG(0)}, {"CONFigure:VOLTage:DC", DMM_ConfigureVoltageDc, SCPI_CMD_DESC("[,] - test command") SCPI_CMD_TAG(0)}, {"MEASure:VOLTage:DC?", DMM_MeasureVoltageDcQ, SCPI_CMD_DESC("[[,]] - test command (0)") SCPI_CMD_TAG(0)}, {"MEASure:VOLTage:DC:RATio?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, @@ -407,9 +407,9 @@ const scpi_command_t scpi_commands[] = { {"MEASure:FREQuency?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, {"MEASure:PERiod?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, {"TEST:BOOL", TEST_Bool, SCPI_CMD_DESC(" - test command") SCPI_CMD_TAG(0)}, - {"TEST:CHOice?", TEST_ChoiceQ, SCPI_CMD_DESC(" - test command (\"BUS\":5,\"IMMediate\":6,\"EXTernal\",7)") SCPI_CMD_TAG(0)}, - {"TEST#:NUMbers#", TEST_Numbers, SCPI_CMD_DESC("\t - test command with numbers - default 1") SCPI_CMD_TAG(0)}, - {"TEST:TEXT", TEST_Text, SCPI_CMD_DESC("[, ...] - debug print as received") SCPI_CMD_TAG(0)}, + {"TEST:CHOice?", TEST_ChoiceQ, SCPI_CMD_DESC(" - test command (\"BUS\":5 \"IMMediate\":6 \"EXTernal\":7)") SCPI_CMD_TAG(0)}, + {"TEST#:NUMbers#", TEST_Numbers, SCPI_CMD_DESC("\t - test command with optional numbers - default 1") SCPI_CMD_TAG(0)}, + {"TEST:TEXT", TEST_Text, SCPI_CMD_DESC("[, ...] - debug print param as received") SCPI_CMD_TAG(0)}, {"TEST:ARBitrary?", TEST_ArbQ, SCPI_CMD_DESC(" - receive and return block data (block data)") SCPI_CMD_TAG(0)}, {"TEST:CHANnellist", TEST_Chanlst, SCPI_CMD_DESC(" - test channel list parsing") SCPI_CMD_TAG(0)}, diff --git a/examples/common/scpi-def.cpp b/examples/common/scpi-def.cpp index df852a6d..432edfb1 100644 --- a/examples/common/scpi-def.cpp +++ b/examples/common/scpi-def.cpp @@ -364,38 +364,38 @@ const scpi_command_t scpi_commands[] = { /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1): *CLS *ESE *ESE? *ESR? *IDN? *OPC *OPC? *RST *SRE *SRE? *STB? *TST? *WAI */ {"*CLS", SCPI_CoreCls, SCPI_CMD_DESC("\t - clear all Event Status registers, errors, output queue") SCPI_CMD_TAG(0)}, // -- Standard Event Status Group [EVENT]-[ENABLE] - {"*ESE", SCPI_CoreEse, SCPI_CMD_DESC("<0..255> - set Standard Event Status Enable (event mask)") SCPI_CMD_TAG(0)}, + {"*ESE", SCPI_CoreEse, SCPI_CMD_DESC("<0..255> - set Standard Event Status Enable / event mask") SCPI_CMD_TAG(0)}, {"*ESE?", SCPI_CoreEseQ, SCPI_CMD_DESC("\t - read ESE (0..255)") SCPI_CMD_TAG(0)}, - {"*ESR?", SCPI_CoreEsrQ, SCPI_CMD_DESC("\t - read+clear Standard Event Status register") SCPI_CMD_TAG(0)}, + {"*ESR?", SCPI_CoreEsrQ, SCPI_CMD_DESC("\t - read+clear Standard Event Status register (0..255)") SCPI_CMD_TAG(0)}, // -- IEEE Mandated Commands (continued ...) - {"*IDN?", SCPI_CoreIdnQ, SCPI_CMD_DESC("\t - read device identifier (multi-line string)") SCPI_CMD_TAG(0)}, + {"*IDN?", SCPI_CoreIdnQ, SCPI_CMD_DESC("\t - read device identifier (str,str,str,str)") SCPI_CMD_TAG(0)}, {"*OPC", SCPI_CoreOpc, SCPI_CMD_DESC("\t - complete ops preceding Operation Complete Command, set ESR.OPC 1") SCPI_CMD_TAG(0)}, - {"*OPC?", SCPI_CoreOpcQ, SCPI_CMD_DESC("\t - read ESR.OPC (0:ongoing ops, 1:done)") SCPI_CMD_TAG(0)}, + {"*OPC?", SCPI_CoreOpcQ, SCPI_CMD_DESC("\t - read ESR.OPC (0:ongoing-ops 1:done)") SCPI_CMD_TAG(0)}, {"*RST", SCPI_CoreRst, SCPI_CMD_DESC("\t - reset instrument and interface") SCPI_CMD_TAG(0)}, - {"*SRE", SCPI_CoreSre, SCPI_CMD_DESC("<0..255> - set Service Request Enable (event mask over STB)") SCPI_CMD_TAG(0)}, + {"*SRE", SCPI_CoreSre, SCPI_CMD_DESC("<0..255> - set Service Request Enable / event mask over STB") SCPI_CMD_TAG(0)}, {"*SRE?", SCPI_CoreSreQ, SCPI_CMD_DESC("\t - read SRE (0..255)") SCPI_CMD_TAG(0)}, {"*STB?", SCPI_CoreStbQ, SCPI_CMD_DESC("\t - read STatus Byte (0..255)") SCPI_CMD_TAG(0)}, - {"*TST?", My_CoreTstQ, SCPI_CMD_DESC("\t - read self-test result (0:no failures)") SCPI_CMD_TAG(0)}, + {"*TST?", My_CoreTstQ, SCPI_CMD_DESC("\t - read self-test result (0:no-failures)") SCPI_CMD_TAG(0)}, {"*WAI", SCPI_CoreWai, SCPI_CMD_DESC("\t - halt cmd execution until pending operations complete") SCPI_CMD_TAG(0)}, /* Required SCPI commands (SCPI std V1999.0 4.2.1) : SYSTem:ERRor, STATus:OPERation, STATus:QUEStionable and STATus:PRESet */ - {"SYSTem:ERRor[:NEXT]?", SCPI_SystemErrorNextQ, SCPI_CMD_DESC("\t - get next error in queue (int error,string)") SCPI_CMD_TAG(0)}, + {"SYSTem:ERRor[:NEXT]?", SCPI_SystemErrorNextQ, SCPI_CMD_DESC("\t - get next error in queue (int-errno,str)") SCPI_CMD_TAG(0)}, {"SYSTem:ERRor:COUNt?", SCPI_SystemErrorCountQ, SCPI_CMD_DESC("\t - queued error count (0.." SCPI_ERROR_QUEUE_SIZE_STR ")") SCPI_CMD_TAG(0)}, - {"SYSTem:VERSion?", SCPI_SystemVersionQ, SCPI_CMD_DESC("\t - query system version (version expr)") SCPI_CMD_TAG(0)}, + {"SYSTem:VERSion?", SCPI_SystemVersionQ, SCPI_CMD_DESC("\t - query system version (str)") SCPI_CMD_TAG(0)}, // -- Operation Status Group [CONDITION]-[EVENT]-[ENABLE] {"STATus:OPERation:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, {"STATus:OPERation[:EVENt]?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, - {"STATus:OPERation:ENABle", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, + {"STATus:OPERation:ENABle", SCPI_Stub, SCPI_CMD_DESC("\t - not implemented") SCPI_CMD_TAG(0)}, {"STATus:OPERation:ENABle?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, // -- Questionable Status Group [CONDITION]-[EVENT]-[ENABLE] - {"STATus:QUEStionable:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented") SCPI_CMD_TAG(0)}, // "\t - read momentary Questionable Condition register (0..65535)" + {"STATus:QUEStionable:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, // "\t - read momentary Questionable Condition register (0..65535)" {"STATus:QUEStionable[:EVENt]?", SCPI_StatusQuestionableEventQ, SCPI_CMD_DESC("\t - read Questionable Event register (0..65535)") SCPI_CMD_TAG(0)}, - {"STATus:QUEStionable:ENABle", SCPI_StatusQuestionableEnable, SCPI_CMD_DESC("<0..65535> - set Questionable Enable (event mask)") SCPI_CMD_TAG(0)}, + {"STATus:QUEStionable:ENABle", SCPI_StatusQuestionableEnable, SCPI_CMD_DESC("<0..65535> - set Questionable Enable / event mask") SCPI_CMD_TAG(0)}, {"STATus:QUEStionable:ENABle?", SCPI_StatusQuestionableEnableQ, SCPI_CMD_DESC("\t - Questionable Status Enable (0..65535)") SCPI_CMD_TAG(0)}, {"STATus:PRESet", SCPI_StatusPreset, SCPI_CMD_DESC("\t - load Status sub-system register defaults") SCPI_CMD_TAG(0)}, /* commands specific to DMM example with TEST sub-system */ - {"SYSTem:COMMunication:TCPIP:CONTROL?", SCPI_SystemCommTcpipControlQ, SCPI_CMD_DESC("\t - read TCPIP control port") SCPI_CMD_TAG(0)}, + {"SYSTem:COMMunication:TCPIP:CONTROL?", SCPI_SystemCommTcpipControlQ, SCPI_CMD_DESC("\t - read TCPIP control port (int)") SCPI_CMD_TAG(0)}, {"CONFigure:VOLTage:DC", DMM_ConfigureVoltageDc, SCPI_CMD_DESC("[,] - test command") SCPI_CMD_TAG(0)}, {"MEASure:VOLTage:DC?", DMM_MeasureVoltageDcQ, SCPI_CMD_DESC("[[,]] - test command (0)") SCPI_CMD_TAG(0)}, {"MEASure:VOLTage:DC:RATio?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, @@ -407,9 +407,9 @@ const scpi_command_t scpi_commands[] = { {"MEASure:FREQuency?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, {"MEASure:PERiod?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, {"TEST:BOOL", TEST_Bool, SCPI_CMD_DESC(" - test command") SCPI_CMD_TAG(0)}, - {"TEST:CHOice?", TEST_ChoiceQ, SCPI_CMD_DESC(" - test command (\"BUS\":5,\"IMMediate\":6,\"EXTernal\",7)") SCPI_CMD_TAG(0)}, - {"TEST#:NUMbers#", TEST_Numbers, SCPI_CMD_DESC("\t - test command with numbers - default 1") SCPI_CMD_TAG(0)}, - {"TEST:TEXT", TEST_Text, SCPI_CMD_DESC("[, ...] - debug print as received") SCPI_CMD_TAG(0)}, + {"TEST:CHOice?", TEST_ChoiceQ, SCPI_CMD_DESC(" - test command (\"BUS\":5 \"IMMediate\":6 \"EXTernal\":7)") SCPI_CMD_TAG(0)}, + {"TEST#:NUMbers#", TEST_Numbers, SCPI_CMD_DESC("\t - test command with optional numbers - default 1") SCPI_CMD_TAG(0)}, + {"TEST:TEXT", TEST_Text, SCPI_CMD_DESC("[, ...] - debug print param as received") SCPI_CMD_TAG(0)}, {"TEST:ARBitrary?", TEST_ArbQ, SCPI_CMD_DESC(" - receive and return block data (block data)") SCPI_CMD_TAG(0)}, {"TEST:CHANnellist", TEST_Chanlst, SCPI_CMD_DESC(" - test channel list parsing") SCPI_CMD_TAG(0)}, diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c index 5c72d7d0..8c5f8b51 100644 --- a/libscpi/src/utils.c +++ b/libscpi/src/utils.c @@ -1140,37 +1140,23 @@ uint64_t SCPI_Swap64(uint64_t val) { ((val & 0x00FF000000000000ull) >> 40) | ((val & 0xFF00000000000000ull) >> 56); } - - -/* Cherokee: strncasestrn() and strncasestr() - * - * Authors: - * Alvaro Lopez Ortega - * - * Copyright (C) 2001-2014 Alvaro Lopez Ortega - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ -#define CHEROKEE_CHAR_TO_LOWER(_ch) ((_ch) | 32) -#define CHEROKEE_CHAR_TO_UPPER(_ch) ((_ch) & ~32) +#define CHAR_TO_UPPER(c) ((c)>96 && (c)<123 ? (char)((c) ^ 0x20) : (c)) +#define CHAR_TO_LOWER(c) ((c)>64 && (c)< 91 ? (char)((c) | 0x20) : (c)) +/** + * @brief Locate a binary substring within a binary string (case-insensitive `strnstrn`). + * @param[in] s binary string + * @param[in] slen length of binary string s + * @param[in] find binary substring + * @param[in] findlen length of binary substring find + * @return Pointer to first match in s if found, otherwise `NULL`. + * @author Alvaro Lopez Ortega + */ char * strncasestrn (const char *s, size_t slen, const char *find, size_t findlen) { - char c; - char sc; + char first; + char cursor_chr; if ((find == NULL) || (findlen == 0)) return (char *)s; @@ -1178,15 +1164,15 @@ char * strncasestrn (const char *s, size_t slen, const char *find, size_t findle if ((*find == '\0')) return (char *)s; - c = *find; + first = CHAR_TO_LOWER(*find); find++; findlen--; do { do { - if (slen-- < 1 || (sc = *s++) == '\0') + if (slen-- < 1 || (cursor_chr = *s++) == '\0') return NULL; - } while (CHEROKEE_CHAR_TO_LOWER(sc) != CHEROKEE_CHAR_TO_LOWER(c)); + } while (CHAR_TO_LOWER(cursor_chr) != first); if (findlen > slen) { return NULL; } @@ -1196,6 +1182,13 @@ char * strncasestrn (const char *s, size_t slen, const char *find, size_t findle return (char *)s; } +/** + * @brief Locate a substring in a binary string (case-insensitive `strnstr`). + * @param[in] s binary string + * @param[in] find substring (zero-terminated) + * @param[in] slen length of binary string s + * @return Pointer to first match in s if found, otherwise `NULL`. + */ char * strncasestr (const char *s, const char *find, size_t slen) { return strncasestrn (s, slen, find, strlen(find)); From c394eb954fe1ede45c9372e795b4705f9c7e25c9 Mon Sep 17 00:00:00 2001 From: helge Date: Sat, 7 Jan 2023 17:27:45 +0100 Subject: [PATCH 10/22] propagate MODE to Makefile for cross-compiling Allow makefile to be used directly for cross-compiling (e.g. when treated as a git submodule). This requires CC and AR to be passed for a particular toolchain, but CFLAGS must also specify CPU and FPU options -> introduce MODE variable. CFLAGS cannot be passed without need to override in the makefile, so a new variable is needed. Cortex-M7 Example (linker: library and project use of VFP registers must match): CC=arm-none-eabi-gcc AR=arm-none-eabi-ar MODE="-mcpu=cortex-m7 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard" (commit can be cherry-picked) --- libscpi/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libscpi/Makefile b/libscpi/Makefile index 9a0b5ee5..d788a9e3 100644 --- a/libscpi/Makefile +++ b/libscpi/Makefile @@ -1,9 +1,9 @@ VERSION = 2.1.0 LIBNAME = scpi -CFLAGS += -Wextra -Wmissing-prototypes -Wimplicit -Iinc +CFLAGS += $(MODE) -Wextra -Wmissing-prototypes -Wimplicit -Iinc CFLAGS_SHARED += $(CFLAGS) -fPIC -LDFLAGS += -lm -Wl,--as-needed +LDFLAGS += $(MODE) -lm -Wl,--as-needed #TESTCFLAGS += $(CFLAGS) `pkg-config --cflags cunit` #TESTLDFLAGS += $(LDFLAGS) `pkg-config --libs cunit` TESTCFLAGS += $(CFLAGS) From 1e1b594e491312b6550081ba73177b7a41e31f4d Mon Sep 17 00:00:00 2001 From: helge Date: Sat, 14 Jan 2023 17:34:10 +0100 Subject: [PATCH 11/22] provide more elaborate description depending on USE_HELP_FILTER When compiled with USE_HELP_FILTER 1, HELP? accepts an optional search string -> HELP? command description extended to reflect input and output types. --- examples/common/scpi-def.c | 7 +++++-- examples/common/scpi-def.cpp | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/common/scpi-def.c b/examples/common/scpi-def.c index 38fa5e4d..8ac22529 100644 --- a/examples/common/scpi-def.c +++ b/examples/common/scpi-def.c @@ -359,8 +359,11 @@ static scpi_result_t My_CoreTstQ(scpi_t * context) { const scpi_command_t scpi_commands[] = { /* Optional help command */ - {"HELP?", SCPI_HelpQ, SCPI_CMD_DESC("\t - list supported commands") SCPI_CMD_TAG(0)}, - +#if USE_HELP_FILTER + {"HELP?", SCPI_HelpQ, SCPI_CMD_DESC("[] - list supported commands [containing \"\"] (multiple block data)") SCPI_CMD_TAG(0)}, +#else + {"HELP?", SCPI_HelpQ, SCPI_CMD_DESC("\t - list supported commands (multiple block data)") SCPI_CMD_TAG(0)}, +#endif /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1): *CLS *ESE *ESE? *ESR? *IDN? *OPC *OPC? *RST *SRE *SRE? *STB? *TST? *WAI */ {"*CLS", SCPI_CoreCls, SCPI_CMD_DESC("\t - clear all Event Status registers, errors, output queue") SCPI_CMD_TAG(0)}, // -- Standard Event Status Group [EVENT]-[ENABLE] diff --git a/examples/common/scpi-def.cpp b/examples/common/scpi-def.cpp index 432edfb1..6abdab09 100644 --- a/examples/common/scpi-def.cpp +++ b/examples/common/scpi-def.cpp @@ -359,7 +359,11 @@ static scpi_result_t My_CoreTstQ(scpi_t * context) { const scpi_command_t scpi_commands[] = { /* Optional help command */ - {"HELP?", SCPI_HelpQ, SCPI_CMD_DESC("\t - list supported commands") SCPI_CMD_TAG(0)}, +#if USE_HELP_FILTER + {"HELP?", SCPI_HelpQ, SCPI_CMD_DESC("[] - list supported commands [containing \"\"] (multiple block data)") SCPI_CMD_TAG(0)}, +#else + {"HELP?", SCPI_HelpQ, SCPI_CMD_DESC("\t - list supported commands (multiple block data)") SCPI_CMD_TAG(0)}, +#endif /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1): *CLS *ESE *ESE? *ESR? *IDN? *OPC *OPC? *RST *SRE *SRE? *STB? *TST? *WAI */ {"*CLS", SCPI_CoreCls, SCPI_CMD_DESC("\t - clear all Event Status registers, errors, output queue") SCPI_CMD_TAG(0)}, From 36ddafecf41f52ef016e310ef5f2edf0afc9a3f7 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 17 Jan 2023 14:36:25 +0100 Subject: [PATCH 12/22] strncasestr, strncasestrn_s, pp_xstr clean-up and formatting remove / comment currently unused code. Double-indirection helper definition moved to utils.h. --- examples/common/scpi-def.c | 3 --- examples/common/scpi-def.cpp | 3 --- examples/common/scpi-def.h | 2 ++ libscpi/inc/scpi/minimal.h | 1 - libscpi/inc/scpi/utils.h | 6 +++++- libscpi/src/utils.c | 22 +++++++++++----------- libscpi/src/utils_private.h | 6 +----- 7 files changed, 19 insertions(+), 24 deletions(-) diff --git a/examples/common/scpi-def.c b/examples/common/scpi-def.c index 8ac22529..5395fc19 100644 --- a/examples/common/scpi-def.c +++ b/examples/common/scpi-def.c @@ -353,9 +353,6 @@ static scpi_result_t My_CoreTstQ(scpi_t * context) { return SCPI_RES_OK; } -#define pp_xstr(s) pp_str(s) -#define pp_str(s) #s -#define SCPI_ERROR_QUEUE_SIZE_STR pp_xstr(SCPI_ERROR_QUEUE_SIZE) const scpi_command_t scpi_commands[] = { /* Optional help command */ diff --git a/examples/common/scpi-def.cpp b/examples/common/scpi-def.cpp index 6abdab09..dcc8c46d 100644 --- a/examples/common/scpi-def.cpp +++ b/examples/common/scpi-def.cpp @@ -353,9 +353,6 @@ static scpi_result_t My_CoreTstQ(scpi_t * context) { return SCPI_RES_OK; } -#define pp_xstr(s) pp_str(s) -#define pp_str(s) #s -#define SCPI_ERROR_QUEUE_SIZE_STR pp_xstr(SCPI_ERROR_QUEUE_SIZE) const scpi_command_t scpi_commands[] = { /* Optional help command */ diff --git a/examples/common/scpi-def.h b/examples/common/scpi-def.h index 9e89f95a..33e893a3 100644 --- a/examples/common/scpi-def.h +++ b/examples/common/scpi-def.h @@ -41,6 +41,8 @@ extern "C" { #define SCPI_IDN3 NULL #define SCPI_IDN4 "01-02" +#define SCPI_ERROR_QUEUE_SIZE_STR PP_XSTR(SCPI_ERROR_QUEUE_SIZE) + extern const scpi_command_t scpi_commands[]; extern scpi_interface_t scpi_interface; extern char scpi_input_buffer[]; diff --git a/libscpi/inc/scpi/minimal.h b/libscpi/inc/scpi/minimal.h index 8b87b777..1c6626f7 100644 --- a/libscpi/inc/scpi/minimal.h +++ b/libscpi/inc/scpi/minimal.h @@ -66,4 +66,3 @@ extern "C" { #endif #endif /* SCPI_MINIMAL_H */ - diff --git a/libscpi/inc/scpi/utils.h b/libscpi/inc/scpi/utils.h index 055e4683..fb853313 100644 --- a/libscpi/inc/scpi/utils.h +++ b/libscpi/inc/scpi/utils.h @@ -54,9 +54,13 @@ extern "C" { /* deprecated finction, should be removed later */ #define SCPI_LongToStr(val, str, len, base) SCPI_Int32ToStr((val), (str), (len), (base), TRUE) +/* Pre-Processor Transform String (double indirection PP_XSTR(s) converts a number definition into a string definiton) */ +#define PP_STR(s) #s +#define PP_XSTR(s) PP_STR(s) + + #ifdef __cplusplus } #endif #endif /* SCPI_UTILS_H */ - diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c index 8c5f8b51..27a9975b 100644 --- a/libscpi/src/utils.c +++ b/libscpi/src/utils.c @@ -1182,14 +1182,14 @@ char * strncasestrn (const char *s, size_t slen, const char *find, size_t findle return (char *)s; } -/** - * @brief Locate a substring in a binary string (case-insensitive `strnstr`). - * @param[in] s binary string - * @param[in] find substring (zero-terminated) - * @param[in] slen length of binary string s - * @return Pointer to first match in s if found, otherwise `NULL`. - */ -char * strncasestr (const char *s, const char *find, size_t slen) -{ - return strncasestrn (s, slen, find, strlen(find)); -} +#/** +# * @brief Locate a substring in a binary string (case-insensitive `strnstr`). +# * @param[in] s binary string +# * @param[in] find substring (zero-terminated) +# * @param[in] slen length of binary string s +# * @return Pointer to first match in s if found, otherwise `NULL`. +# */ +#char * strncasestr (const char *s, const char *find, size_t slen) +#{ +# return strncasestrn (s, slen, find, strlen(find)); +#} diff --git a/libscpi/src/utils_private.h b/libscpi/src/utils_private.h index 05d39cb9..d3af82e8 100644 --- a/libscpi/src/utils_private.h +++ b/libscpi/src/utils_private.h @@ -99,12 +99,8 @@ extern "C" { char *OUR_strndup(const char *s, size_t n); #endif - char * strncasestr (const char *s, const char *find, size_t slen); char * strncasestrn (const char *s, size_t slen, const char *find, size_t findlen); - -#ifndef strncasestrn_s -#define strncasestrn_s(s,s_len,lit) strncasestrn(s, s_len, lit, sizeof(lit)-1) -#endif +# char * strncasestr (const char *s, const char *find, size_t slen); #ifndef min #define min(a, b) (((a) < (b)) ? (a) : (b)) From 9c66dcdc4cd1f9b24415fdf2a7fbb5404c730661 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 17 Jan 2023 14:41:34 +0100 Subject: [PATCH 13/22] fix C89 issue (FALSE, for syntax) --- libscpi/src/minimal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libscpi/src/minimal.c b/libscpi/src/minimal.c index 4ead96b3..a14f8aeb 100644 --- a/libscpi/src/minimal.c +++ b/libscpi/src/minimal.c @@ -223,10 +223,10 @@ scpi_result_t SCPI_HelpQ(scpi_t * context) { #if USE_HELP_FILTER size_t search_string_len = 0; const char * search_string = NULL; - scpi_bool_t narrowed_down = SCPI_ParamCharacters(context, &search_string, &search_string_len, false); + scpi_bool_t narrowed_down = SCPI_ParamCharacters(context, &search_string, &search_string_len, FALSE); #endif - - for(int i = 0; context->cmdlist[i].pattern != NULL; i++) { + size_t i; + for(i = 0; context->cmdlist[i].pattern != NULL; i++) { size_t pattern_len = strlen(context->cmdlist[i].pattern); #if USE_HELP_FILTER if(narrowed_down && (NULL == strncasestrn(context->cmdlist[i].pattern, pattern_len, search_string, search_string_len))){ From 0e7c8286c633bdb6f95119a7b6b323a38f118de8 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 17 Jan 2023 14:48:31 +0100 Subject: [PATCH 14/22] remove strcasestr --- libscpi/src/utils.c | 12 ------------ libscpi/src/utils_private.h | 1 - 2 files changed, 13 deletions(-) diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c index 27a9975b..7ee0958c 100644 --- a/libscpi/src/utils.c +++ b/libscpi/src/utils.c @@ -1181,15 +1181,3 @@ char * strncasestrn (const char *s, size_t slen, const char *find, size_t findle s--; return (char *)s; } - -#/** -# * @brief Locate a substring in a binary string (case-insensitive `strnstr`). -# * @param[in] s binary string -# * @param[in] find substring (zero-terminated) -# * @param[in] slen length of binary string s -# * @return Pointer to first match in s if found, otherwise `NULL`. -# */ -#char * strncasestr (const char *s, const char *find, size_t slen) -#{ -# return strncasestrn (s, slen, find, strlen(find)); -#} diff --git a/libscpi/src/utils_private.h b/libscpi/src/utils_private.h index d3af82e8..7955433a 100644 --- a/libscpi/src/utils_private.h +++ b/libscpi/src/utils_private.h @@ -100,7 +100,6 @@ extern "C" { #endif char * strncasestrn (const char *s, size_t slen, const char *find, size_t findlen); -# char * strncasestr (const char *s, const char *find, size_t slen); #ifndef min #define min(a, b) (((a) < (b)) ? (a) : (b)) From 5dfac2b7ca3fb831434065a18da6ebd84ca4b731 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 17 Jan 2023 16:51:57 +0100 Subject: [PATCH 15/22] strncasecmp -> SCPIDEFINE_strncasecmp --- libscpi/src/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c index 7ee0958c..cf851929 100644 --- a/libscpi/src/utils.c +++ b/libscpi/src/utils.c @@ -1176,7 +1176,7 @@ char * strncasestrn (const char *s, size_t slen, const char *find, size_t findle if (findlen > slen) { return NULL; } - } while (strncasecmp (s, find, findlen) != 0); + } while (SCPIDEFINE_strncasecmp(s, find, findlen) != 0); s--; return (char *)s; From 5153e039a08640666dca9fb06bb8c54ea981f709 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 17 Jan 2023 17:03:03 +0100 Subject: [PATCH 16/22] C style comments --- examples/common/scpi-def.c | 12 ++++++------ examples/common/scpi-def.cpp | 13 ++++++------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/examples/common/scpi-def.c b/examples/common/scpi-def.c index 5395fc19..050d89a0 100644 --- a/examples/common/scpi-def.c +++ b/examples/common/scpi-def.c @@ -363,11 +363,11 @@ const scpi_command_t scpi_commands[] = { #endif /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1): *CLS *ESE *ESE? *ESR? *IDN? *OPC *OPC? *RST *SRE *SRE? *STB? *TST? *WAI */ {"*CLS", SCPI_CoreCls, SCPI_CMD_DESC("\t - clear all Event Status registers, errors, output queue") SCPI_CMD_TAG(0)}, - // -- Standard Event Status Group [EVENT]-[ENABLE] + /* -- Standard Event Status Group [EVENT]-[ENABLE] */ {"*ESE", SCPI_CoreEse, SCPI_CMD_DESC("<0..255> - set Standard Event Status Enable / event mask") SCPI_CMD_TAG(0)}, {"*ESE?", SCPI_CoreEseQ, SCPI_CMD_DESC("\t - read ESE (0..255)") SCPI_CMD_TAG(0)}, {"*ESR?", SCPI_CoreEsrQ, SCPI_CMD_DESC("\t - read+clear Standard Event Status register (0..255)") SCPI_CMD_TAG(0)}, - // -- IEEE Mandated Commands (continued ...) + /* -- IEEE Mandated Commands (continued ...) */ {"*IDN?", SCPI_CoreIdnQ, SCPI_CMD_DESC("\t - read device identifier (str,str,str,str)") SCPI_CMD_TAG(0)}, {"*OPC", SCPI_CoreOpc, SCPI_CMD_DESC("\t - complete ops preceding Operation Complete Command, set ESR.OPC 1") SCPI_CMD_TAG(0)}, {"*OPC?", SCPI_CoreOpcQ, SCPI_CMD_DESC("\t - read ESR.OPC (0:ongoing-ops 1:done)") SCPI_CMD_TAG(0)}, @@ -378,17 +378,17 @@ const scpi_command_t scpi_commands[] = { {"*TST?", My_CoreTstQ, SCPI_CMD_DESC("\t - read self-test result (0:no-failures)") SCPI_CMD_TAG(0)}, {"*WAI", SCPI_CoreWai, SCPI_CMD_DESC("\t - halt cmd execution until pending operations complete") SCPI_CMD_TAG(0)}, - /* Required SCPI commands (SCPI std V1999.0 4.2.1) : SYSTem:ERRor, STATus:OPERation, STATus:QUEStionable and STATus:PRESet */ + /* Required SCPI commands (SCPI std V1999.0 4.2.1) : SYSTem:ERRor, STATus:OPERation, STATus:QUEStionable and STATus:PRESet */ {"SYSTem:ERRor[:NEXT]?", SCPI_SystemErrorNextQ, SCPI_CMD_DESC("\t - get next error in queue (int-errno,str)") SCPI_CMD_TAG(0)}, {"SYSTem:ERRor:COUNt?", SCPI_SystemErrorCountQ, SCPI_CMD_DESC("\t - queued error count (0.." SCPI_ERROR_QUEUE_SIZE_STR ")") SCPI_CMD_TAG(0)}, {"SYSTem:VERSion?", SCPI_SystemVersionQ, SCPI_CMD_DESC("\t - query system version (str)") SCPI_CMD_TAG(0)}, - // -- Operation Status Group [CONDITION]-[EVENT]-[ENABLE] + /* -- Operation Status Group [CONDITION]-[EVENT]-[ENABLE] */ {"STATus:OPERation:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, {"STATus:OPERation[:EVENt]?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, {"STATus:OPERation:ENABle", SCPI_Stub, SCPI_CMD_DESC("\t - not implemented") SCPI_CMD_TAG(0)}, {"STATus:OPERation:ENABle?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, - // -- Questionable Status Group [CONDITION]-[EVENT]-[ENABLE] - {"STATus:QUEStionable:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, // "\t - read momentary Questionable Condition register (0..65535)" + /* -- Questionable Status Group [CONDITION]-[EVENT]-[ENABLE] */ + {"STATus:QUEStionable:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, /* "\t - read momentary Questionable Condition register (0..65535)" */ {"STATus:QUEStionable[:EVENt]?", SCPI_StatusQuestionableEventQ, SCPI_CMD_DESC("\t - read Questionable Event register (0..65535)") SCPI_CMD_TAG(0)}, {"STATus:QUEStionable:ENABle", SCPI_StatusQuestionableEnable, SCPI_CMD_DESC("<0..65535> - set Questionable Enable / event mask") SCPI_CMD_TAG(0)}, {"STATus:QUEStionable:ENABle?", SCPI_StatusQuestionableEnableQ, SCPI_CMD_DESC("\t - Questionable Status Enable (0..65535)") SCPI_CMD_TAG(0)}, diff --git a/examples/common/scpi-def.cpp b/examples/common/scpi-def.cpp index dcc8c46d..052808e4 100644 --- a/examples/common/scpi-def.cpp +++ b/examples/common/scpi-def.cpp @@ -361,14 +361,13 @@ const scpi_command_t scpi_commands[] = { #else {"HELP?", SCPI_HelpQ, SCPI_CMD_DESC("\t - list supported commands (multiple block data)") SCPI_CMD_TAG(0)}, #endif - /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1): *CLS *ESE *ESE? *ESR? *IDN? *OPC *OPC? *RST *SRE *SRE? *STB? *TST? *WAI */ {"*CLS", SCPI_CoreCls, SCPI_CMD_DESC("\t - clear all Event Status registers, errors, output queue") SCPI_CMD_TAG(0)}, - // -- Standard Event Status Group [EVENT]-[ENABLE] + /* -- Standard Event Status Group [EVENT]-[ENABLE] */ {"*ESE", SCPI_CoreEse, SCPI_CMD_DESC("<0..255> - set Standard Event Status Enable / event mask") SCPI_CMD_TAG(0)}, {"*ESE?", SCPI_CoreEseQ, SCPI_CMD_DESC("\t - read ESE (0..255)") SCPI_CMD_TAG(0)}, {"*ESR?", SCPI_CoreEsrQ, SCPI_CMD_DESC("\t - read+clear Standard Event Status register (0..255)") SCPI_CMD_TAG(0)}, - // -- IEEE Mandated Commands (continued ...) + /* -- IEEE Mandated Commands (continued ...) */ {"*IDN?", SCPI_CoreIdnQ, SCPI_CMD_DESC("\t - read device identifier (str,str,str,str)") SCPI_CMD_TAG(0)}, {"*OPC", SCPI_CoreOpc, SCPI_CMD_DESC("\t - complete ops preceding Operation Complete Command, set ESR.OPC 1") SCPI_CMD_TAG(0)}, {"*OPC?", SCPI_CoreOpcQ, SCPI_CMD_DESC("\t - read ESR.OPC (0:ongoing-ops 1:done)") SCPI_CMD_TAG(0)}, @@ -379,17 +378,17 @@ const scpi_command_t scpi_commands[] = { {"*TST?", My_CoreTstQ, SCPI_CMD_DESC("\t - read self-test result (0:no-failures)") SCPI_CMD_TAG(0)}, {"*WAI", SCPI_CoreWai, SCPI_CMD_DESC("\t - halt cmd execution until pending operations complete") SCPI_CMD_TAG(0)}, - /* Required SCPI commands (SCPI std V1999.0 4.2.1) : SYSTem:ERRor, STATus:OPERation, STATus:QUEStionable and STATus:PRESet */ + /* Required SCPI commands (SCPI std V1999.0 4.2.1) : SYSTem:ERRor, STATus:OPERation, STATus:QUEStionable and STATus:PRESet */ {"SYSTem:ERRor[:NEXT]?", SCPI_SystemErrorNextQ, SCPI_CMD_DESC("\t - get next error in queue (int-errno,str)") SCPI_CMD_TAG(0)}, {"SYSTem:ERRor:COUNt?", SCPI_SystemErrorCountQ, SCPI_CMD_DESC("\t - queued error count (0.." SCPI_ERROR_QUEUE_SIZE_STR ")") SCPI_CMD_TAG(0)}, {"SYSTem:VERSion?", SCPI_SystemVersionQ, SCPI_CMD_DESC("\t - query system version (str)") SCPI_CMD_TAG(0)}, - // -- Operation Status Group [CONDITION]-[EVENT]-[ENABLE] + /* -- Operation Status Group [CONDITION]-[EVENT]-[ENABLE] */ {"STATus:OPERation:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, {"STATus:OPERation[:EVENt]?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, {"STATus:OPERation:ENABle", SCPI_Stub, SCPI_CMD_DESC("\t - not implemented") SCPI_CMD_TAG(0)}, {"STATus:OPERation:ENABle?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, - // -- Questionable Status Group [CONDITION]-[EVENT]-[ENABLE] - {"STATus:QUEStionable:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, // "\t - read momentary Questionable Condition register (0..65535)" + /* -- Questionable Status Group [CONDITION]-[EVENT]-[ENABLE] */ + {"STATus:QUEStionable:CONDition?", SCPI_StubQ, SCPI_CMD_DESC("\t - not implemented (0)") SCPI_CMD_TAG(0)}, /* "\t - read momentary Questionable Condition register (0..65535)" */ {"STATus:QUEStionable[:EVENt]?", SCPI_StatusQuestionableEventQ, SCPI_CMD_DESC("\t - read Questionable Event register (0..65535)") SCPI_CMD_TAG(0)}, {"STATus:QUEStionable:ENABle", SCPI_StatusQuestionableEnable, SCPI_CMD_DESC("<0..65535> - set Questionable Enable / event mask") SCPI_CMD_TAG(0)}, {"STATus:QUEStionable:ENABle?", SCPI_StatusQuestionableEnableQ, SCPI_CMD_DESC("\t - Questionable Status Enable (0..65535)") SCPI_CMD_TAG(0)}, From 8aa90a744995556e5cf17cd4d61b0ab039974859 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 17 Jan 2023 17:43:13 +0100 Subject: [PATCH 17/22] split off HELP? into help.h/.c --- libscpi/inc/scpi/help.h | 53 ++++++++++++++++++++++++ libscpi/inc/scpi/minimal.h | 1 - libscpi/inc/scpi/scpi.h | 1 + libscpi/src/help.c | 83 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 libscpi/inc/scpi/help.h create mode 100644 libscpi/src/help.c diff --git a/libscpi/inc/scpi/help.h b/libscpi/inc/scpi/help.h new file mode 100644 index 00000000..47eac0b9 --- /dev/null +++ b/libscpi/inc/scpi/help.h @@ -0,0 +1,53 @@ +/*- + * BSD 2-Clause License + * + * Copyright (c) 2023, Helge Wurst + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file help.h + * @date Tue Jan 17 16:27:00 UTC 2023 + * + * @brief HELP? [""] command handler + * + * + */ + +#ifndef SCPI_HELP_H +#define SCPI_HELP_H + +#include "scpi/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + scpi_result_t SCPI_HelpQ(scpi_t * context); + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_HELP_H */ diff --git a/libscpi/inc/scpi/minimal.h b/libscpi/inc/scpi/minimal.h index 1c6626f7..8208bfff 100644 --- a/libscpi/inc/scpi/minimal.h +++ b/libscpi/inc/scpi/minimal.h @@ -59,7 +59,6 @@ extern "C" { scpi_result_t SCPI_StatusOperationEnableQ(scpi_t * context); scpi_result_t SCPI_StatusOperationEnable(scpi_t * context); scpi_result_t SCPI_StatusPreset(scpi_t * context); - scpi_result_t SCPI_HelpQ(scpi_t * context); #ifdef __cplusplus } diff --git a/libscpi/inc/scpi/scpi.h b/libscpi/inc/scpi/scpi.h index ea28dd44..eb333bf1 100644 --- a/libscpi/inc/scpi/scpi.h +++ b/libscpi/inc/scpi/scpi.h @@ -46,6 +46,7 @@ #include "scpi/units.h" #include "scpi/utils.h" #include "scpi/expression.h" +#include "scpi/help.h" #endif /* SCPI_H */ diff --git a/libscpi/src/help.c b/libscpi/src/help.c new file mode 100644 index 00000000..95149cdf --- /dev/null +++ b/libscpi/src/help.c @@ -0,0 +1,83 @@ +/*- + * BSD 2-Clause License + * + * Copyright (c) 2023, Helge Wurst + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + /** + * @file help.c + * @date Tue Jan 17 16:27:00 UTC 2023 + * + * @brief HELP? [""] command handler + * + * + */ + +#include "scpi/parser.h" +#include "scpi/help.h" +#include "scpi/constants.h" +#include "scpi/error.h" +#include "scpi/ieee488.h" +#include "utils_private.h" + +/** + * HELP? [""] + * @param context + * @return + */ +scpi_result_t SCPI_HelpQ(scpi_t * context) { +#if USE_HELP_FILTER + size_t search_string_len = 0; + const char * search_string = NULL; + scpi_bool_t narrowed_down = SCPI_ParamCharacters(context, &search_string, &search_string_len, FALSE); +#endif + size_t i; + for(i = 0; context->cmdlist[i].pattern != NULL; i++) { + size_t pattern_len = strlen(context->cmdlist[i].pattern); +#if USE_HELP_FILTER + if(narrowed_down && (NULL == strncasestrn(context->cmdlist[i].pattern, pattern_len, search_string, search_string_len))){ + continue; + } +#endif + size_t block_len = 1 + pattern_len + strlen(SCPI_LINE_ENDING); +#if USE_COMMAND_DESCRIPTIONS + size_t description_len = context->cmdlist[i].description ? strlen(context->cmdlist[i].description) : 0; + if(description_len > 0){ + block_len = 1 + pattern_len + 1 + description_len + strlen(SCPI_LINE_ENDING); + } +#endif + SCPI_ResultArbitraryBlockHeader(context, block_len); + SCPI_ResultArbitraryBlockData(context, "\t", 1); + SCPI_ResultArbitraryBlockData(context, context->cmdlist[i].pattern, pattern_len); +#if USE_COMMAND_DESCRIPTIONS + if(description_len > 0){ + SCPI_ResultArbitraryBlockData(context, " ", 1); + SCPI_ResultArbitraryBlockData(context, context->cmdlist[i].description, description_len); + } +#endif + SCPI_ResultArbitraryBlockData(context, SCPI_LINE_ENDING, strlen(SCPI_LINE_ENDING)); + } + return SCPI_RES_OK; +} From 31a3e44bb7f18dbbb52a3b154aa2254fef370894 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 17 Jan 2023 17:52:08 +0100 Subject: [PATCH 18/22] add help.c, help.h to Makefile --- libscpi/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libscpi/Makefile b/libscpi/Makefile index d788a9e3..3ab5fa9d 100644 --- a/libscpi/Makefile +++ b/libscpi/Makefile @@ -28,7 +28,7 @@ SHAREDLIBVER = $(SHAREDLIB).$(VERSION) SRCS = $(addprefix src/, \ error.c fifo.c ieee488.c \ - minimal.c parser.c units.c utils.c \ + minimal.c help.c parser.c units.c utils.c \ lexer.c expression.c \ ) @@ -37,7 +37,7 @@ OBJS_SHARED = $(addprefix $(OBJDIR_SHARED)/, $(notdir $(SRCS:.c=.o))) HDRS = $(addprefix inc/scpi/, \ scpi.h constants.h error.h \ - ieee488.h minimal.h parser.h types.h units.h \ + ieee488.h minimal.h help.h parser.h types.h units.h \ expression.h \ ) \ $(addprefix src/, \ From d8a5d2460ad50cf30796d07342384d208400b387 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 17 Jan 2023 17:56:24 +0100 Subject: [PATCH 19/22] redo delete SCPI_HelpQ --- libscpi/src/minimal.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/libscpi/src/minimal.c b/libscpi/src/minimal.c index a14f8aeb..29dff824 100644 --- a/libscpi/src/minimal.c +++ b/libscpi/src/minimal.c @@ -213,43 +213,3 @@ scpi_result_t SCPI_StatusPreset(scpi_t * context) { SCPI_RegSet(context, SCPI_REG_QUES, 0); return SCPI_RES_OK; } - -/** - * HELP? [] - * @param context - * @return - */ -scpi_result_t SCPI_HelpQ(scpi_t * context) { -#if USE_HELP_FILTER - size_t search_string_len = 0; - const char * search_string = NULL; - scpi_bool_t narrowed_down = SCPI_ParamCharacters(context, &search_string, &search_string_len, FALSE); -#endif - size_t i; - for(i = 0; context->cmdlist[i].pattern != NULL; i++) { - size_t pattern_len = strlen(context->cmdlist[i].pattern); -#if USE_HELP_FILTER - if(narrowed_down && (NULL == strncasestrn(context->cmdlist[i].pattern, pattern_len, search_string, search_string_len))){ - continue; - } -#endif - size_t block_len = 1 + pattern_len + strlen(SCPI_LINE_ENDING); -#if USE_COMMAND_DESCRIPTIONS - size_t description_len = context->cmdlist[i].description ? strlen(context->cmdlist[i].description) : 0; - if(description_len > 0){ - block_len = 1 + pattern_len + 1 + description_len + strlen(SCPI_LINE_ENDING); - } -#endif - SCPI_ResultArbitraryBlockHeader(context, block_len); - SCPI_ResultArbitraryBlockData(context, "\t", 1); - SCPI_ResultArbitraryBlockData(context, context->cmdlist[i].pattern, pattern_len); -#if USE_COMMAND_DESCRIPTIONS - if(description_len > 0){ - SCPI_ResultArbitraryBlockData(context, " ", 1); - SCPI_ResultArbitraryBlockData(context, context->cmdlist[i].description, description_len); - } -#endif - SCPI_ResultArbitraryBlockData(context, SCPI_LINE_ENDING, strlen(SCPI_LINE_ENDING)); - } - return SCPI_RES_OK; -} From 63f5e88d2e8d7759a0bb3f73ba59a57e428136d8 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 17 Jan 2023 18:10:10 +0100 Subject: [PATCH 20/22] Revert "propagate MODE to Makefile for cross-compiling" This reverts commit c394eb954fe1ede45c9372e795b4705f9c7e25c9. --- libscpi/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libscpi/Makefile b/libscpi/Makefile index 3ab5fa9d..04c27f34 100644 --- a/libscpi/Makefile +++ b/libscpi/Makefile @@ -1,9 +1,9 @@ VERSION = 2.1.0 LIBNAME = scpi -CFLAGS += $(MODE) -Wextra -Wmissing-prototypes -Wimplicit -Iinc +CFLAGS += -Wextra -Wmissing-prototypes -Wimplicit -Iinc CFLAGS_SHARED += $(CFLAGS) -fPIC -LDFLAGS += $(MODE) -lm -Wl,--as-needed +LDFLAGS += -lm -Wl,--as-needed #TESTCFLAGS += $(CFLAGS) `pkg-config --cflags cunit` #TESTLDFLAGS += $(LDFLAGS) `pkg-config --libs cunit` TESTCFLAGS += $(CFLAGS) From d803ffeaf4cc050262b3a8ef02866dba77ced840 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 17 Jan 2023 18:19:34 +0100 Subject: [PATCH 21/22] simply SCPI_CMD_LIST_END definition --- libscpi/inc/scpi/types.h | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/libscpi/inc/scpi/types.h b/libscpi/inc/scpi/types.h index 550532dc..59855e49 100644 --- a/libscpi/inc/scpi/types.h +++ b/libscpi/inc/scpi/types.h @@ -170,17 +170,22 @@ extern "C" { typedef enum _scpi_result_t scpi_result_t; typedef struct _scpi_command_t scpi_command_t; - -#if USE_COMMAND_DESCRIPTIONS && USE_COMMAND_TAGS -#define SCPI_CMD_LIST_END {NULL, NULL, NULL, 0} -#elif USE_COMMAND_DESCRIPTIONS -#define SCPI_CMD_LIST_END {NULL, NULL, NULL} -#elif USE_COMMAND_TAGS -#define SCPI_CMD_LIST_END {NULL, NULL, 0} + +/* Helper macros for _scpi_command_t items. Usage: + _scpi_command_t cmd = {.pattern=":SOME:PATTern", .callback=SCPI_StubQ, SCPI_CMD_DESC("\t - a command") SCPI_CMD_TAG(0)}; +*/ +#if USE_COMMAND_DESCRIPTIONS +#define SCPI_CMD_DESC(S) (S), #else -#define SCPI_CMD_LIST_END {NULL, NULL} +#define SCPI_CMD_DESC(S) +#endif +#if USE_COMMAND_TAGS +#define SCPI_CMD_TAG(T) (T), +#else +#define SCPI_CMD_TAG(T) #endif +#define SCPI_CMD_LIST_END {NULL, NULL SCPI_CMD_DESC(NULL) SCPI_CMD_TAG(0)} /* scpi interface */ typedef struct _scpi_t scpi_t; @@ -420,20 +425,6 @@ extern "C" { #endif /* USE_COMMAND_TAGS */ }; -/* Helper macros for _scpi_command_t items. Usage: - _scpi_command_t cmd = {.pattern=":SOME:PATTern", .callback=SCPI_StubQ, SCPI_CMD_DESC("\t - a command") SCPI_CMD_TAG(0)}; -*/ -#if USE_COMMAND_DESCRIPTIONS -#define SCPI_CMD_DESC(S) (S), -#else -#define SCPI_CMD_DESC(S) -#endif -#if USE_COMMAND_TAGS -#define SCPI_CMD_TAG(T) (T), -#else -#define SCPI_CMD_TAG(T) -#endif - struct _scpi_interface_t { scpi_error_callback_t error; scpi_write_t write; From a44b9aa12ee7f8b94f580cf32e4870a79bff95d2 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 17 Jan 2023 18:23:46 +0100 Subject: [PATCH 22/22] add missing , --- libscpi/inc/scpi/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libscpi/inc/scpi/types.h b/libscpi/inc/scpi/types.h index 59855e49..b012f718 100644 --- a/libscpi/inc/scpi/types.h +++ b/libscpi/inc/scpi/types.h @@ -185,7 +185,7 @@ extern "C" { #define SCPI_CMD_TAG(T) #endif -#define SCPI_CMD_LIST_END {NULL, NULL SCPI_CMD_DESC(NULL) SCPI_CMD_TAG(0)} +#define SCPI_CMD_LIST_END {NULL, NULL, SCPI_CMD_DESC(NULL) SCPI_CMD_TAG(0)} /* scpi interface */ typedef struct _scpi_t scpi_t;