New file |
| | |
| | | /*- |
| | | * Copyright (c) 2012-2013 Jan Breuer, |
| | | * |
| | | * All Rights Reserved |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are |
| | | * met: |
| | | * 1. Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * 2. 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 AUTHORS ``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 AUTHORS 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 config.h |
| | | * @date Wed Mar 20 12:21:26 UTC 2013 |
| | | * |
| | | * @brief SCPI Configuration |
| | | * |
| | | * |
| | | */ |
| | | |
| | | #ifndef __SCPI_CONFIG_H_ |
| | | #define __SCPI_CONFIG_H_ |
| | | |
| | | #ifdef __cplusplus |
| | | extern "C" { |
| | | #endif |
| | | |
| | | /* ======== test strnlen ======== */ |
| | | #ifndef HAVE_STRNLEN |
| | | #define HAVE_STRNLEN 1 |
| | | #endif |
| | | /* ======== test strncasecmp ======== */ |
| | | #ifndef HAVE_STRNCASECMP |
| | | #define HAVE_STRNCASECMP 1 |
| | | #endif |
| | | |
| | | /* define local macros depending on existance of strnlen */ |
| | | #if HAVE_STRNLEN |
| | | #define SCPI_strnlen(s, l) strnlen((s), (l)) |
| | | #else |
| | | #define SCPI_strnlen(s, l) BSD_strnlen((s), (l)) |
| | | #endif |
| | | |
| | | /* define local macros depending on existance of strncasecmp */ |
| | | #if HAVE_STRNCASECMP |
| | | #define SCPI_strncasecmp(s1, s2, l) strncasecmp((s1), (s2), (l)) |
| | | #else |
| | | #define SCPI_strncasecmp(s1, s2, l) strcasecmp((s1), (s2)) |
| | | #endif |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | | #endif |
| | | |
| | | #endif |
| | |
| | | #endif |
| | | |
| | | |
| | | //#define SCPI_DEBUG_COMMAND(a) scpi_debug_command(a) |
| | | #define SCPI_DEBUG_COMMAND(a) |
| | | /* #define SCPI_DEBUG_COMMAND(a) scpi_debug_command(a) */ |
| | | #define SCPI_DEBUG_COMMAND(a) |
| | | |
| | | |
| | | bool_t SCPI_DebugCommand(scpi_t * context); |
| | |
| | | #define SCPI_ERROR_INVALID_SUFFIX -131 |
| | | #define SCPI_ERROR_SUFFIX_NOT_ALLOWED -138 |
| | | |
| | | #define SCPI_ERROR_EXECUTION_ERROR -200 |
| | | #define SCPI_ERROR_EXECUTION_ERROR -200 |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | |
| | | scpi_result_t SCPI_CoreWai(scpi_t * context); |
| | | |
| | | |
| | | #define STB_R01 0x01 // Not used |
| | | #define STB_PRO 0x02 // Protection Event Flag |
| | | #define STB_QMA 0x04 // Error/Event queue message available |
| | | #define STB_QES 0x08 // Questionable status |
| | | #define STB_MAV 0x10 // Message Available |
| | | #define STB_ESR 0x20 // Standard Event Status Register |
| | | #define STB_SRQ 0x40 // Service Request |
| | | #define STB_OPS 0x80 // Operation Status Flag |
| | | #define STB_R01 0x01 /* Not used */ |
| | | #define STB_PRO 0x02 /* Protection Event Flag */ |
| | | #define STB_QMA 0x04 /* Error/Event queue message available */ |
| | | #define STB_QES 0x08 /* Questionable status */ |
| | | #define STB_MAV 0x10 /* Message Available */ |
| | | #define STB_ESR 0x20 /* Standard Event Status Register */ |
| | | #define STB_SRQ 0x40 /* Service Request */ |
| | | #define STB_OPS 0x80 /* Operation Status Flag */ |
| | | |
| | | |
| | | #define ESR_OPC 0x01 // Operation complete |
| | | #define ESR_REQ 0x02 // Request Control |
| | | #define ESR_QER 0x04 // Query Error |
| | | #define ESR_DER 0x08 // Device Dependent Error |
| | | #define ESR_EER 0x10 // Execution Error (e.g. range error) |
| | | #define ESR_CER 0x20 // Command error (e.g. syntax error) |
| | | #define ESR_URQ 0x40 // User Request |
| | | #define ESR_PON 0x80 // Power On |
| | | #define ESR_OPC 0x01 /* Operation complete */ |
| | | #define ESR_REQ 0x02 /* Request Control */ |
| | | #define ESR_QER 0x04 /* Query Error */ |
| | | #define ESR_DER 0x08 /* Device Dependent Error */ |
| | | #define ESR_EER 0x10 /* Execution Error (e.g. range error) */ |
| | | #define ESR_CER 0x20 /* Command error (e.g. syntax error) */ |
| | | #define ESR_URQ 0x40 /* User Request */ |
| | | #define ESR_PON 0x80 /* Power On */ |
| | | |
| | | |
| | | scpi_reg_val_t SCPI_RegGet(scpi_t * context, scpi_reg_name_t name); |
| | |
| | | |
| | | /* basic data types */ |
| | | typedef bool bool_t; |
| | | //typedef enum { FALSE = 0, TRUE } bool_t; |
| | | /* typedef enum { FALSE = 0, TRUE } bool_t; */ |
| | | |
| | | /* IEEE 488.2 registers */ |
| | | enum _scpi_reg_name_t { |
| | | SCPI_REG_STB = 0, // Status Byte |
| | | SCPI_REG_SRE, // Service Request Enable Register |
| | | SCPI_REG_ESR, // Standard Event Status Register (ESR, SESR) |
| | | SCPI_REG_ESE, // Event Status Enable Register |
| | | SCPI_REG_OPER, // OPERation Status Register |
| | | SCPI_REG_OPERE, // OPERation Status Enable Register |
| | | SCPI_REG_QUES, // QUEStionable status register |
| | | SCPI_REG_QUESE, // QUEStionable status Enable Register |
| | | SCPI_REG_STB = 0, /* Status Byte */ |
| | | SCPI_REG_SRE, /* Service Request Enable Register */ |
| | | SCPI_REG_ESR, /* Standard Event Status Register (ESR, SESR) */ |
| | | SCPI_REG_ESE, /* Event Status Enable Register */ |
| | | SCPI_REG_OPER, /* OPERation Status Register */ |
| | | SCPI_REG_OPERE, /* OPERation Status Enable Register */ |
| | | SCPI_REG_QUES, /* QUEStionable status register */ |
| | | SCPI_REG_QUESE, /* QUEStionable status Enable Register */ |
| | | |
| | | /* last definition - number of registers */ |
| | | SCPI_REG_COUNT, |
| | | SCPI_REG_COUNT |
| | | }; |
| | | typedef enum _scpi_reg_name_t scpi_reg_name_t; |
| | | |
| | | enum _scpi_ctrl_name_t { |
| | | SCPI_CTRL_SRQ = 1, // service request |
| | | SCPI_CTRL_GTL, // Go to local |
| | | SCPI_CTRL_SDC, // Selected device clear |
| | | SCPI_CTRL_PPC, // Parallel poll configure |
| | | SCPI_CTRL_GET, // Group execute trigger |
| | | SCPI_CTRL_TCT, // Take control |
| | | SCPI_CTRL_LLO, // Device clear |
| | | SCPI_CTRL_DCL, // Local lockout |
| | | SCPI_CTRL_PPU, // Parallel poll unconfigure |
| | | SCPI_CTRL_SPE, // Serial poll enable |
| | | SCPI_CTRL_SPD, // Serial poll disable |
| | | SCPI_CTRL_MLA, // My local address |
| | | SCPI_CTRL_UNL, // Unlisten |
| | | SCPI_CTRL_MTA, // My talk address |
| | | SCPI_CTRL_UNT, // Untalk |
| | | SCPI_CTRL_MSA, // My secondary address |
| | | SCPI_CTRL_SRQ = 1, /* service request */ |
| | | SCPI_CTRL_GTL, /* Go to local */ |
| | | SCPI_CTRL_SDC, /* Selected device clear */ |
| | | SCPI_CTRL_PPC, /* Parallel poll configure */ |
| | | SCPI_CTRL_GET, /* Group execute trigger */ |
| | | SCPI_CTRL_TCT, /* Take control */ |
| | | SCPI_CTRL_LLO, /* Device clear */ |
| | | SCPI_CTRL_DCL, /* Local lockout */ |
| | | SCPI_CTRL_PPU, /* Parallel poll unconfigure */ |
| | | SCPI_CTRL_SPE, /* Serial poll enable */ |
| | | SCPI_CTRL_SPD, /* Serial poll disable */ |
| | | SCPI_CTRL_MLA, /* My local address */ |
| | | SCPI_CTRL_UNL, /* Unlisten */ |
| | | SCPI_CTRL_MTA, /* My talk address */ |
| | | SCPI_CTRL_UNT, /* Untalk */ |
| | | SCPI_CTRL_MSA /* My secondary address */ |
| | | }; |
| | | typedef enum _scpi_ctrl_name_t scpi_ctrl_name_t; |
| | | |
| | |
| | | /* scpi commands */ |
| | | enum _scpi_result_t { |
| | | SCPI_RES_OK = 1, |
| | | SCPI_RES_ERR = -1, |
| | | SCPI_RES_ERR = -1 |
| | | }; |
| | | typedef enum _scpi_result_t scpi_result_t; |
| | | |
| | |
| | | SCPI_UNIT_OHM, |
| | | SCPI_UNIT_HERTZ, |
| | | SCPI_UNIT_CELSIUS, |
| | | SCPI_UNIT_SECONDS, |
| | | SCPI_UNIT_SECONDS |
| | | }; |
| | | typedef enum _scpi_unit_t scpi_unit_t; |
| | | |
| | |
| | | SCPI_NUM_DOWN, |
| | | SCPI_NUM_NAN, |
| | | SCPI_NUM_INF, |
| | | SCPI_NUM_NINF, |
| | | SCPI_NUM_NINF |
| | | }; |
| | | typedef enum _scpi_special_number_t scpi_special_number_t; |
| | | |
| | |
| | | #include "scpi/error.h" |
| | | #include "scpi/fifo.h" |
| | | |
| | | // basic FIFO |
| | | /* basic FIFO */ |
| | | static fifo_t local_error_queue; |
| | | |
| | | |
| | | |
| | | void SCPI_ErrorInit(scpi_t * context) { |
| | | //// FreeRTOS |
| | | // context->error_queue = (scpi_error_queue_t)xQueueCreate(100, sizeof(int16_t)); |
| | | |
| | | // basic FIFO |
| | | /* |
| | | * // FreeRTOS |
| | | * context->error_queue = (scpi_error_queue_t)xQueueCreate(100, sizeof(int16_t)); |
| | | */ |
| | | |
| | | /* basic FIFO */ |
| | | context->error_queue = (scpi_error_queue_t)&local_error_queue; |
| | | fifo_init((fifo_t *)context->error_queue); |
| | | } |
| | |
| | | * @param context - scpi context |
| | | */ |
| | | void SCPI_ErrorClear(scpi_t * context) { |
| | | //// FreeRTOS |
| | | //xQueueReset((xQueueHandle)context->error_queue); |
| | | |
| | | // basic FIFO |
| | | /* |
| | | * // FreeRTOS |
| | | * xQueueReset((xQueueHandle)context->error_queue); |
| | | */ |
| | | |
| | | /* basic FIFO */ |
| | | fifo_clear((fifo_t *)context->error_queue); |
| | | } |
| | | |
| | |
| | | */ |
| | | int16_t SCPI_ErrorPop(scpi_t * context) { |
| | | int16_t result = 0; |
| | | |
| | | //// FreeRTOS |
| | | //if (pdFALSE == xQueueReceive((xQueueHandle)context->error_queue, &result, 0)) { |
| | | // result = 0; |
| | | //} |
| | | |
| | | // basic FIFO |
| | | |
| | | /* |
| | | * // FreeRTOS |
| | | * if (pdFALSE == xQueueReceive((xQueueHandle)context->error_queue, &result, 0)) { |
| | | * result = 0; |
| | | * } |
| | | */ |
| | | |
| | | /* basic FIFO */ |
| | | fifo_remove((fifo_t *)context->error_queue, &result); |
| | | |
| | | return result; |
| | |
| | | */ |
| | | int32_t SCPI_ErrorCount(scpi_t * context) { |
| | | int16_t result = 0; |
| | | |
| | | //// FreeRTOS |
| | | //result = uxQueueMessagesWaiting((xQueueHandle)context->error_queue); |
| | | |
| | | //basic FIFO |
| | | |
| | | /* |
| | | * // FreeRTOS |
| | | * result = uxQueueMessagesWaiting((xQueueHandle)context->error_queue); |
| | | */ |
| | | |
| | | /* basic FIFO */ |
| | | fifo_count((fifo_t *)context->error_queue, &result); |
| | | |
| | | |
| | | |
| | | return result; |
| | | } |
| | | |
| | | static void SCPI_ErrorAddInternal(scpi_t * context, int16_t err) { |
| | | //// FreeRTOS |
| | | //xQueueSend((xQueueHandle)context->error_queue, &err, 0); |
| | | |
| | | // basic FIFO |
| | | /* |
| | | * // FreeRTOS |
| | | * xQueueSend((xQueueHandle)context->error_queue, &err, 0); |
| | | */ |
| | | |
| | | /* basic FIFO */ |
| | | fifo_add((fifo_t *)context->error_queue, err); |
| | | } |
| | | |
| | |
| | | #define ERROR_DEFS_N 8 |
| | | |
| | | static const struct error_reg errs[ERROR_DEFS_N] = { |
| | | {-100, -199, ESR_CER}, // Command error (e.g. syntax error) ch 21.8.9 |
| | | {-200, -299, ESR_EER}, // Execution Error (e.g. range error) ch 21.8.10 |
| | | {-300, -399, ESR_DER}, // Device specific error -300, -399 ch 21.8.11 |
| | | {-400, -499, ESR_QER}, // Query error -400, -499 ch 21.8.12 |
| | | {-500, -599, ESR_PON}, // Power on event -500, -599 ch 21.8.13 |
| | | {-600, -699, ESR_URQ}, // User Request Event -600, -699 ch 21.8.14 |
| | | {-700, -799, ESR_REQ}, // Request Control Event -700, -799 ch 21.8.15 |
| | | {-800, -899, ESR_OPC}, // Operation Complete Event -800, -899 ch 21.8.16 |
| | | {-100, -199, ESR_CER}, /* Command error (e.g. syntax error) ch 21.8.9 */ |
| | | {-200, -299, ESR_EER}, /* Execution Error (e.g. range error) ch 21.8.10 */ |
| | | {-300, -399, ESR_DER}, /* Device specific error -300, -399 ch 21.8.11 */ |
| | | {-400, -499, ESR_QER}, /* Query error -400, -499 ch 21.8.12 */ |
| | | {-500, -599, ESR_PON}, /* Power on event -500, -599 ch 21.8.13 */ |
| | | {-600, -699, ESR_URQ}, /* User Request Event -600, -699 ch 21.8.14 */ |
| | | {-700, -799, ESR_REQ}, /* Request Control Event -700, -799 ch 21.8.15 */ |
| | | {-800, -899, ESR_OPC}, /* Operation Complete Event -800, -899 ch 21.8.16 */ |
| | | }; |
| | | |
| | | /** |
| | |
| | | |
| | | |
| | | case SCPI_REG_COUNT: |
| | | // nothing to do |
| | | /* nothing to do */ |
| | | break; |
| | | } |
| | | |
| | | // set updated register value |
| | | /* set updated register value */ |
| | | context->registers[name] = val; |
| | | |
| | | if (srq) { |
| | |
| | | * @param context |
| | | */ |
| | | void SCPI_EventClear(scpi_t * context) { |
| | | // TODO |
| | | /* TODO */ |
| | | SCPI_RegSet(context, SCPI_REG_ESR, 0); |
| | | } |
| | | |
| | |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_CoreOpcQ(scpi_t * context) { |
| | | // Operation is always completed |
| | | /* Operation is always completed */ |
| | | SCPI_ResultInt(context, 1); |
| | | return SCPI_RES_OK; |
| | | } |
| | |
| | | int result = 0; |
| | | if (context && context->interface && context->interface->test) { |
| | | result = context->interface->test(context); |
| | | } |
| | | } |
| | | SCPI_ResultInt(context, result); |
| | | return SCPI_RES_OK; |
| | | } |
| | |
| | | */ |
| | | scpi_result_t SCPI_CoreWai(scpi_t * context) { |
| | | (void) context; |
| | | // NOP |
| | | /* NOP */ |
| | | return SCPI_RES_OK; |
| | | } |
| | | |
| | |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_StatusQuestionableEventQ(scpi_t * context) { |
| | | // return value |
| | | /* return value */ |
| | | SCPI_ResultInt(context, SCPI_RegGet(context, SCPI_REG_QUES)); |
| | | |
| | | // clear register |
| | | /* clear register */ |
| | | SCPI_RegSet(context, SCPI_REG_QUES, 0); |
| | | |
| | | return SCPI_RES_OK; |
| | |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_StatusQuestionableEnableQ(scpi_t * context) { |
| | | // return value |
| | | /* return value */ |
| | | SCPI_ResultInt(context, SCPI_RegGet(context, SCPI_REG_QUESE)); |
| | | |
| | | return SCPI_RES_OK; |
| | |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_StatusPreset(scpi_t * context) { |
| | | // clear STATUS:... |
| | | /* clear STATUS:... */ |
| | | SCPI_RegSet(context, SCPI_REG_QUES, 0); |
| | | return SCPI_RES_OK; |
| | | } |
| | |
| | | #include <ctype.h> |
| | | #include <string.h> |
| | | |
| | | #include "scpi/config.h" |
| | | #include "scpi/parser.h" |
| | | #include "utils.h" |
| | | #include "scpi/error.h" |
| | |
| | | int result = FALSE; |
| | | |
| | | const char * pattern_ptr = pattern; |
| | | int pattern_len = strlen(pattern); |
| | | int pattern_len = SCPI_strnlen(pattern, len); |
| | | const char * pattern_end = pattern + pattern_len; |
| | | |
| | | const char * cmd_ptr = cmd; |
| | | size_t cmd_len = strnlen(cmd, len); |
| | | size_t cmd_len = SCPI_strnlen(cmd, len); |
| | | const char * cmd_end = cmd + cmd_len; |
| | | |
| | | while (1) { |
| | |
| | | cmd_ptr = cmd_ptr + cmd_sep_pos; |
| | | result = TRUE; |
| | | |
| | | // command is complete |
| | | /* command is complete */ |
| | | if ((pattern_ptr == pattern_end) && (cmd_ptr >= cmd_end)) { |
| | | break; |
| | | } |
| | | |
| | | // pattern complete, but command not |
| | | /* pattern complete, but command not */ |
| | | if ((pattern_ptr == pattern_end) && (cmd_ptr < cmd_end)) { |
| | | result = FALSE; |
| | | break; |
| | | } |
| | | |
| | | // command complete, but pattern not |
| | | /* command complete, but pattern not */ |
| | | if (cmd_ptr >= cmd_end) { |
| | | result = FALSE; |
| | | break; |
| | | } |
| | | |
| | | // both command and patter contains command separator at this position |
| | | /* both command and patter contains command separator at this position */ |
| | | if ((pattern_ptr[0] == cmd_ptr[0]) && ((pattern_ptr[0] == ':') || (pattern_ptr[0] == '?'))) { |
| | | pattern_ptr = pattern_ptr + 1; |
| | | cmd_ptr = cmd_ptr + 1; |
| | |
| | | * @param len - lenght of data to be written |
| | | * @return number of bytes written |
| | | */ |
| | | static inline size_t writeData(scpi_t * context, const char * data, size_t len) { |
| | | static size_t writeData(scpi_t * context, const char * data, size_t len) { |
| | | return context->interface->write(context, data, len); |
| | | } |
| | | |
| | |
| | | * @param context |
| | | * @return |
| | | */ |
| | | static inline int flushData(scpi_t * context) { |
| | | static int flushData(scpi_t * context) { |
| | | if (context && context->interface && context->interface->flush) { |
| | | return context->interface->flush(context); |
| | | } else { |
| | |
| | | * @param context |
| | | * @return number of bytes written |
| | | */ |
| | | static inline size_t writeDelimiter(scpi_t * context) { |
| | | static size_t writeDelimiter(scpi_t * context) { |
| | | if (context->output_count > 0) { |
| | | return writeData(context, ", ", 2); |
| | | } else { |
| | |
| | | * @param context |
| | | * @return pocet zapsanych znaku |
| | | */ |
| | | static inline size_t writeNewLine(scpi_t * context) { |
| | | static size_t writeNewLine(scpi_t * context) { |
| | | if (context->output_count > 0) { |
| | | size_t len; |
| | | len = writeData(context, "\r\n", 2); |
| | |
| | | * @param context |
| | | */ |
| | | static void processCommand(scpi_t * context) { |
| | | const scpi_command_t * cmd = context->paramlist.cmd; |
| | | |
| | | context->cmd_error = FALSE; |
| | | context->output_count = 0; |
| | | context->input_count = 0; |
| | | |
| | | const scpi_command_t * cmd = context->paramlist.cmd; |
| | | |
| | | SCPI_DEBUG_COMMAND(context); |
| | | /* if callback exists - call command callback*/ |
| | | /* if callback exists - call command callback */ |
| | | if (cmd->callback != NULL) { |
| | | if ((cmd->callback(context) != SCPI_RES_OK) && !context->cmd_error) { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_EXECUTION_ERROR); |
| | |
| | | return FALSE; |
| | | } |
| | | |
| | | if (strncasecmp(str1, str2, len2) == 0) { |
| | | if (SCPI_strncasecmp(str1, str2, len2) == 0) { |
| | | return TRUE; |
| | | } |
| | | |
| | |
| | | STATE_TEXT, |
| | | STATE_LAST_WHITESPACE, |
| | | STATE_COMMA, |
| | | STATE_ERROR, |
| | | STATE_ERROR |
| | | }; |
| | | typedef enum _locate_text_states locate_text_states; |
| | | |
| | |
| | | /** |
| | | * Test locate text state, if it is correct final state |
| | | */ |
| | | static inline bool_t isFinalState(locate_text_states state) { |
| | | static bool_t isFinalState(locate_text_states state) { |
| | | return ( |
| | | ((state) == STATE_COMMA) |
| | | || ((state) == STATE_LAST_WHITESPACE) |
| | |
| | | * @param nfa stores automaton state |
| | | * @param c current char processed |
| | | */ |
| | | static inline bool_t locateTextAutomaton(locate_text_nfa * nfa, unsigned char c) { |
| | | static bool_t locateTextAutomaton(locate_text_nfa * nfa, unsigned char c) { |
| | | switch(nfa->state) { |
| | | /* first state locating only white spaces */ |
| | | case STATE_FIRST_WHITESPACE: |
| | |
| | | * @param nfa stores automaton state |
| | | * @param c current char processed |
| | | */ |
| | | static inline bool_t locateStrAutomaton(locate_text_nfa * nfa, unsigned char c) { |
| | | static bool_t locateStrAutomaton(locate_text_nfa * nfa, unsigned char c) { |
| | | switch(nfa->state) { |
| | | /* first state locating only white spaces */ |
| | | case STATE_FIRST_WHITESPACE: |
| | |
| | | return compareStr(pattern, pattern_len, str, str_len) || |
| | | compareStr(pattern, pattern_sep_pos_short, str, str_len); |
| | | } |
| | | |
| | | |
| | | #if !HAVE_STRNLEN |
| | | /* use FreeBSD strnlen */ |
| | | |
| | | /*- |
| | | * Copyright (c) 2009 David Schultz <das@FreeBSD.org> |
| | | * All rights reserved. |
| | | */ |
| | | size_t |
| | | BSD_strnlen(const char *s, size_t maxlen) |
| | | { |
| | | size_t len; |
| | | |
| | | for (len = 0; len < maxlen; len++, s++) { |
| | | if (!*s) |
| | | break; |
| | | } |
| | | return (len); |
| | | } |
| | | #endif |
| | | |
| | |
| | | #define SCPI_UTILS_H |
| | | |
| | | #include <stdint.h> |
| | | #include "scpi/config.h" |
| | | #include "scpi/types.h" |
| | | |
| | | #ifdef __cplusplus |
| | |
| | | size_t skipWhitespace(const char * cmd, size_t len) LOCAL; |
| | | bool_t matchPattern(const char * pattern, size_t pattern_len, const char * str, size_t str_len) LOCAL; |
| | | |
| | | #if !HAVE_STRNLEN |
| | | size_t BSD_strnlen(const char *s, size_t maxlen); |
| | | #endif |
| | | |
| | | #define min(a, b) (((a) < (b)) ? (a) : (b)) |
| | | #define max(a, b) (((a) > (b)) ? (a) : (b)) |
| | | |