| | |
| | | |
| | | void SCPI_ErrorInit(scpi_t * context, scpi_error_t * data, int16_t size); |
| | | void SCPI_ErrorClear(scpi_t * context); |
| | | scpi_bool_t SCPI_ErrorPop(scpi_t * context, scpi_error_t * error); |
| | | void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info); |
| | | scpi_bool_t SCPI_ErrorPop(scpi_t * context, scpi_error_t * error); |
| | | void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info); |
| | | void SCPI_ErrorPush(scpi_t * context, int16_t err); |
| | | int32_t SCPI_ErrorCount(scpi_t * context); |
| | | const char * SCPI_ErrorTranslate(int16_t err); |
| | |
| | | |
| | | typedef scpi_result_t(*scpi_command_callback_t)(scpi_t *); |
| | | |
| | | struct _scpi_error_info_heap_t { |
| | | struct _scpi_error_info_heap_t { |
| | | size_t wr; |
| | | //size_t rd; |
| | | size_t count; |
| | | size_t count; |
| | | size_t size; |
| | | char * data; |
| | | }; |
| | | typedef struct _scpi_error_info_heap_t scpi_error_info_heap_t; |
| | | |
| | | struct _scpi_error_t { |
| | | int16_t error_code; |
| | | const char * device_dependent_info; |
| | | }; |
| | | typedef struct _scpi_error_t scpi_error_t; |
| | | |
| | | }; |
| | | typedef struct _scpi_error_info_heap_t scpi_error_info_heap_t; |
| | | |
| | | struct _scpi_error_t { |
| | | int16_t error_code; |
| | | const char * device_dependent_info; |
| | | }; |
| | | typedef struct _scpi_error_t scpi_error_t; |
| | | |
| | | struct _scpi_fifo_t { |
| | | int16_t wr; |
| | | int16_t rd; |
| | |
| | | int_fast16_t input_count; |
| | | scpi_bool_t cmd_error; |
| | | scpi_fifo_t error_queue; |
| | | scpi_error_info_heap_t error_info_heap; |
| | | scpi_error_info_heap_t error_info_heap; |
| | | scpi_reg_val_t registers[SCPI_REG_COUNT]; |
| | | const scpi_unit_def_t * units; |
| | | void * user_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, false); |
| | | } |
| | | #endif |
| | | scpi_error_t error; |
| | | while (fifo_remove(&context->error_queue, &error)) { |
| | | SCPIDEFINE_free(&context->error_info_heap, error.device_dependent_info, false); |
| | | } |
| | | #endif |
| | | fifo_clear(&context->error_queue); |
| | | |
| | | SCPI_ErrorEmitEmpty(context); |
| | |
| | | * Pop error from queue |
| | | * @param context - scpi context |
| | | * @param error |
| | | * @return |
| | | * @return |
| | | */ |
| | | scpi_bool_t SCPI_ErrorPop(scpi_t * context, scpi_error_t * error) { |
| | | if(!error || !context) return FALSE; |
| | | error->error_code = 0; |
| | | error->device_dependent_info = NULL; |
| | | fifo_remove(&context->error_queue, error); |
| | | if (!error || !context) return FALSE; |
| | | error->error_code = 0; |
| | | error->device_dependent_info = NULL; |
| | | fifo_remove(&context->error_queue, error); |
| | | |
| | | SCPI_ErrorEmitEmpty(context); |
| | | SCPI_ErrorEmitEmpty(context); |
| | | |
| | | return TRUE; |
| | | return TRUE; |
| | | } |
| | | |
| | | /** |
| | |
| | | scpi_reg_val_t bit; |
| | | }; |
| | | |
| | | #define ERROR_DEFS_N 9 |
| | | #define ERROR_DEFS_N 9 |
| | | |
| | | static const struct error_reg errs[ERROR_DEFS_N] = { |
| | | {-100, -199, ESR_CER}, /* Command error (e.g. syntax error) ch 21.8.9 */ |
| | |
| | | * @param err - error number |
| | | */ |
| | | void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info) { |
| | | int i; |
| | | char * info_ptr = NULL; |
| | | |
| | | int i; |
| | | char * info_ptr = NULL; |
| | | |
| | | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION |
| | | if (info){ |
| | | info_ptr = SCPIDEFINE_strdup(&context->error_info_heap, info); |
| | | } |
| | | if (info) { |
| | | info_ptr = SCPIDEFINE_strdup(&context->error_info_heap, info); |
| | | } |
| | | #endif |
| | | |
| | | scpi_bool_t queue_overflow = !SCPI_ErrorAddInternal(context, err, info_ptr); |
| | | scpi_bool_t queue_overflow = !SCPI_ErrorAddInternal(context, err, info_ptr); |
| | | |
| | | 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); |
| | | } |
| | | } |
| | | 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 USE_DEVICE_DEPENDENT_ERROR_INFORMATION |
| | | SCPIDEFINE_free(&context->error_info_heap, info_ptr, true); |
| | | SCPI_ErrorEmit(context, err); |
| | | if (queue_overflow) { |
| | | SCPI_ErrorEmit(context, SCPI_ERROR_QUEUE_OVERFLOW); |
| | | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION |
| | | SCPIDEFINE_free(&context->error_info_heap, info_ptr, true); |
| | | #endif |
| | | } |
| | | } |
| | | |
| | | if (context) { |
| | | context->cmd_error = TRUE; |
| | | } |
| | | if (context) { |
| | | context->cmd_error = TRUE; |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param err - error number |
| | | */ |
| | | void SCPI_ErrorPush(scpi_t * context, int16_t err) { |
| | | SCPI_ErrorPushEx(context, err, NULL); |
| | | return; |
| | | SCPI_ErrorPushEx(context, err, NULL); |
| | | return; |
| | | } |
| | | |
| | | /** |
| | |
| | | #else |
| | | #define XE(def, val, str) |
| | | #endif |
| | | LIST_OF_ERRORS |
| | | LIST_OF_ERRORS |
| | | |
| | | #if USE_USER_ERROR_LIST |
| | | LIST_OF_USER_ERRORS |
| | | LIST_OF_USER_ERRORS |
| | | #endif |
| | | #undef X |
| | | #undef XE |
| | | default: return "Unknown error"; |
| | | default: return "Unknown error"; |
| | | } |
| | | } |
| | | |
| | |
| | | * 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: |
| | |
| | | * 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 |
| | |
| | | /** |
| | | * @file scpi_minimal.c |
| | | * @date Thu Nov 15 10:58:45 UTC 2012 |
| | | * |
| | | * |
| | | * @brief SCPI minimal implementation |
| | | * |
| | | * |
| | | * |
| | | * |
| | | */ |
| | | |
| | | |
| | |
| | | /** |
| | | * Command stub function |
| | | * @param context |
| | | * @return |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_Stub(scpi_t * context) { |
| | | (void) context; |
| | |
| | | /** |
| | | * Query command stub function |
| | | * @param context |
| | | * @return |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_StubQ(scpi_t * context) { |
| | | SCPI_ResultInt32(context, 0); |
| | |
| | | /** |
| | | * SYSTem:VERSion? |
| | | * @param context |
| | | * @return |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_SystemVersionQ(scpi_t * context) { |
| | | SCPI_ResultMnemonic(context, SCPI_STD_VERSION_REVISION); |
| | |
| | | /** |
| | | * SYSTem:ERRor[:NEXT]? |
| | | * @param context |
| | | * @return |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_SystemErrorNextQ(scpi_t * context) { |
| | | scpi_error_t error; |
| | | SCPI_ErrorPop(context, &error); |
| | | SCPI_ResultError(context, &error); |
| | | return SCPI_RES_OK; |
| | | scpi_error_t error; |
| | | SCPI_ErrorPop(context, &error); |
| | | SCPI_ResultError(context, &error); |
| | | return SCPI_RES_OK; |
| | | } |
| | | |
| | | /** |
| | | * SYSTem:ERRor:COUNt? |
| | | * @param context |
| | | * @return |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_SystemErrorCountQ(scpi_t * context) { |
| | | SCPI_ResultInt32(context, SCPI_ErrorCount(context)); |
| | |
| | | /** |
| | | * STATus:QUEStionable[:EVENt]? |
| | | * @param context |
| | | * @return |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_StatusQuestionableEventQ(scpi_t * context) { |
| | | /* return value */ |
| | |
| | | /** |
| | | * STATus:QUEStionable:ENABle? |
| | | * @param context |
| | | * @return |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_StatusQuestionableEnableQ(scpi_t * context) { |
| | | /* return value */ |
| | |
| | | /** |
| | | * STATus:QUEStionable:ENABle |
| | | * @param context |
| | | * @return |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_StatusQuestionableEnable(scpi_t * context) { |
| | | int32_t new_QUESE; |
| | |
| | | /** |
| | | * STATus:PRESet |
| | | * @param context |
| | | * @return |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_StatusPreset(scpi_t * context) { |
| | | /* clear STATUS:... */ |
| | |
| | | result &= processCommand(context); |
| | | cmd_prev = state->programHeader; |
| | | } else { |
| | | /* test */ |
| | | /* place undefined header with error */ |
| | | data[r?(r-1):r]=0; |
| | | SCPI_ErrorPushEx(context, SCPI_ERROR_UNDEFINED_HEADER, data); |
| | | //SCPI_ErrorPush(context, SCPI_ERROR_UNDEFINED_HEADER); |
| | | /* test */ |
| | | /* place undefined header with error */ |
| | | data[r ? (r - 1) : r] = 0; |
| | | SCPI_ErrorPushEx(context, SCPI_ERROR_UNDEFINED_HEADER, data); |
| | | //SCPI_ErrorPush(context, SCPI_ERROR_UNDEFINED_HEADER); |
| | | result = FALSE; |
| | | } |
| | | } |
| | |
| | | * @param buffer |
| | | * @param interface |
| | | */ |
| | | void SCPI_Init(scpi_t * context, |
| | | void SCPI_Init(scpi_t * context, |
| | | const scpi_command_t * commands, |
| | | scpi_interface_t * interface, |
| | | const scpi_unit_def_t * units, |
| | | const char * idn1, const char * idn2, const char * idn3, const char * idn4, |
| | | char * input_buffer, size_t input_buffer_length, |
| | | char * input_buffer, size_t input_buffer_length, |
| | | scpi_error_t * error_queue_data, int16_t error_queue_size, |
| | | char * error_info_heap, size_t error_info_heap_length) { |
| | | memset(context, 0, sizeof(*context)); |
| | | char * error_info_heap, size_t error_info_heap_length) { |
| | | memset(context, 0, sizeof (*context)); |
| | | context->cmdlist = commands; |
| | | context->interface = interface; |
| | | context->units = units; |
| | |
| | | context->buffer.data = input_buffer; |
| | | context->buffer.length = input_buffer_length; |
| | | context->buffer.position = 0; |
| | | context->error_info_heap.data = error_info_heap; |
| | | 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); |
| | | context->error_info_heap.data = error_info_heap; |
| | | 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); |
| | | } |
| | | |
| | |
| | | return result; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * SCPI-99:21.8 Device-dependent error information. |
| | | * Write error information with the following syntax: |
| | |
| | | * @return |
| | | */ |
| | | size_t SCPI_ResultError(scpi_t * context, scpi_error_t * error) { |
| | | size_t result = 0; |
| | | size_t outputlimit = SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH; |
| | | size_t step = 0; |
| | | const char * quote; |
| | | size_t result = 0; |
| | | size_t outputlimit = SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH; |
| | | size_t step = 0; |
| | | const char * quote; |
| | | |
| | | 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]); |
| | | |
| | | 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; |
| | | data[1] = error->device_dependent_info; |
| | | #if USE_MEMORY_ALLOCATION_FREE |
| | | len[1] = error->device_dependent_info ? strlen(data[1]) : 0; |
| | | len[1] = error->device_dependent_info ? strlen(data[1]) : 0; |
| | | #else |
| | | SCPIDEFINE_get_parts(&context->error_info_heap, data[1], &len[1], &data[2], &len[2]); |
| | | SCPIDEFINE_get_parts(&context->error_info_heap, data[1], &len[1], &data[2], &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 < SCPIDEFINE_DESCRIPTION_MAX_PARTS); 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 |
| | | SCPIDEFINE_free(&context->error_info_heap, error->device_dependent_info, false); |
| | | #endif |
| | | |
| | | return result; |
| | | result += SCPI_ResultInt32(context, error->error_code); |
| | | result += writeDelimiter(context); |
| | | result += writeData(context, "\"", 1); |
| | | |
| | | for (size_t i = 0; data[i] && outputlimit && (i < SCPIDEFINE_DESCRIPTION_MAX_PARTS); 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 |
| | | SCPIDEFINE_free(&context->error_info_heap, error->device_dependent_info, false); |
| | | #endif |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | |
| | | case 8: |
| | | x = 0x8000000000000000ULL; |
| | | break; |
| | | default: |
| | | default: |
| | | case 10: |
| | | x = 10000000000000000000ULL; |
| | | base = 10; |
| | |
| | | #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 |
| | |
| | | * @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(!s || !heap) { |
| | | return NULL; |
| | | } |
| | | if (!s || !heap) { |
| | | return NULL; |
| | | } |
| | | |
| | | if(heap->data[heap->wr]!='\0'){ |
| | | return NULL; |
| | | } |
| | | |
| | | if( *s == '\0' ){ |
| | | return NULL; |
| | | } |
| | | |
| | | size_t len=strlen(s) + 1; // additional '\0' at end |
| | | if( len > heap->count ) { |
| | | return NULL; |
| | | } |
| | | 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; |
| | | if (heap->data[heap->wr] != '\0') { |
| | | return NULL; |
| | | } |
| | | |
| | | if (*s == '\0') { |
| | | return NULL; |
| | | } |
| | | |
| | | size_t len = strlen(s) + 1; // additional '\0' at end |
| | | if (len > heap->count) { |
| | | return NULL; |
| | | } |
| | | 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 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 (!heap || !s || !len1 || !s2 || !len2) { |
| | | return FALSE; |
| | | } |
| | | |
| | | if(&s[*len1-1] == &heap->data[heap->size-1]){ |
| | | *s2 = heap->data; |
| | | *len2 = strnlen(*s2, heap->size); |
| | | }else{ |
| | | *s2 = NULL; |
| | | *len2 = 0; |
| | | } |
| | | return TRUE; |
| | | 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; |
| | | } |
| | | |
| | | /** |
| | |
| | | * @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; |
| | | |
| | | 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( heap->count == heap->size){ |
| | | heap->wr = 0; |
| | | return; |
| | | } |
| | | if(rollback){ |
| | | size_t rb = len[0] + len[1]; |
| | | if( rb > heap->wr){ |
| | | heap->wr += heap->size; |
| | | } |
| | | heap->wr -= rb; |
| | | } |
| | | |
| | | if (!s) return; |
| | | |
| | | char * data_add; |
| | | size_t len[2]; |
| | | |
| | | if (!OUR_get_parts(heap, s, &len[0], &data_add, &len[1])) return; |
| | | |
| | | 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 (heap->count == heap->size) { |
| | | heap->wr = 0; |
| | | return; |
| | | } |
| | | if (rollback) { |
| | | size_t rb = len[0] + len[1]; |
| | | if (rb > heap->wr) { |
| | | heap->wr += heap->size; |
| | | } |
| | | heap->wr -= rb; |
| | | } |
| | | } |
| | | |
| | | #endif |
| | |
| | | buf[--w2] = (int) ((fj + .03) * 10) + '0'; |
| | | r2++; |
| | | } |
| | | while (w2 < (int)bufsize) buf[w1++] = buf[w2++]; |
| | | while (w2 < (int) bufsize) buf[w1++] = buf[w2++]; |
| | | } else if (arg > 0) { |
| | | while ((fj = arg * 10) < 1) { |
| | | arg = fj; |
| | |
| | | buf[0] = '\0'; |
| | | return buf; |
| | | } |
| | | while (w1 <= w2 && w1 < (int)bufsize) { |
| | | while (w1 <= w2 && w1 < (int) bufsize) { |
| | | arg *= 10; |
| | | arg = modf(arg, &fj); |
| | | buf[w1++] = (int) fj + '0'; |
| | | } |
| | | if (w2 >= (int)bufsize) { |
| | | if (w2 >= (int) bufsize) { |
| | | buf[bufsize - 1] = '\0'; |
| | | return buf; |
| | | } |
| | |
| | | |
| | | /** |
| | | * Get native CPU endiannes |
| | | * @return |
| | | * @return |
| | | */ |
| | | scpi_array_format_t SCPI_GetNativeFormat(void) { |
| | | |
| | | union { |
| | | uint32_t i; |
| | | char c[4]; |
| | |
| | | /** |
| | | * Swap 16bit number |
| | | * @param val |
| | | * @return |
| | | * @return |
| | | */ |
| | | uint16_t SCPI_Swap16(uint16_t val) { |
| | | return ((val & 0x00FF) << 8) | |
| | | return ((val & 0x00FF) << 8) | |
| | | ((val & 0xFF00) >> 8); |
| | | } |
| | | |
| | | /** |
| | | * Swap 32bit number |
| | | * @param val |
| | | * @return |
| | | * @return |
| | | */ |
| | | uint32_t SCPI_Swap32(uint32_t val) { |
| | | return ((val & 0x000000FF) << 24) | |
| | |
| | | /** |
| | | * Swap 64bit number |
| | | * @param val |
| | | * @return |
| | | * @return |
| | | */ |
| | | uint64_t SCPI_Swap64(uint64_t val) { |
| | | return ((val & 0x00000000000000FFul) << 56) | |