#ifndef GPIB_PARSER_NUMUTILS_H #define GPIB_PARSER_NUMUTILS_H #include // isalpha, isdigit #include // ptrdiff_t #include // NULL #include // size_t #include "gpib_parser_casts.h" #include "gpib_parser_chars.h" // Service characters definitions #include "gpib_parser_validators_numbers.h" // String check mode for GPIB_StrChkFormat() typedef enum { eSCM_DEC, // Check mode: for demical number eSCM_HEX, // Check mode: for hexademical number eSCM_FLOAT, // Check mode: for float number eSCM_BIN, // Check mode: for binary number eSCM_OCT, // Check mode: for octal number eSCM_EXP, // Check mode: for exponential number eSCM_MNEMONIC, // Check mode: for mnemonic parameter eSCM_DIGIT // Check mode: for demical digits } eStringCheckMode_t; //----------------------------------------------------------------------------- // sFormatDouble2Str_t: // Compound Literal structure for GPIB_Double2Str() typedef union { uint32_t format; struct { uint32_t nLeadDigits : 8; uint32_t nFracDigits : 8; uint32_t bSciFormat : 1; uint32_t reserved :15; }; } sFormatDouble2Str_t; //----------------------------------------------------------------------------- // sFormatInt2Str_t: // Compound Literal structure for GPIB_Integer2Str() typedef union { uint32_t format; struct { uint32_t nLeadDigits : 4; uint32_t reserved :28; }; } sFormatInt2Str_t; #define Format_Float2Str_NdotN ((sFormatDouble2Str_t){ .bSciFormat = 0, .nLeadDigits = 0, .nFracDigits = 0 }).format #define Format_Float2Str_Ndot3 ((sFormatDouble2Str_t){ .bSciFormat = 0, .nLeadDigits = 0, .nFracDigits = 3 }).format #define Format_Float2Str_2dot3 ((sFormatDouble2Str_t){ .bSciFormat = 0, .nLeadDigits = 2, .nFracDigits = 3 }).format #define Format_Float2Str_Sci ((sFormatDouble2Str_t){ .bSciFormat = 1, .nLeadDigits = 0, .nFracDigits = 0 }).format #define Format_Double2Str_NdotN ((sFormatDouble2Str_t){ .bSciFormat = 0, .nLeadDigits = 0, .nFracDigits = 0 }).format #define Format_Double2Str_Ndot3 ((sFormatDouble2Str_t){ .bSciFormat = 0, .nLeadDigits = 0, .nFracDigits = 3 }).format #define Format_Double2Str_2dot3 ((sFormatDouble2Str_t){ .bSciFormat = 0, .nLeadDigits = 2, .nFracDigits = 3 }).format #define Format_Double2Str_Sci ((sFormatDouble2Str_t){ .bSciFormat = 1, .nLeadDigits = 0, .nFracDigits = 0 }).format #define Format_Int2Str_N ( (sFormatInt2Str_t) { .nLeadDigits = 0 }).format #define Format_Int2Str_10N ( (sFormatInt2Str_t) { .nLeadDigits = 10 }).format size_t GPIB_Float2Str( float value, char * strBuf, size_t strBufSize, uint32_t compound_format ); size_t GPIB_Double2Str( double value, char * strBuf, size_t strBufSize, uint32_t compound_format ); size_t GPIB_Integer2Str( int32_t value, char * strBuf, size_t strBufSize, uint32_t compound_format ); //----------------------------------------------------------------------------- // GPIB_NUMBER_NSYSPREFIX_SIZE: // Numeric string-prefix length in bytes: // e.g. For '#HDEADBEED' the prefix '#H' specifies the hexademical numeric system. // There are three types of numeric systems: binary (#B), octal(#O) and hexademical (#H). // The prefix length for all of them is 2. #define GPIB_NUMBER_NSYSPREFIX_SIZE (2) //----------------------------------------------------------------------------- // eGPIB_ParseNumbers_type_t: // Mode of GPIB_ParseNumbers() call. // Describes the @type parameter. typedef enum { USBTMC_PARSENUMBERS_TYPE_FLOAT, USBTMC_PARSENUMBERS_TYPE_INT, } eGPIB_ParseNumbers_type_t; //----------------------------------------------------------------------------- // ChooseLowestPtr: // Checks two pointers @ptr_a and @ptr_b and prefers the lowest in absolute addresses, // The function prefers non-NULL pointers, and returns NULL only if both @ptr_a and // @ptr_b are NULL. static inline void * ChooseLowestPtr( void * ptr_a, void * ptr_b ) { // First, check the @ptr_a for NULL // and prefer the other pointer, even if it's NULL too, // because there no choice is. if( NULL == ptr_a ) return ptr_b; else // Then, check the @ptr_b for NULL // and prefer the other pointer, even if it's NULL too, // because there no choice is. if( NULL == ptr_b ) return ptr_a; // Since @ptr_a and @ptr_b aren't NULL for sure, determine which of the // pointers is greater than the other in absolute values. ptrdiff_t diff = (ptrdiff_t)ptr_b - (ptrdiff_t)ptr_a; // @ptr_a is less if( diff > 0 ) // prefer @ptr_a return ptr_a; // Otherwise, prefer @ptr_b return ptr_b; /* #define GetMin(A,B) ((TOUINT(A)>TOUINT(B))?(B):(A)) */ /* #define GetMax(A,B) ((TOUINT(A) 0 ) // prefer @ptr_a return ptr_a; // Otherwise, prefer @ptr_b return ptr_b; /* #define GetMin(A,B) ((TOUINT(A)>TOUINT(B))?(B):(A)) */ /* #define GetMax(A,B) ((TOUINT(A)