Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/j123b567/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
mvladic committed Oct 16, 2015
2 parents b7e9d68 + 7cae5d8 commit d6e013b
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 42 deletions.
11 changes: 11 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@ addons:
packages:
- libcunit1-dev
- clang
- gcc-multilib

sudo: false

before_script:
- wget http://downloads.sourceforge.net/project/cunit/CUnit/2.1-3/CUnit-2.1-3.tar.bz2 -O /tmp/cunit.tar.bz2
- tar -xvf /tmp/cunit.tar.bz2
- cd CUnit-2.1-3
- CFLAGS="-m32" LDFLAGS="-m32" ./bootstrap
- make
- export LD_LIBRARY_PATH=$PWD/CUnit/Sources/.libs/:$LD_LIBRARY_PATH
- cd ..

script:
- make
- CC=clang CFLAGS="-g -O0 -fsanitize=address" LDFLAGS="-g -fsanitize=address" make clean test
- CFLAGS="-m32" LDFLAGS="-m32 -L$PWD/CUnit-2.1-3/CUnit/Sources/.libs/" make clean test
2 changes: 1 addition & 1 deletion examples/test-tcp-srq/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ scpi_result_t SCPI_Reset(scpi_t * context) {
}

scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context) {
SCPI_ResultInt(context, CONTROL_PORT);
SCPI_ResultInt32(context, CONTROL_PORT);
return SCPI_RES_OK;
}

Expand Down
8 changes: 8 additions & 0 deletions libscpi/inc/scpi/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ extern "C" {
#define USE_USER_ERROR_LIST 0
#endif

#ifndef USE_COMMAND_TAGS
#define USE_COMMAND_TAGS 1
#endif

#ifndef USE_DEPRECATED_FUNCTIONS
#define USE_DEPRECATED_FUNCTIONS 1
#endif

/* Compiler specific */
/* RealView/Keil ARM Compiler, e.g. Cortex-M CPUs */
#if defined(__CC_ARM)
Expand Down
2 changes: 1 addition & 1 deletion libscpi/inc/scpi/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ extern "C" {
XE(SCPI_ERROR_COMMUNICATION_ERROR, -360, "Communication error") \
XE(SCPI_ERROR_PARITY_ERROR_IN_CMD_MSG, -361, "Parity error in program message") \
XE(SCPI_ERROR_FRAMING_ERROR_IN_CMD_MSG, -362, "Framing error in program message") \
XE(SCPI_ERROR_INPUT_BUFFER_OVERRUN, -363, "Input buffer overrun") \
X(SCPI_ERROR_INPUT_BUFFER_OVERRUN, -363, "Input buffer overrun") \
XE(SCPI_ERROR_TIME_OUT, -365, "Time out error") \
XE(SCPI_ERROR_QUERY_ERROR, -400, "Query error") \
XE(SCPI_ERROR_QUERY_INTERRUPTED, -410, "Query INTERRUPTED") \
Expand Down
18 changes: 11 additions & 7 deletions libscpi/inc/scpi/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* 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:
Expand All @@ -11,7 +11,7 @@
* 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
Expand All @@ -28,10 +28,10 @@
/**
* @file scpi_parser.h
* @date Thu Nov 15 10:58:45 UTC 2012
*
*
* @brief SCPI parser implementation
*
*
*
*
*/

#ifndef SCPI_PARSER_H
Expand All @@ -45,8 +45,8 @@ extern "C" {
#endif
void SCPI_Init(scpi_t * context);

int SCPI_Input(scpi_t * context, const char * data, int len);
int SCPI_Parse(scpi_t * context, char * data, int len);
scpi_bool_t SCPI_Input(scpi_t * context, const char * data, int len);
scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len);

size_t SCPI_ResultCharacters(scpi_t * context, const char * data, size_t len);
#define SCPI_ResultMnemonic(context, data) SCPI_ResultCharacters((context), (data), strlen(data))
Expand Down Expand Up @@ -87,17 +87,21 @@ extern "C" {
scpi_bool_t SCPI_ParamChoice(scpi_t * context, const scpi_choice_def_t * options, int32_t * value, scpi_bool_t mandatory);

scpi_bool_t SCPI_IsCmd(scpi_t * context, const char * cmd);
#if USE_COMMAND_TAGS
int32_t SCPI_CmdTag(scpi_t * context);
#endif /* USE_COMMAND_TAGS */
scpi_bool_t SCPI_Match(const char * pattern, const char * value, size_t len);
scpi_bool_t SCPI_CommandNumbers(scpi_t * context, int32_t * numbers, size_t len, int32_t default_value);

#if USE_DEPRECATED_FUNCTIONS
// deprecated finction, should be removed later
#define SCPI_ResultIntBase(context, val, base) SCPI_ResultInt32Base ((context), (val), (base), TRUE)
#define SCPI_ResultInt(context, val) SCPI_ResultInt32 ((context), (val))
#define SCPI_ParamToInt(context, parameter, value) SCPI_ParamToInt32((context), (parameter), (value))
#define SCPI_ParamToUnsignedInt(context, parameter, value) SCPI_ParamToUInt32((context), (parameter), (value))
#define SCPI_ParamInt(context, value, mandatory) SCPI_ParamInt32((context), (value), (mandatory))
#define SCPI_ParamUnsignedInt(context, value, mandatory) SCPI_ParamUInt32((context), (value), (mandatory))
#endif /* USE_DEPRECATED_FUNCTIONS */

#ifdef __cplusplus
}
Expand Down
2 changes: 2 additions & 0 deletions libscpi/inc/scpi/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,9 @@ extern "C" {
struct _scpi_command_t {
const char * pattern;
scpi_command_callback_t callback;
#if USE_COMMAND_TAGS
int32_t tag;
#endif /* USE_COMMAND_TAGS */
};

struct _scpi_interface_t {
Expand Down
2 changes: 1 addition & 1 deletion libscpi/src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ static scpi_expr_result_t channelSpec(scpi_t * context, lex_state_t * state, int
size_t i = 0;
while (scpiLex_DecimalNumericProgramData(state, &param)) {
if (i < length) {
SCPI_ParamToInt(context, &param, &values[i]);
SCPI_ParamToInt32(context, &param, &values[i]);
}

if (scpiLex_SpecificCharacter(state, &param, '!')) {
Expand Down
6 changes: 4 additions & 2 deletions libscpi/src/ieee488.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,9 @@ scpi_result_t SCPI_CoreEse(scpi_t * context) {
int32_t new_ESE;
if (SCPI_ParamInt32(context, &new_ESE, TRUE)) {
SCPI_RegSet(context, SCPI_REG_ESE, (scpi_reg_val_t) new_ESE);
return SCPI_RES_OK;
}
return SCPI_RES_OK;
return SCPI_RES_ERR;
}

/**
Expand Down Expand Up @@ -303,8 +304,9 @@ scpi_result_t SCPI_CoreSre(scpi_t * context) {
int32_t new_SRE;
if (SCPI_ParamInt32(context, &new_SRE, TRUE)) {
SCPI_RegSet(context, SCPI_REG_SRE, (scpi_reg_val_t) new_SRE);
return SCPI_RES_OK;
}
return SCPI_RES_OK;
return SCPI_RES_ERR;
}

/**
Expand Down
45 changes: 30 additions & 15 deletions libscpi/src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,10 @@ static size_t writeSemicolon(scpi_t * context) {
* Process command
* @param context
*/
static void processCommand(scpi_t * context) {
static scpi_bool_t processCommand(scpi_t * context) {
const scpi_command_t * cmd = context->param_list.cmd;
lex_state_t * state = &context->param_list.lex_state;
scpi_bool_t result = TRUE;

/* conditionaly write ; */
writeSemicolon(context);
Expand All @@ -131,15 +132,25 @@ static void processCommand(scpi_t * context) {

/* 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);
if ((cmd->callback(context) != SCPI_RES_OK)) {
if (!context->cmd_error) {
SCPI_ErrorPush(context, SCPI_ERROR_EXECUTION_ERROR);
}
result = FALSE;
} else {
if (context->cmd_error) {
result = FALSE;
}
}
}

/* set error if command callback did not read all parameters */
if (state->pos < (state->buffer + state->len) && !context->cmd_error) {
SCPI_ErrorPush(context, SCPI_ERROR_PARAMETER_NOT_ALLOWED);
result = FALSE;
}

return result;
}

/**
Expand All @@ -166,28 +177,27 @@ static scpi_bool_t findCommandHeader(scpi_t * context, const char * header, int
* @param context
* @param data - complete command line
* @param len - command line length
* @return 1 if the last evaluated command was found
* @return FALSE if there was some error during evaluation of commands
*/
int SCPI_Parse(scpi_t * context, char * data, int len) {
int result = 0;
scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len) {
scpi_bool_t result = TRUE;
scpi_parser_state_t * state;
int r;
scpi_token_t cmd_prev = {SCPI_TOKEN_UNKNOWN, NULL, 0};

if (context == NULL) {
return -1;
return FALSE;
}

state = &context->parser_state;
context->output_count = 0;

while (1) {
result = 0;

r = scpiParser_detectProgramMessageUnit(state, data, len);

if (state->programHeader.type == SCPI_TOKEN_INVALID) {
SCPI_ErrorPush(context, SCPI_ERROR_INVALID_CHARACTER);
result = FALSE;
} else if (state->programHeader.len > 0) {

composeCompoundCommand(&cmd_prev, &state->programHeader);
Expand All @@ -201,12 +211,11 @@ int SCPI_Parse(scpi_t * context, char * data, int len) {
context->param_list.cmd_raw.position = 0;
context->param_list.cmd_raw.length = state->programHeader.len;

processCommand(context);

result = 1;
result &= processCommand(context);
cmd_prev = state->programHeader;
} else {
SCPI_ErrorPush(context, SCPI_ERROR_UNDEFINED_HEADER);
result = FALSE;
}
}

Expand Down Expand Up @@ -260,8 +269,8 @@ void SCPI_Init(scpi_t * context) {
* @param len - length of data
* @return
*/
int SCPI_Input(scpi_t * context, const char * data, int len) {
int result = 0;
scpi_bool_t SCPI_Input(scpi_t * context, const char * data, int len) {
scpi_bool_t result = TRUE;
size_t totcmdlen = 0;
int cmdlen = 0;

Expand All @@ -274,7 +283,11 @@ int SCPI_Input(scpi_t * context, const char * data, int len) {

buffer_free = context->buffer.length - context->buffer.position;
if (len > (buffer_free - 1)) {
return -1;
/* Input buffer overrun - invalidate buffer */
context->buffer.position = 0;
context->buffer.data[context->buffer.position] = 0;
SCPI_ErrorPush(context, SCPI_ERROR_INPUT_BUFFER_OVERRUN);
return FALSE;
}
memcpy(&context->buffer.data[context->buffer.position], data, len);
context->buffer.position += len;
Expand Down Expand Up @@ -1337,6 +1350,7 @@ scpi_bool_t SCPI_IsCmd(scpi_t * context, const char * cmd) {
return matchCommand(pattern, cmd, strlen(cmd), NULL, 0, 0);
}

#if USE_COMMAND_TAGS
/**
* Return the .tag field of the matching scpi_command_t
* @param context
Expand All @@ -1349,6 +1363,7 @@ int32_t SCPI_CmdTag(scpi_t * context) {
return 0;
}
}
#endif /* USE_COMMAND_TAGS */

scpi_bool_t SCPI_Match(const char * pattern, const char * value, size_t len) {
return matchCommand(pattern, value, len, NULL, 0, 0);
Expand Down
6 changes: 3 additions & 3 deletions libscpi/src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ size_t UInt32ToStrBaseSign(uint32_t val, char * str, size_t len, int8_t base, sc
* @return number of bytes written to str (without '\0')
*/
size_t SCPI_Int32ToStr(int32_t val, char * str, size_t len) {
return UInt32ToStrBaseSign((int32_t) val, str, len, 10, TRUE);
return UInt32ToStrBaseSign((uint32_t) val, str, len, 10, TRUE);
}

/**
Expand Down Expand Up @@ -229,7 +229,7 @@ size_t UInt64ToStrBaseSign(uint64_t val, char * str, size_t len, int8_t base, sc
* @return number of bytes written to str (without '\0')
*/
size_t SCPI_Int64ToStr(int64_t val, char * str, size_t len) {
return UInt64ToStrBaseSign((int64_t) val, str, len, 10, TRUE);
return UInt64ToStrBaseSign((uint64_t) val, str, len, 10, TRUE);
}

/**
Expand Down Expand Up @@ -298,7 +298,7 @@ size_t strBaseToUInt32(const char * str, uint32_t * val, int8_t base) {
*/
size_t strBaseToInt64(const char * str, int64_t * val, int8_t base) {
char * endptr;
*val = strtol(str, &endptr, base);
*val = strtoll(str, &endptr, base);
return endptr - str;
}

Expand Down
29 changes: 17 additions & 12 deletions libscpi/test/test_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,19 +241,24 @@ static void testErrorHandling(void) {
output_buffer_clear();
error_buffer_clear();

#define TEST_ERROR(data, output, err_num) { \
#define TEST_ERROR(data, output, expected_result, err_num) { \
output_buffer_clear(); \
error_buffer_clear(); \
SCPI_Input(&scpi_context, data, strlen(data)); \
scpi_bool_t result = SCPI_Input(&scpi_context, data, strlen(data)); \
CU_ASSERT_STRING_EQUAL(output, output_buffer); \
CU_ASSERT_EQUAL(err_buffer[0], err_num) \
CU_ASSERT_EQUAL(err_buffer[0], err_num); \
CU_ASSERT_EQUAL(result, expected_result); \
}

TEST_ERROR("*IDN?\r\n", "MA,IN,0,VER\r\n", 0);
TEST_ERROR("IDN?\r\n", "", SCPI_ERROR_UNDEFINED_HEADER);
TEST_ERROR("*ESE\r\n", "", SCPI_ERROR_MISSING_PARAMETER);
TEST_ERROR("*IDN? 12\r\n", "MA,IN,0,VER\r\n", SCPI_ERROR_PARAMETER_NOT_ALLOWED);
TEST_ERROR("TEXT? \"PARAM1\", \"PARAM2\"\r\n", "\"PARAM2\"\r\n", 0);
TEST_ERROR("*IDN?\r\n", "MA,IN,0,VER\r\n", TRUE, 0);
TEST_ERROR("IDN?\r\n", "", FALSE, SCPI_ERROR_UNDEFINED_HEADER);
TEST_ERROR("*ESE\r\n", "", FALSE, SCPI_ERROR_MISSING_PARAMETER);
TEST_ERROR("*IDN? 12\r\n", "MA,IN,0,VER\r\n", FALSE, SCPI_ERROR_PARAMETER_NOT_ALLOWED);
TEST_ERROR("TEXT? \"PARAM1\", \"PARAM2\"\r\n", "\"PARAM2\"\r\n", TRUE, 0);
TEST_ERROR("ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ"
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ"
"ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ",
"", FALSE, SCPI_ERROR_INPUT_BUFFER_OVERRUN);

// TODO: SCPI_ERROR_INVALID_SEPARATOR
// TODO: SCPI_ERROR_INVALID_SUFFIX
Expand Down Expand Up @@ -387,8 +392,8 @@ static void testSCPI_ParamUInt32(void) {
TEST_ParamUInt32("10V", TRUE, 0, FALSE, -138);

// test range
TEST_ParamUInt32("2147483647", TRUE, 2147483647, TRUE, 0);
TEST_ParamUInt32("4294967295", TRUE, 4294967295, TRUE, 0);
TEST_ParamUInt32("2147483647", TRUE, 2147483647ULL, TRUE, 0);
TEST_ParamUInt32("4294967295", TRUE, 4294967295ULL, TRUE, 0);
}

#define TEST_ParamInt64(data, mandatory, expected_value, expected_result, expected_error_code) \
Expand Down Expand Up @@ -467,8 +472,8 @@ static void testSCPI_ParamUInt64(void) {
TEST_ParamUInt64("10V", TRUE, 0, FALSE, -138);

// test range
TEST_ParamUInt64("2147483647", TRUE, 2147483647, TRUE, 0);
TEST_ParamUInt64("4294967295", TRUE, 4294967295, TRUE, 0);
TEST_ParamUInt64("2147483647", TRUE, 2147483647ULL, TRUE, 0);
TEST_ParamUInt64("4294967295", TRUE, 4294967295ULL, TRUE, 0);
TEST_ParamUInt64("9223372036854775807", TRUE, 9223372036854775807ULL, TRUE, 0);
TEST_ParamUInt64("18446744073709551615", TRUE, 18446744073709551615ULL, TRUE, 0);
}
Expand Down
10 changes: 10 additions & 0 deletions libscpi/test/test_scpi_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ static void test_Int32ToStr() {
CU_ASSERT(len == strlen(ref));
CU_ASSERT_STRING_EQUAL(str, ref);
}

int16_t val16[] = {0, 1, -1, INT16_MIN, INT16_MAX, 0x0123, 0x4567, 0x89ab, 0xcdef};
int N16 = sizeof (val16) / sizeof (int16_t);
// test signed conversion to decimal numbers
for (i = 0; i < N16; i++) {
len = SCPI_Int32ToStr((int32_t) val16[i], str, max);
snprintf(ref, max, "%"PRIi16, val16[i]);
CU_ASSERT(len == strlen(ref));
CU_ASSERT_STRING_EQUAL(str, ref);
}
}

static void test_UInt32ToStrBase() {
Expand Down

0 comments on commit d6e013b

Please sign in to comment.