strdup(malloc)/free ready.
| | |
| | | |
| | | #ifndef USE_DEVICE_DEPENDENT_ERROR_INFORMATION |
| | | #define USE_DEVICE_DEPENDENT_ERROR_INFORMATION 1 |
| | | #endif |
| | | |
| | | #ifndef USE_MEMORY_ALLOCATION_FREE |
| | | #define USE_MEMORY_ALLOCATION_FREE 1 |
| | | #endif |
| | | #endif |
| | | |
| | | |
| | | |
| | | #ifndef USE_COMMAND_TAGS |
| | | #define USE_COMMAND_TAGS 1 |
| | |
| | | |
| | | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION |
| | | #if USE_MEMORY_ALLOCATION_FREE |
| | | #include <stdlib.h> |
| | | #include <string.h> |
| | | #include <malloc.h> |
| | | #define SCPIDEFINE_strdup(s) strdup((s)) |
| | | #define SCPIDEFINE_free(s) free((s)) |
| | | #define SCPIDEFINE_strdup(h,s) strdup((s)) |
| | | #define SCPIDEFINE_free(h,s) free((s)) |
| | | #else |
| | | #define SCPIDEFINE_strdup(s) NULL |
| | | #define SCPIDEFINE_free(s) NULL |
| | | #define SCPIDEFINE_strdup(h,s) OUR_strdup((h), (s)) |
| | | #define SCPIDEFINE_free(h,s) OUR_free((h), (s)) |
| | | #define SCPIDEFINE_get_1st_part(s,l) OUR_get_1st_part((s),(l)) |
| | | #define SCPIDEFINE_get_2st_part(s,l) OUR_get_2nd_part((s),(l)) |
| | | #endif |
| | | #else |
| | | #define SCPIDEFINE_strdup(s) NULL |
| | | #define SCPIDEFINE_free(s) NULL |
| | | #define SCPIDEFINE_strdup(h,s) (void)(s) |
| | | #define SCPIDEFINE_free(h,s) (void)(s) |
| | | #endif |
| | | |
| | | #ifdef __cplusplus |
| | |
| | | size_t SCPI_ResultFloat(scpi_t * context, float val); |
| | | size_t SCPI_ResultDouble(scpi_t * context, double val); |
| | | size_t SCPI_ResultText(scpi_t * context, const char * data); |
| | | size_t SCPI_ResultError(scpi_t * context, scpi_error_t * error); |
| | | size_t SCPI_ResultArbitraryBlock(scpi_t * context, const void * data, size_t len); |
| | | size_t SCPI_ResultArbitraryBlockHeader(scpi_t * context, size_t len); |
| | | size_t SCPI_ResultArbitraryBlockData(scpi_t * context, const void * data, size_t len); |
| | |
| | | typedef scpi_result_t(*scpi_command_callback_t)(scpi_t *); |
| | | |
| | | struct _scpi_error_info_heap_t { |
| | | size_t length; |
| | | size_t position; |
| | | int16_t wr; |
| | | int16_t rd; |
| | | int16_t count; |
| | | int16_t size; |
| | | char * data; |
| | | }; |
| | | typedef struct _scpi_error_info_heap_t scpi_error_info_heap_t; |
| | |
| | | * @param context - scpi context |
| | | */ |
| | | void SCPI_ErrorClear(scpi_t * context) { |
| | | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION |
| | | scpi_error_t error; |
| | | while(fifo_remove(&context->error_queue, &error)){ |
| | | SCPIDEFINE_free(&context->error_info_heap, error.device_dependent_info); |
| | | } |
| | | #endif |
| | | fifo_clear(&context->error_queue); |
| | | |
| | | SCPI_ErrorEmitEmpty(context); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Pop error from queue |
| | | * @param context - scpi context |
| | | * @param error |
| | | * @return |
| | | */ |
| | | scpi_bool_t SCPI_ErrorPopEx(scpi_t * context, scpi_error_t * error) { |
| | | if(error == NULL) return FALSE; |
| | | |
| | | if(!error) return FALSE; |
| | | error->error_code = 0; |
| | | error->device_dependent_info = NULL; |
| | | fifo_remove(&context->error_queue, error); |
| | | |
| | | SCPI_ErrorEmitEmpty(context); |
| | |
| | | |
| | | static scpi_bool_t SCPI_ErrorAddInternal(scpi_t * context, int16_t err, char * info) { |
| | | if (!fifo_add(&context->error_queue, err, info)) { |
| | | fifo_remove_last(&context->error_queue, NULL); |
| | | scpi_error_t * error; |
| | | fifo_remove_last(&context->error_queue, error); |
| | | SCPIDEFINE_free(&context->error_info_heap, error->device_dependent_info); |
| | | fifo_add(&context->error_queue, SCPI_ERROR_QUEUE_OVERFLOW, NULL); |
| | | return FALSE; |
| | | } |
| | |
| | | */ |
| | | void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info) { |
| | | int i; |
| | | char * info_ptr=SCPIDEFINE_strdup(info); |
| | | char * info_ptr = NULL; |
| | | |
| | | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION |
| | | if (info){ |
| | | info_ptr = SCPIDEFINE_strdup(&context->error_info_heap, info); |
| | | } |
| | | #endif |
| | | |
| | | scpi_bool_t queue_overflow = !SCPI_ErrorAddInternal(context, err, info_ptr); |
| | | |
| | | for (i = 0; i < ERROR_DEFS_N; i++) { |
| | |
| | | void SCPI_ErrorPush(scpi_t * context, int16_t err) { |
| | | SCPI_ErrorPushEx(context, err, NULL); |
| | | return; |
| | | int i; |
| | | |
| | | scpi_bool_t queue_overflow = !SCPI_ErrorAddInternal(context, err, NULL); |
| | | |
| | | for (i = 0; i < ERROR_DEFS_N; i++) { |
| | | if ((err <= errs[i].from) && (err >= errs[i].to)) { |
| | | SCPI_RegSetBits(context, SCPI_REG_ESR, errs[i].bit); |
| | | } |
| | | } |
| | | |
| | | SCPI_ErrorEmit(context, err); |
| | | if (queue_overflow) { |
| | | SCPI_ErrorEmit(context, SCPI_ERROR_QUEUE_OVERFLOW); |
| | | } |
| | | |
| | | if (context) { |
| | | context->cmd_error = TRUE; |
| | | } |
| | | //int i; |
| | | // |
| | | //scpi_bool_t queue_overflow = !SCPI_ErrorAddInternal(context, err, NULL); |
| | | // |
| | | //for (i = 0; i < ERROR_DEFS_N; i++) { |
| | | //if ((err <= errs[i].from) && (err >= errs[i].to)) { |
| | | //SCPI_RegSetBits(context, SCPI_REG_ESR, errs[i].bit); |
| | | //} |
| | | //} |
| | | // |
| | | //SCPI_ErrorEmit(context, err); |
| | | //if (queue_overflow) { |
| | | //SCPI_ErrorEmit(context, SCPI_ERROR_QUEUE_OVERFLOW); |
| | | //} |
| | | // |
| | | //if (context) { |
| | | //context->cmd_error = TRUE; |
| | | //} |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | scpi_result_t SCPI_SystemErrorNextQ(scpi_t * context) { |
| | | scpi_error_t error; |
| | | if(!SCPI_ErrorPopEx(context, &error))return SCPI_RES_ERR; |
| | | SCPI_ErrorPopEx(context, &error); |
| | | SCPI_ResultError(context, &error); |
| | | return SCPI_RES_OK; |
| | | |
| | | //int16_t err = SCPI_ErrorPop(context); |
| | | |
| | | SCPI_ResultInt32(context, error.error_code); |
| | | SCPI_ResultText(context, SCPI_ErrorTranslate(error.error_code)); |
| | | |
| | | size_t info_len=0; |
| | | if(error.device_dependent_info){ |
| | | info_len=SCPIDEFINE_strnlen(error.device_dependent_info,255); |
| | | SCPI_ResultCharacters(context, ";", 1); |
| | | SCPI_ResultText(context, error.device_dependent_info); |
| | | SCPIDEFINE_free(error.device_dependent_info); |
| | | } |
| | | |
| | | |
| | | |
| | | return SCPI_RES_OK; |
| | | //SCPI_ResultInt32(context, error.error_code); |
| | | //SCPI_ResultText(context, SCPI_ErrorTranslate(error.error_code)); |
| | | //return SCPI_RES_OK; |
| | | } |
| | | |
| | | /** |
| | |
| | | return result; |
| | | } |
| | | |
| | | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION |
| | | #if USE_MEMORY_ALLOCATION_FREE |
| | | #define MAX_BUFF_SIZE 2 |
| | | #else |
| | | #define MAX_BUFF_SIZE 3 |
| | | #endif |
| | | #else |
| | | #define MAX_BUFF_SIZE 1 |
| | | #endif |
| | | |
| | | static size_t startoutputlimit = 0; |
| | | |
| | | size_t SCPI_ResultError(scpi_t * context, scpi_error_t * error) { |
| | | size_t result = 0; |
| | | size_t outputlimit = startoutputlimit++; |
| | | size_t step = 0; |
| | | const char * quote; |
| | | |
| | | char * data[MAX_BUFF_SIZE]; |
| | | size_t len[MAX_BUFF_SIZE]; |
| | | |
| | | data[0] = SCPI_ErrorTranslate(error->error_code); |
| | | len[0] = strlen(data[0]); |
| | | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION |
| | | #if USE_MEMORY_ALLOCATION_FREE |
| | | data[1] = error->device_dependent_info; |
| | | len[1] = error->device_dependent_info ? strlen(data[1]) : 0; |
| | | #else |
| | | data[1] = SCPIDEFINE_get_1st_part(error->device_dependent_info,&len[1]); |
| | | data[2] = SCPIDEFINE_get_1st_part(data[1],&len[2]); |
| | | #endif |
| | | #endif |
| | | |
| | | result += SCPI_ResultInt32(context, error->error_code); |
| | | result += writeDelimiter(context); |
| | | result += writeData(context, "\"", 1); |
| | | |
| | | for(size_t i = 0; data[i] && outputlimit && (i < MAX_BUFF_SIZE); i++){ |
| | | if(i==1){ |
| | | result += writeSemicolon(context); |
| | | outputlimit -= 1; |
| | | } |
| | | if(len[i] > outputlimit) { |
| | | len[i] = outputlimit; |
| | | } |
| | | |
| | | while ((quote = strnpbrk(data[i], len[i], "\""))) { |
| | | if((step = quote - data[i] + 1) >= outputlimit){ |
| | | len[i] -= 1; |
| | | outputlimit -= 1; |
| | | break; |
| | | } |
| | | result += writeData(context, data[i], step); |
| | | result += writeData(context, "\"", 1); |
| | | len[i] -= step ; |
| | | outputlimit -= step + 1; |
| | | data[i] = quote + 1; |
| | | if(len[i] > outputlimit) { |
| | | len[i] = outputlimit; |
| | | } |
| | | } |
| | | |
| | | result += writeData(context, data[i], len[i]); |
| | | outputlimit-=len[i]; |
| | | } |
| | | result += writeData(context, "\"", 1); |
| | | |
| | | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION |
| | | #if USE_MEMORY_ALLOCATION_FREE |
| | | SCPIDEFINE_free(error->device_dependent_info); |
| | | #else |
| | | #endif |
| | | #endif |
| | | |
| | | return result; |
| | | } |
| | | #undef MAX_BUFF_SIZE |
| | | |
| | | /** |
| | | * Write arbitrary block header with length |
| | | * @param context |
| | |
| | | } |
| | | #endif |
| | | |
| | | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE |
| | | char * OUR_strdup(scpi_error_info_heap_t * heap, const char *s) { |
| | | if(!heap || !s) { |
| | | return NULL; |
| | | } |
| | | if(heap->data[heap->wr]!='\0'){ |
| | | return NULL; |
| | | } |
| | | |
| | | size_t len=strlen(s) + 1; // additional '\0' at end |
| | | if(len > heap->count){ |
| | | return NULL; |
| | | } |
| | | size_t f_part=(&heap->data[heap->wr]-heap->data) |
| | | |
| | | |
| | | return NULL; |
| | | } |
| | | void OUR_free(scpi_error_info_heap_t * heap, const char *s) { |
| | | |
| | | } |
| | | char * OUR_get_1st_part(const char *s, size_t * len) { |
| | | return NULL; |
| | | } |
| | | char * OUR_get_2nd_part(const char *s, size_t * len) { |
| | | return NULL; |
| | | } |
| | | #endif |
| | | |
| | | // Floating point to string conversion routines |
| | | // |
| | | // Copyright (C) 2002 Michael Ringgaard. All rights reserved. |
| | |
| | | int OUR_strncasecmp(const char *s1, const char *s2, size_t n) LOCAL; |
| | | #endif |
| | | |
| | | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE |
| | | char * OUR_strdup(scpi_error_info_heap_t * heap, const char *s) LOCAL; |
| | | void OUR_free(scpi_error_info_heap_t * heap, const char *s) LOCAL; |
| | | char * OUR_get_1st_part(const char *s, size_t * len) LOCAL; |
| | | char * OUR_get_2nd_part(const char *s, size_t * len) LOCAL; |
| | | #endif |
| | | |
| | | #ifndef min |
| | | #define min(a, b) (((a) < (b)) ? (a) : (b)) |
| | | #endif |