| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- #ifndef GPIB_PARSER_NUMUTILS_H
- #define GPIB_PARSER_NUMUTILS_H
- #include <ctype.h> // isalpha, isdigit
- #include <stddef.h> // ptrdiff_t
- #include <string.h> // NULL
- #include <stdint.h> // 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)<TOUINT(B))?(B):(A)) */
- /* #define GetNearPointer(P1,P2) ((P1!=NULL && P2!=NULL)?GetMin(P1,P2):((P1!=NULL)?P1:P2)) */
- }
-
- // ChooseLowestPtrConst:
- // 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 const void * ChooseLowestPtrConst( const void * ptr_a, const 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)<TOUINT(B))?(B):(A)) */
- /* #define GetNearPointer(P1,P2) ((P1!=NULL && P2!=NULL)?GetMin(P1,P2):((P1!=NULL)?P1:P2)) */
- }
- // ----------------------------------------------------------------------------
-
- // SubPointers:
- // Substracts the @ptr_sub from the @ptr_src pointer and returns the difference.
- static inline ptrdiff_t SubPointers( const void * ptr_src, const void * ptr_sub )
- {
- ptrdiff_t diff = (ptrdiff_t)ptr_src - (ptrdiff_t)ptr_sub;
-
- return diff;
- /* #define SubPointers(P1,P2) TOUINT((TOUINT(TOPCHAR(P1))-TOUINT(TOPCHAR(P2)))) */
- }
- // ----------------------------------------------------------------------------
-
- // DecCharToNum:
- // Converts a demical charater into the number
- static inline int DecCharToNum( const char ch )
- {
- // In case the given @ch isn't numeric character return zero
- return ( IsDemicalChar(ch) ? (int)ch - '0' : 0 );
-
- /* #define CharToDec(character) ((IsDEC(character))?(int)character-'0':0);*/
- }
-
- #define BinCharToNum(ch) (DecCharToNum(ch)) // binary system: convert the character into the demical number
- #define OctCharToNum(ch) (DecCharToNum(ch)) // octal system: convert the character into the demical number
- // ----------------------------------------------------------------------------
-
- // HexCharToNum:
- // Converts a hexademical charater into the number
- static inline int HexCharToNum( const char ch )
- {
- // In case the given @ch isn't numeric character return zero
- return ( IsHexademicalChar(ch) ? (int)(tolower(ch) - 'a') + 10 : 0 );
-
- /* #define CharHexToDec( character ) ( ( IsDemicalChar (character) )? ((character)-'0'): ( ( IsHexademicalChar(character))? ((character)-'A'+0x0A): 0 ) ) */
- }
-
- // ----------------------------------------------------------------------------
-
- // HexCharToNumber:
- // Converts a hex-literal character into the number
- static inline int HexCharToNumber( const char ch )
- {
- return ( IsDemicalChar(ch) ? DecCharToNum(ch) : HexCharToNum(ch) );
-
- /* #define CharHexToDec( character ) ( ( IsDemicalChar (character) )? ((character)-'0'): ( ( IsHexademicalChar(character))? ((character)-'A'+0x0A): 0 ) ) */
- }
-
- // ----------------------------------------------------------------------------
-
- // IsBinarySystem:
- // Parses the number's string prefix and detects if it relates to a binary numeric system
- // Prefix is "#B", e.g. "#B1000"
- static inline BOOL IsBinarySystem( const char * prefix )
- {
- return MAKE_BOOL(
- GPIB_CHAR_NMBSYSTEM_SIGN == prefix[0] // First character: is a numeric system prefix character
- && 'b' == tolower(prefix[1]) // Second character: 'b' or 'B'
- );
- /* #define IsBinSystem( string ) ( (*(string)=='#' && ( (*(string+1) & 0xDF)=='B' ))?TRUE:FALSE ) */
- }
-
- // ----------------------------------------------------------------------------
-
- // IsHexademicalSystem:
- // Parses the number's string prefix and detects if it relates to a hexademical numeric system
- // Prefix is "#H", e.g. "#HA41C"
- static inline BOOL IsHexademicalSystem( const char * prefix )
- {
- return MAKE_BOOL(
- GPIB_CHAR_NMBSYSTEM_SIGN == prefix[0] // First character: is a numeric system prefix character
- && 'h' == tolower(prefix[1]) // Second character: 'h' or 'H'
- );
- /* #define IsHexSystem( string ) ( (*(string)=='#' && ( (*(string+1) & 0xDF)=='H' ))?TRUE:FALSE ) */
- }
-
- // ----------------------------------------------------------------------------
-
- // IsOctalSystem:
- // Parses the number's string prefix and detects if it relates to an octal numeric system
- // Prefix is "#O" or "#Q", e.g. "#O606", "#Q606"
- static inline BOOL IsOctalSystem( const char * prefix )
- {
- return MAKE_BOOL(
- GPIB_CHAR_NMBSYSTEM_SIGN == prefix[0] // First character: is a numeric system prefix character
- && ( 'o' == tolower(prefix[1]) // Second character: 'o' or 'O'
- || 'q' == tolower(prefix[1]) // Second character: 'q' or 'Q'
- )
- );
- /* #define IsOctSystem( string ) ( (*(string)=='#' && ( (*(string+1) & 0xDF)=='O' ))?TRUE:FALSE ) */
- }
-
- // ----------------------------------------------------------------------------
-
- // IsNumericSystem:
- // Checks if the given @prefix relates to a numeric system: hexademical, octal or binary.
- static inline BOOL IsNumericSystem( const char * prefix )
- {
- return MAKE_BOOL( IsHexademicalSystem(prefix) // Check first for hexademical
- || IsBinarySystem(prefix) // Next check for binary
- || IsOctalSystem(prefix) ); // At last check for octal
-
- /* #define IsNumericSystem( string ) ( ( IsOctalSystem( string ) || IsHexademicalSystem( string ) || IsBinarySystem( string ))?TRUE:FALSE ) */
- }
-
- // ----------------------------------------------------------------------------
-
- // GetNumericSystemBase:
- // Returns a number system base if any system detected based on @prefix
- static inline int GetNumericSystemBase( const char * prefix )
- {
- if( IsHexademicalSystem( prefix ) )
- return 16;
-
- if( IsOctalSystem( prefix ) )
- return 8;
-
- if( IsBinarySystem( prefix ) )
- return 2;
-
- return 0;
-
- /*#define GetNumericSystem( string ) ( (IsNumericSystem(string))?( (IsBinarySystem( string ))?2:( (IsOctalSystem( string ))?8:( (IsHexademicalSystem( string ))?16:(0) ) ) ):0)*/
- }
-
- /* protos */
- BOOL ConvertNumerationSystem( const char * str, int nsys, uint32_t * pResult, const char * * ppEnd ); // "gpib_parser_numutils.c"
- int GPIB_ParseNumbers( const char * str, eGPIB_ParseNumbers_type_t type, size_t count, int * , ... ); // "gpib_parser_numutils.c"
- #endif
|