From 508dece619e26b08a95fa856581d14816b2eef1f Mon Sep 17 00:00:00 2001 From: Chernov Dmitriy <cd_work@mail.ru> Date: 周一, 29 2月 2016 22:16:38 +0800 Subject: [PATCH] manual heap ready --- libscpi/inc/scpi/types.h | 2 libscpi/src/minimal.c | 12 +- libscpi/src/parser.c | 44 ++++------ libscpi/inc/scpi/config.h | 18 ++-- libscpi/src/utils_private.h | 5 libscpi/src/error.c | 7 - libscpi/inc/scpi/constants.h | 5 + libscpi/src/utils.c | 103 ++++++++++++++++++++++--- 8 files changed, 137 insertions(+), 59 deletions(-) diff --git a/libscpi/inc/scpi/config.h b/libscpi/inc/scpi/config.h index 75b9731..ea19d8e 100644 --- a/libscpi/inc/scpi/config.h +++ b/libscpi/inc/scpi/config.h @@ -263,17 +263,19 @@ #include <stdlib.h> #include <string.h> #include <malloc.h> - #define SCPIDEFINE_strdup(h,s) strdup((s)) - #define SCPIDEFINE_free(h,s) free((s)) + #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 2 + #define SCPIDEFINE_strdup(h, s) strdup((s)) + #define SCPIDEFINE_free(h, s, r) free((s)) #else - #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)) + #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 3 + #define SCPIDEFINE_strdup(h, s) OUR_strdup((h), (s)) + #define SCPIDEFINE_free(h, s, r) OUR_free((h), (s), (r)) + #define SCPIDEFINE_get_parts(h, s, l1, s2, l2) OUR_get_parts((h), (s), (l1), (s2), (l2)) #endif #else - #define SCPIDEFINE_strdup(h,s) (void)(s) - #define SCPIDEFINE_free(h,s) (void)(s) + #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 1 + #define SCPIDEFINE_strdup(h, s) NULL + #define SCPIDEFINE_free(h, s, r) (void) #endif #ifdef __cplusplus diff --git a/libscpi/inc/scpi/constants.h b/libscpi/inc/scpi/constants.h index 61cd9a6..e2ad2d0 100644 --- a/libscpi/inc/scpi/constants.h +++ b/libscpi/inc/scpi/constants.h @@ -48,6 +48,11 @@ */ #define SCPI_STD_VERSION_REVISION "1999.0" +/* 21.8 :ERRor Subsystem + * The maximum string length of <Error/event_description> plus <Device-dependent_info> is 255 characters. + */ +#define SCPI_STD_ERROR_DESC_CHARS_LIMIT 255 + #ifdef __cplusplus } #endif diff --git a/libscpi/inc/scpi/types.h b/libscpi/inc/scpi/types.h index 8dbcd64..085ca00 100644 --- a/libscpi/inc/scpi/types.h +++ b/libscpi/inc/scpi/types.h @@ -203,7 +203,7 @@ struct _scpi_error_info_heap_t { int16_t wr; - int16_t rd; + //int16_t rd; int16_t count; int16_t size; char * data; diff --git a/libscpi/src/error.c b/libscpi/src/error.c index ca48cc5..7b17f4c 100644 --- a/libscpi/src/error.c +++ b/libscpi/src/error.c @@ -84,7 +84,7 @@ #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); + SCPIDEFINE_free(&context->error_info_heap, error.device_dependent_info, false); } #endif fifo_clear(&context->error_queue); @@ -138,9 +138,7 @@ static scpi_bool_t SCPI_ErrorAddInternal(scpi_t * context, int16_t err, char * info) { if (!fifo_add(&context->error_queue, err, info)) { - scpi_error_t * error; - fifo_remove_last(&context->error_queue, error); - SCPIDEFINE_free(&context->error_info_heap, error->device_dependent_info); + fifo_remove_last(&context->error_queue, NULL); fifo_add(&context->error_queue, SCPI_ERROR_QUEUE_OVERFLOW, NULL); return FALSE; } @@ -193,6 +191,7 @@ SCPI_ErrorEmit(context, err); if (queue_overflow) { SCPI_ErrorEmit(context, SCPI_ERROR_QUEUE_OVERFLOW); + SCPIDEFINE_free(&context->error_info_heap, info_ptr, true); } if (context) { diff --git a/libscpi/src/minimal.c b/libscpi/src/minimal.c index f5372ff..f2af219 100644 --- a/libscpi/src/minimal.c +++ b/libscpi/src/minimal.c @@ -77,15 +77,15 @@ * @return */ scpi_result_t SCPI_SystemErrorNextQ(scpi_t * context) { - scpi_error_t error; + SCPI_ResultInt32(context,context->error_info_heap.count); + + scpi_error_t error; SCPI_ErrorPopEx(context, &error); SCPI_ResultError(context, &error); + + SCPI_ResultInt32(context,context->error_info_heap.count); return SCPI_RES_OK; - - //int16_t err = SCPI_ErrorPop(context); - //SCPI_ResultInt32(context, error.error_code); - //SCPI_ResultText(context, SCPI_ErrorTranslate(error.error_code)); - //return SCPI_RES_OK; + } /** diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c index ca0aa93..fd85e47 100644 --- a/libscpi/src/parser.c +++ b/libscpi/src/parser.c @@ -269,8 +269,10 @@ context->buffer.length = input_buffer_length; context->buffer.position = 0; context->error_info_heap.data = error_info_heap; - context->error_info_heap.position = 0; - context->error_info_heap.length = error_info_heap_length; + context->error_info_heap.wr = 0; + context->error_info_heap.size = error_info_heap_length; + context->error_info_heap.count = context->error_info_heap.size; + memset(context->error_info_heap.data,0,context->error_info_heap.size); SCPI_ErrorInit(context, error_queue_data, error_queue_size); } @@ -507,36 +509,32 @@ 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; - +/** + * Write string withn " to the result + * @param context + * @param data + * @return + */ +static size_t outputlimit_0=0; size_t SCPI_ResultError(scpi_t * context, scpi_error_t * error) { size_t result = 0; - size_t outputlimit = startoutputlimit++; + size_t outputlimit = outputlimit_0++; //SCPI_STD_ERROR_DESC_CHARS_LIMIT; size_t step = 0; const char * quote; - char * data[MAX_BUFF_SIZE]; - size_t len[MAX_BUFF_SIZE]; + char * data[SCPIDEFINE_DESCRIPTION_MAX_PARTS]; + size_t len[SCPIDEFINE_DESCRIPTION_MAX_PARTS]; data[0] = SCPI_ErrorTranslate(error->error_code); len[0] = strlen(data[0]); + #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION + data[1] = error->device_dependent_info; #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]); + SCPIDEFINE_get_parts(&context->error_info_heap, data[1], &len[1], &data[2], &len[2]); #endif #endif @@ -544,7 +542,7 @@ result += writeDelimiter(context); result += writeData(context, "\"", 1); - for(size_t i = 0; data[i] && outputlimit && (i < MAX_BUFF_SIZE); i++){ + for(size_t i = 0; data[i] && outputlimit && (i < SCPIDEFINE_DESCRIPTION_MAX_PARTS); i++){ if(i==1){ result += writeSemicolon(context); outputlimit -= 1; @@ -575,15 +573,11 @@ result += writeData(context, "\"", 1); #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION - #if USE_MEMORY_ALLOCATION_FREE - SCPIDEFINE_free(error->device_dependent_info); - #else - #endif + SCPIDEFINE_free(&context->error_info_heap, error->device_dependent_info, false); #endif return result; } -#undef MAX_BUFF_SIZE /** * Write arbitrary block header with length diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c index 945a625..de8fb64 100644 --- a/libscpi/src/utils.c +++ b/libscpi/src/utils.c @@ -751,8 +751,16 @@ #endif #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE +/** + * Duplicate string if "strdup" ("malloc/free") not supported on system. + * Allocate space in heap if it possible + * + * @param heap - pointer to manual allocated heap buffer + * @param s - current pointer of duplication string + * @return - pointer of duplicated string or NULL, if duplicate is not possible. + */ char * OUR_strdup(scpi_error_info_heap_t * heap, const char *s) { - if(!heap || !s) { + if(!s || !heap) { return NULL; } if(heap->data[heap->wr]!='\0'){ @@ -763,20 +771,91 @@ if(len > heap->count){ return NULL; } - size_t f_part=(&heap->data[heap->wr]-heap->data) + char * ptrs = s; + char * head = &heap->data[heap->wr]; + size_t rem = heap->size - (&heap->data[heap->wr]-heap->data); + size_t sstp = 0; + + if(len >= rem){ + memcpy(&heap->data[heap->wr],s,rem); + len = len - rem; + ptrs += rem; + heap->wr = 0; + heap->count -= rem; + } + + memcpy(&heap->data[heap->wr],ptrs,len); + heap->wr += len; + heap->count -= len; + + return head; +} + +/** + * Return pointers and lengths two parts of string in the circular buffer from heap + * + * @param heap - pointer to manual allocated heap buffer + * @param s - pointer of duplicate string. + * @return len1 - lenght of first part of string. + * @return s2 - pointer of second part of string, if string splited . + * @return len2 - lenght of second part of string. + */ +scpi_bool_t OUR_get_parts(scpi_error_info_heap_t * heap, const char * s, size_t * len1, const char ** s2, size_t * len2) { + if(!heap || !s || !len1 || !s2 || !len2) { + return FALSE; + } + + if(*s == '\0') { + return FALSE; + } + + *len1 = 0; + size_t rem = heap->size - (s - heap->data); + *len1 = strnlen(s, rem); + + if(&s[*len1-1] == &heap->data[heap->size-1]){ + *s2 = heap->data; + *len2 = strnlen(*s2, heap->size); + }else{ + *s2 = NULL; + *len2 = 0; + } + return TRUE; +} + +/** + * Frees space in heap, if "malloc/free" not supported on system, or nothing. + * + * @param heap - pointer to manual allocated heap buffer + * @param s - pointer of duplicate string + * @param rollback - backward write pointer in heap + */ +void OUR_free(scpi_error_info_heap_t * heap, const char * s, scpi_bool_t rollback) { + + if(!s) return; + + char * data_add; + size_t len[2]; + + if( !OUR_get_parts( heap, s, &len[0], &data_add, &len[1] ) ) return; - return NULL; + if(data_add) { + len[1]++; + memset(data_add,0,len[1]); + heap->count += len[1]; + } else { + len[0]++; + } + memset(s,0,len[0]); + heap->count += len[0]; + if(rollback){ + heap->wr-=len[0]; + heap->wr-=len[1]; + if(heap->wr < 0)heap->wr += heap->size; + } } -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 diff --git a/libscpi/src/utils_private.h b/libscpi/src/utils_private.h index 68b52bc..09aad22 100644 --- a/libscpi/src/utils_private.h +++ b/libscpi/src/utils_private.h @@ -89,9 +89,8 @@ #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; + void OUR_free(scpi_error_info_heap_t * heap, const char *s, scpi_bool_t rollback) LOCAL; + scpi_bool_t OUR_get_parts(scpi_error_info_heap_t * heap, const char *s1, size_t * len1, const char ** s2, size_t * len2) LOCAL; #endif #ifndef min -- Gitblit v1.9.1