diff --git a/Makefile b/Makefile index bd94ee5..456c007 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ all: main.c scpi_parser.c scpi_parser.h - gcc main.c scpi_parser.c -o main.elf + gcc main.c scpi_parser.c scpi_errors.c -o main.elf run: all ./main.elf diff --git a/errorgen.php b/errorgen.php new file mode 100644 index 0000000..2dfad74 --- /dev/null +++ b/errorgen.php @@ -0,0 +1,182 @@ + 'CMD', + -200 => 'EXE', + -300 => 'DEV', +]; + +foreach($lines as $a) +{ + $a = trim($a); + if($a == '') continue; + + list($num, $name) = explode("\t", $a); + + $pfx = ''; $ii=($num - $num%100); + if (isset($prefixes[$ii]) && $num%100!=0) { + $pfx = $prefixes[$ii].'_'; + } + + $enum = str_replace(' ', '_', strtoupper($name)); + $enum = 'E_' . $pfx . preg_replace("/[^A-Z0-9_]/", "_", $enum); + + //echo "\t$enum = $num,\n"; + + echo "\t{"."$num, \"$name\"},\n"; +} diff --git a/main.c b/main.c index 76ee213..bb723fc 100644 --- a/main.c +++ b/main.c @@ -2,6 +2,7 @@ #include #include #include "scpi_parser.h" +#include "scpi_errors.h" @@ -124,4 +125,9 @@ int main() for (int i = 0; i < strlen(inp); i++) { scpi_handle_byte(inp[i]); } + + char buf[250]; + scpi_error_string(buf, E_EXE_DATA_QUESTIONABLE, "The data smells fishy"); + + printf("%s\n", buf); } diff --git a/scpi.pro b/scpi.pro index 7bdb150..b99da06 100644 --- a/scpi.pro +++ b/scpi.pro @@ -5,7 +5,8 @@ CONFIG -= qt SOURCES += \ scpi_parser.c \ - main.c + main.c \ + scpi_errors.c DISTFILES += \ style.astylerc \ @@ -15,4 +16,5 @@ DISTFILES += \ Makefile HEADERS += \ - scpi_parser.h + scpi_parser.h \ + scpi_errors.h diff --git a/scpi.pro.user b/scpi.pro.user index 35cb7cc..af18b34 100644 --- a/scpi.pro.user +++ b/scpi.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/scpi_errors.c b/scpi_errors.c new file mode 100644 index 0000000..973a845 --- /dev/null +++ b/scpi_errors.c @@ -0,0 +1,187 @@ +#include +#include +#include +#include +#include + +#include "scpi_errors.h" + +typedef struct { + const int16_t errno; + const char *msg; +} SCPI_error_desc; + +static const SCPI_error_desc error_table[] = { + { -100, "Command error"}, + { -101, "Invalid character"}, + { -102, "Syntax error"}, + { -103, "Invalid separator"}, + { -104, "Data type error"}, + { -105, "GET not allowed"}, + { -108, "Parameter not allowed"}, + { -109, "Missing parameter"}, + { -110, "Command header error"}, + { -111, "Header separator error"}, + { -112, "Program mnemonic too long"}, + { -113, "Undefined header"}, + { -114, "Header suffix out of range"}, + { -115, "Unexpected number of parameters"}, + { -120, "Numeric data error"}, + { -121, "Invalid character in number"}, + { -123, "Exponent too large"}, + { -124, "Too many digits"}, + { -128, "Numeric data not allowed"}, + { -130, "Suffix error"}, + { -131, "Invalid suffix"}, + { -134, "Suffix too long"}, + { -138, "Suffix not allowed"}, + { -140, "Character data error"}, + { -141, "Invalid character data"}, + { -144, "Character data too long"}, + { -148, "Character data not allowed"}, + { -150, "String data error"}, + { -151, "Invalid string data"}, + { -158, "String data not allowed"}, + { -160, "Block data error"}, + { -161, "Invalid block data"}, + { -168, "Block data not allowed"}, + { -170, "Expression error"}, + { -171, "Invalid expression"}, + { -178, "Expression data not allowed"}, + { -180, "Macro error"}, + { -181, "Invalid outside macro definition"}, + { -183, "Invalid inside macro definition"}, + { -184, "Macro parameter error"}, + { -200, "Execution error"}, + { -201, "Invalid while in local"}, + { -202, "Settings lost due to rtl"}, + { -203, "Command protected"}, + { -210, "Trigger error"}, + { -211, "Trigger ignored"}, + { -212, "Arm ignored"}, + { -213, "Init ignored"}, + { -214, "Trigger deadlock"}, + { -215, "Arm deadlock"}, + { -220, "Parameter error"}, + { -221, "Settings conflict"}, + { -222, "Data out of range"}, + { -223, "Too much data"}, + { -224, "Illegal parameter value"}, + { -225, "Out of memory"}, + { -226, "Lists not same length"}, + { -230, "Data corrupt or stale"}, + { -231, "Data questionable"}, + { -232, "Invalid format"}, + { -233, "Invalid version"}, + { -240, "Hardware error"}, + { -241, "Hardware missing"}, + { -250, "Mass storage error"}, + { -251, "Missing mass storage"}, + { -252, "Missing media"}, + { -253, "Corrupt media"}, + { -254, "Media full"}, + { -255, "Directory full"}, + { -256, "File name not found"}, + { -257, "File name error"}, + { -258, "Media protected"}, + { -260, "Expression error"}, + { -261, "Math error in expression"}, + { -270, "Macro error"}, + { -271, "Macro syntax error"}, + { -272, "Macro execution error"}, + { -273, "Illegal macro label"}, + { -274, "Macro parameter error"}, + { -275, "Macro definition too long"}, + { -276, "Macro recursion error"}, + { -277, "Macro redefinition not allowed"}, + { -278, "Macro header not found"}, + { -280, "Program error"}, + { -281, "Cannot create program"}, + { -282, "Illegal program name"}, + { -283, "Illegal variable name"}, + { -284, "Program currently running"}, + { -285, "Program syntax error"}, + { -286, "Program runtime error"}, + { -290, "Memory use error"}, + { -291, "Out of memory"}, + { -292, "Referenced name does not exist"}, + { -293, "Referenced name already exists"}, + { -294, "Incompatible type"}, + { -300, "Device-specific error"}, + { -310, "System error"}, + { -311, "Memory error"}, + { -312, "PUD memory lost"}, + { -313, "Calibration memory lost"}, + { -314, "Save/recall memory lost"}, + { -315, "Configuration memory lost"}, + { -320, "Storage fault"}, + { -321, "Out of memory"}, + { -330, "Self-test failed"}, + { -340, "Calibration failed"}, + { -350, "Queue overflow"}, + { -360, "Communication error"}, + { -361, "Parity error in program message"}, + { -362, "Framing error in program message"}, + { -363, "Input buffer overrun"}, + { -365, "Time out error"}, + { -400, "Query error"}, + { -410, "Query INTERRUPTED"}, + { -420, "Query UNTERMINATED"}, + { -430, "Query DEADLOCKED"}, + { -440, "Query UNTERMINATED after indefinite response"}, + { -500, "Power on"}, + { -600, "User request"}, + { -700, "Request control"}, + { -800, "Operation complete"}, + {0} +}; + + +const char * scpi_error_message(SCPI_error_t errno) +{ + for (int i = 0; error_table[i].errno != 0; i++) { + if (error_table[i].errno == errno) { + return error_table[i].msg; + } + } + + return NULL; +} + + +void scpi_error_string(char *buffer, SCPI_error_t errno, const char *extra) +{ + const char *msg = scpi_error_message(errno); + + // len - total length, offs - current segment length + int len, offs; + + len = offs = sprintf(buffer, "%d,\"", errno); // ," + buffer += offs; + + if (msg == NULL) { + msg = "Unknown error"; + } + + offs = sprintf(buffer, "%s", msg); // Error message + len += offs; + buffer += offs; + + if (extra != NULL) { + // extra info + offs = sprintf(buffer, "; "); // ;_ + len += offs; + buffer += offs; + + // copy in the extra string + int ll = 250 - len - 2; + int xlen = strlen(extra); + if (ll > xlen) ll = xlen; + strncpy(buffer, extra, ll); // Extra msg + + len += ll; + buffer += ll; + } + + sprintf(buffer, "\""); // " +} diff --git a/scpi_errors.h b/scpi_errors.h new file mode 100644 index 0000000..1b86abe --- /dev/null +++ b/scpi_errors.h @@ -0,0 +1,140 @@ +#pragma once +#include +#include + +// SCPI error constants +typedef enum { + E_COMMAND_ERROR = -100, + E_CMD_INVALID_CHARACTER = -101, + E_CMD_SYNTAX_ERROR = -102, + E_CMD_INVALID_SEPARATOR = -103, + E_CMD_DATA_TYPE_ERROR = -104, + E_CMD_GET_NOT_ALLOWED = -105, + E_CMD_PARAMETER_NOT_ALLOWED = -108, + E_CMD_MISSING_PARAMETER = -109, + E_CMD_COMMAND_HEADER_ERROR = -110, + E_CMD_HEADER_SEPARATOR_ERROR = -111, + E_CMD_PROGRAM_MNEMONIC_TOO_LONG = -112, + E_CMD_UNDEFINED_HEADER = -113, + E_CMD_HEADER_SUFFIX_OUT_OF_RANGE = -114, + E_CMD_UNEXPECTED_NUMBER_OF_PARAMETERS = -115, + E_CMD_NUMERIC_DATA_ERROR = -120, + E_CMD_INVALID_CHARACTER_IN_NUMBER = -121, + E_CMD_EXPONENT_TOO_LARGE = -123, + E_CMD_TOO_MANY_DIGITS = -124, + E_CMD_NUMERIC_DATA_NOT_ALLOWED = -128, + E_CMD_SUFFIX_ERROR = -130, + E_CMD_INVALID_SUFFIX = -131, + E_CMD_SUFFIX_TOO_LONG = -134, + E_CMD_SUFFIX_NOT_ALLOWED = -138, + E_CMD_CHARACTER_DATA_ERROR = -140, + E_CMD_INVALID_CHARACTER_DATA = -141, + E_CMD_CHARACTER_DATA_TOO_LONG = -144, + E_CMD_CHARACTER_DATA_NOT_ALLOWED = -148, + E_CMD_STRING_DATA_ERROR = -150, + E_CMD_INVALID_STRING_DATA = -151, + E_CMD_STRING_DATA_NOT_ALLOWED = -158, + E_CMD_BLOCK_DATA_ERROR = -160, + E_CMD_INVALID_BLOCK_DATA = -161, + E_CMD_BLOCK_DATA_NOT_ALLOWED = -168, + E_CMD_EXPRESSION_ERROR = -170, + E_CMD_INVALID_EXPRESSION = -171, + E_CMD_EXPRESSION_DATA_NOT_ALLOWED = -178, + E_CMD_MACRO_ERROR = -180, + E_CMD_INVALID_OUTSIDE_MACRO_DEFINITION = -181, + E_CMD_INVALID_INSIDE_MACRO_DEFINITION = -183, + E_CMD_MACRO_PARAMETER_ERROR = -184, + E_EXECUTION_ERROR = -200, + E_EXE_INVALID_WHILE_IN_LOCAL = -201, + E_EXE_SETTINGS_LOST_DUE_TO_RTL = -202, + E_EXE_COMMAND_PROTECTED = -203, + E_EXE_TRIGGER_ERROR = -210, + E_EXE_TRIGGER_IGNORED = -211, + E_EXE_ARM_IGNORED = -212, + E_EXE_INIT_IGNORED = -213, + E_EXE_TRIGGER_DEADLOCK = -214, + E_EXE_ARM_DEADLOCK = -215, + E_EXE_PARAMETER_ERROR = -220, + E_EXE_SETTINGS_CONFLICT = -221, + E_EXE_DATA_OUT_OF_RANGE = -222, + E_EXE_TOO_MUCH_DATA = -223, + E_EXE_ILLEGAL_PARAMETER_VALUE = -224, + E_EXE_OUT_OF_MEMORY = -225, + E_EXE_LISTS_NOT_SAME_LENGTH = -226, + E_EXE_DATA_CORRUPT_OR_STALE = -230, + E_EXE_DATA_QUESTIONABLE = -231, + E_EXE_INVALID_FORMAT = -232, + E_EXE_INVALID_VERSION = -233, + E_EXE_HARDWARE_ERROR = -240, + E_EXE_HARDWARE_MISSING = -241, + E_EXE_MASS_STORAGE_ERROR = -250, + E_EXE_MISSING_MASS_STORAGE = -251, + E_EXE_MISSING_MEDIA = -252, + E_EXE_CORRUPT_MEDIA = -253, + E_EXE_MEDIA_FULL = -254, + E_EXE_DIRECTORY_FULL = -255, + E_EXE_FILE_NAME_NOT_FOUND = -256, + E_EXE_FILE_NAME_ERROR = -257, + E_EXE_MEDIA_PROTECTED = -258, + E_EXE_EXPRESSION_ERROR = -260, + E_EXE_MATH_ERROR_IN_EXPRESSION = -261, + E_EXE_MACRO_ERROR = -270, + E_EXE_MACRO_SYNTAX_ERROR = -271, + E_EXE_MACRO_EXECUTION_ERROR = -272, + E_EXE_ILLEGAL_MACRO_LABEL = -273, + E_EXE_MACRO_PARAMETER_ERROR = -274, + E_EXE_MACRO_DEFINITION_TOO_LONG = -275, + E_EXE_MACRO_RECURSION_ERROR = -276, + E_EXE_MACRO_REDEFINITION_NOT_ALLOWED = -277, + E_EXE_MACRO_HEADER_NOT_FOUND = -278, + E_EXE_PROGRAM_ERROR = -280, + E_EXE_CANNOT_CREATE_PROGRAM = -281, + E_EXE_ILLEGAL_PROGRAM_NAME = -282, + E_EXE_ILLEGAL_VARIABLE_NAME = -283, + E_EXE_PROGRAM_CURRENTLY_RUNNING = -284, + E_EXE_PROGRAM_SYNTAX_ERROR = -285, + E_EXE_PROGRAM_RUNTIME_ERROR = -286, + E_EXE_MEMORY_USE_ERROR = -290, + E_EXE_OUT_OF_MEMORY_291 = -291, + E_EXE_REFERENCED_NAME_DOES_NOT_EXIST = -292, + E_EXE_REFERENCED_NAME_ALREADY_EXISTS = -293, + E_EXE_INCOMPATIBLE_TYPE = -294, + E_DEVICE_SPECIFIC_ERROR = -300, + E_DEV_SYSTEM_ERROR = -310, + E_DEV_MEMORY_ERROR = -311, + E_DEV_PUD_MEMORY_LOST = -312, + E_DEV_CALIBRATION_MEMORY_LOST = -313, + E_DEV_SAVE_RECALL_MEMORY_LOST = -314, + E_DEV_CONFIGURATION_MEMORY_LOST = -315, + E_DEV_STORAGE_FAULT = -320, + E_DEV_OUT_OF_MEMORY = -321, + E_DEV_SELF_TEST_FAILED = -330, + E_DEV_CALIBRATION_FAILED = -340, + E_DEV_QUEUE_OVERFLOW = -350, + E_DEV_COMMUNICATION_ERROR = -360, + E_DEV_PARITY_ERROR_IN_PROGRAM_MESSAGE = -361, + E_DEV_FRAMING_ERROR_IN_PROGRAM_MESSAGE = -362, + E_DEV_INPUT_BUFFER_OVERRUN = -363, + E_DEV_TIME_OUT_ERROR = -365, + E_QUERY_ERROR = -400, + E_QUERY_INTERRUPTED = -410, + E_QUERY_UNTERMINATED = -420, + E_QUERY_DEADLOCKED = -430, + E_QUERY_UNTERMINATED_AFTER_INDEFINITE_RESPONSE = -440, + E_POWER_ON = -500, + E_USER_REQUEST = -600, + E_REQUEST_CONTROL = -700, + E_OPERATION_COMPLETE = -800, +} SCPI_error_t; + + +/** Get SCPI error message (alone) */ +const char *scpi_error_message(SCPI_error_t errno); + +/** + * Get SCPI error string for reporting: + * ,"[; ]" + * + * extra can be NULL to skip the optional part. + */ +void scpi_error_string(char *buffer, SCPI_error_t errno, const char *extra);