📄 trio.c
字号:
# define CLASS_ALPHA "[:alpha:]"# define CLASS_BLANK "[:blank:]"# define CLASS_CNTRL "[:cntrl:]"# define CLASS_DIGIT "[:digit:]"# define CLASS_GRAPH "[:graph:]"# define CLASS_LOWER "[:lower:]"# define CLASS_PRINT "[:print:]"# define CLASS_PUNCT "[:punct:]"# define CLASS_SPACE "[:space:]"# define CLASS_UPPER "[:upper:]"# define CLASS_XDIGIT "[:xdigit:]"#endif/* * SPECIFIERS: * * * a Hex-float * A Hex-float * c Character * C Widechar character (wint_t) * d Decimal * e Float * E Float * F Float * F Float * g Float * G Float * i Integer * m Error message * n Count * o Octal * p Pointer * s String * S Widechar string (wchar_t *) * u Unsigned * x Hex * X Hex * [] Group * <> User-defined * * Reserved: * * D Binary Coded Decimal %D(length,precision) (OS/390) */#define SPECIFIER_CHAR 'c'#define SPECIFIER_STRING 's'#define SPECIFIER_DECIMAL 'd'#define SPECIFIER_INTEGER 'i'#define SPECIFIER_UNSIGNED 'u'#define SPECIFIER_OCTAL 'o'#define SPECIFIER_HEX 'x'#define SPECIFIER_HEX_UPPER 'X'#if TRIO_FEATURE_FLOAT# define SPECIFIER_FLOAT_E 'e'# define SPECIFIER_FLOAT_E_UPPER 'E'# define SPECIFIER_FLOAT_F 'f'# define SPECIFIER_FLOAT_F_UPPER 'F'# define SPECIFIER_FLOAT_G 'g'# define SPECIFIER_FLOAT_G_UPPER 'G'#endif#define SPECIFIER_POINTER 'p'#if TRIO_FEATURE_SCANF# define SPECIFIER_GROUP '['# define SPECIFIER_UNGROUP ']'#endif#define SPECIFIER_COUNT 'n'#if TRIO_UNIX98# define SPECIFIER_CHAR_UPPER 'C'# define SPECIFIER_STRING_UPPER 'S'#endif#define SPECIFIER_HEXFLOAT 'a'#define SPECIFIER_HEXFLOAT_UPPER 'A'#define SPECIFIER_ERRNO 'm'#if TRIO_FEATURE_BINARY# define SPECIFIER_BINARY 'b'# define SPECIFIER_BINARY_UPPER 'B'#endif#if TRIO_FEATURE_USER_DEFINED# define SPECIFIER_USER_DEFINED_BEGIN '<'# define SPECIFIER_USER_DEFINED_END '>'# define SPECIFIER_USER_DEFINED_SEPARATOR ':'#endif/* * QUALIFIERS: * * * Numbers = d,i,o,u,x,X * Float = a,A,e,E,f,F,g,G * String = s * Char = c * * * 9$ Position * Use the 9th parameter. 9 can be any number between 1 and * the maximal argument * * 9 Width * Set width to 9. 9 can be any number, but must not be postfixed * by '$' * * h Short * Numbers: * (unsigned) short int * * hh Short short * Numbers: * (unsigned) char * * l Long * Numbers: * (unsigned) long int * String: * as the S specifier * Char: * as the C specifier * * ll Long Long * Numbers: * (unsigned) long long int * * L Long Double * Float * long double * * # Alternative * Float: * Decimal-point is always present * String: * non-printable characters are handled as \number * * Spacing * * + Sign * * - Alignment * * . Precision * * * Parameter * print: use parameter * scan: no parameter (ignore) * * q Quad * * Z size_t * * w Widechar * * ' Thousands/quote * Numbers: * Integer part grouped in thousands * Binary numbers: * Number grouped in nibbles (4 bits) * String: * Quoted string * * j intmax_t * t prtdiff_t * z size_t * * ! Sticky * @ Parameter (for both print and scan) * * I n-bit Integer * Numbers: * The following options exists * I8 = 8-bit integer * I16 = 16-bit integer * I32 = 32-bit integer * I64 = 64-bit integer */#define QUALIFIER_POSITION '$'#define QUALIFIER_SHORT 'h'#define QUALIFIER_LONG 'l'#define QUALIFIER_LONG_UPPER 'L'#define QUALIFIER_ALTERNATIVE '#'#define QUALIFIER_SPACE ' '#define QUALIFIER_PLUS '+'#define QUALIFIER_MINUS '-'#define QUALIFIER_DOT '.'#define QUALIFIER_STAR '*'#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */#define QUALIFIER_SIZE_T 'z'#define QUALIFIER_PTRDIFF_T 't'#define QUALIFIER_INTMAX_T 'j'#define QUALIFIER_QUAD 'q'#define QUALIFIER_SIZE_T_UPPER 'Z'#if TRIO_MISC# define QUALIFIER_WIDECHAR 'w'#endif#define QUALIFIER_FIXED_SIZE 'I'#define QUALIFIER_QUOTE '\''#define QUALIFIER_STICKY '!'#define QUALIFIER_VARSIZE '&' /* This should remain undocumented */#define QUALIFIER_ROUNDING_UPPER 'R'#if TRIO_EXTENSION# define QUALIFIER_PARAM '@' /* Experimental */# define QUALIFIER_COLON ':' /* For scanlists */# define QUALIFIER_EQUAL '=' /* For scanlists */#endif/************************************************************************* * * Internal Structures * *************************************************************************//* Parameters */typedef struct { /* An indication of which entry in the data union is used */ int type; /* The flags */ trio_flags_t flags; /* The width qualifier */ int width; /* The precision qualifier */ int precision; /* The base qualifier */ int base; /* The size for the variable size qualifier */ int varsize; /* The marker of the end of the specifier */ int indexAfterSpecifier; /* The data from the argument list */ union { char *string;#if TRIO_FEATURE_WIDECHAR trio_wchar_t *wstring;#endif trio_pointer_t pointer; union { trio_intmax_t as_signed; trio_uintmax_t as_unsigned; } number;#if TRIO_FEATURE_FLOAT double doubleNumber; double *doublePointer; trio_long_double_t longdoubleNumber; trio_long_double_t *longdoublePointer;#endif int errorNumber; } data;#if TRIO_FEATURE_USER_DEFINED /* For the user-defined specifier */ char user_name[MAX_USER_NAME]; char user_data[MAX_USER_DATA];#endif} trio_parameter_t;/* Container for customized functions */typedef struct { union { trio_outstream_t out; trio_instream_t in; } stream; trio_pointer_t closure;} trio_custom_t;/* General trio "class" */typedef struct _trio_class_t { /* * The function to write characters to a stream. */ void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int)); /* * The function to read characters from a stream. */ void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *)); /* * The current location in the stream. */ trio_pointer_t location; /* * The character currently being processed. */ int current; /* * The number of characters that would have been written/read * if there had been sufficient space. */ int processed; /* * The number of characters that are actually written/read. * Processed and committed will only differ for the *nprintf * and *nscanf functions. */ int committed; /* * The upper limit of characters that may be written/read. */ int max; /* * The last output error that was detected. */ int error;} trio_class_t;/* References (for user-defined callbacks) */typedef struct _trio_reference_t { trio_class_t *data; trio_parameter_t *parameter;} trio_reference_t;#if TRIO_FEATURE_USER_DEFINED/* Registered entries (for user-defined callbacks) */typedef struct _trio_userdef_t { struct _trio_userdef_t *next; trio_callback_t callback; char *name;} trio_userdef_t;#endif/************************************************************************* * * Internal Variables * *************************************************************************/static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.95 2005/12/26 17:15:21 breese Exp $";#if TRIO_FEATURE_FLOAT/* * Need this to workaround a parser bug in HP C/iX compiler that fails * to resolves macro definitions that includes type 'long double', * e.g: va_arg(arg_ptr, long double) */# if defined(TRIO_PLATFORM_MPEIX)static TRIO_CONST trio_long_double_t ___dummy_long_double = 0;# endif#endifstatic TRIO_CONST char internalNullString[] = "(nil)";#if defined(USE_LOCALE)static struct lconv *internalLocaleValues = NULL;#endif/* * UNIX98 says "in a locale where the radix character is not defined, * the radix character defaults to a period (.)" */#if TRIO_FEATURE_FLOAT || TRIO_FEATURE_LOCALE || defined(USE_LOCALE)static int internalDecimalPointLength = 1;static char internalDecimalPoint = '.';static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ".";#endif#if TRIO_FEATURE_QUOTE || TRIO_FEATURE_LOCALE || TRIO_EXTENSIONstatic int internalThousandSeparatorLength = 1;static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ",";static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING };#endifstatic TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz";static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";#if TRIO_FEATURE_SCANFstatic BOOLEAN_T internalDigitsUnconverted = TRUE;static int internalDigitArray[128];# if TRIO_EXTENSIONstatic BOOLEAN_T internalCollationUnconverted = TRUE;static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS];# endif#endif#if TRIO_FEATURE_USER_DEFINEDstatic TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL;static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL;static trio_userdef_t *internalUserDef = NULL;#endif/************************************************************************* * * Internal Functions * ************************************************************************/#if defined(TRIO_EMBED_NAN)# include "trionan.c"#endif#if defined(TRIO_EMBED_STRING)# include "triostr.c"#endif/************************************************************************* * TrioIsQualifier * * Description: * Remember to add all new qualifiers to this function. * QUALIFIER_POSITION must not be added. */TRIO_PRIVATE BOOLEAN_TTrioIsQualifierTRIO_ARGS1((character), TRIO_CONST char character){ /* QUALIFIER_POSITION is not included */ switch (character) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case QUALIFIER_PLUS: case QUALIFIER_MINUS: case QUALIFIER_SPACE: case QUALIFIER_DOT: case QUALIFIER_STAR: case QUALIFIER_ALTERNATIVE: case QUALIFIER_SHORT: case QUALIFIER_LONG: case QUALIFIER_CIRCUMFLEX: case QUALIFIER_LONG_UPPER: case QUALIFIER_SIZE_T: case QUALIFIER_PTRDIFF_T: case QUALIFIER_INTMAX_T: case QUALIFIER_QUAD: case QUALIFIER_SIZE_T_UPPER:#if defined(QUALIFIER_WIDECHAR) case QUALIFIER_WIDECHAR:#endif case QUALIFIER_QUOTE: case QUALIFIER_STICKY: case QUALIFIER_VARSIZE:#if defined(QUALIFIER_PARAM) case QUALIFIER_PARAM:#endif case QUALIFIER_FIXED_SIZE: case QUALIFIER_ROUNDING_UPPER: return TRUE; default: return FALSE; }}/************************************************************************* * TrioSetLocale */#if defined(USE_LOCALE)TRIO_PRIVATE voidTrioSetLocale(TRIO_NOARGS){ internalLocaleValues = (struct lconv *)localeconv(); if (internalLocaleValues) { if ((internalLocaleValues->decimal_point) && (internalLocaleValues->decimal_point[0] != NIL)) { internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point); if (internalDecimalPointLength == 1) { internalDecimalPoint = internalLocaleValues->decimal_point[0]; } else { internalDecimalPoint = NIL; trio_copy_max(internalDecimalPointString, sizeof(internalDecimalPointString), internalLocaleValues->decimal_point); } }# if TRIO_EXTENSION if ((internalLocaleValues->thousands_sep) && (internalLocaleValues->thousands_sep[0] != NIL)) { trio_copy_max(internalThousandSeparator, sizeof(internalThousandSeparator), internalLocaleValues->thousands_sep); internalThousandSeparatorLength = trio_length(internalThousandSeparator); }# endif# if TRIO_EXTENSION if ((internalLocaleValues->grouping) && (internalLocaleValues->grouping[0] != NIL)) { trio_copy_max(internalGrouping, sizeof(internalGrouping), internalLocaleValues->grouping); }# endif }}#endif /* defined(USE_LOCALE) */#if TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTETRIO_PRIVATE intTrioCalcThousandSeparatorLengthTRIO_ARGS1((digits), int digits){ int count = 0; int step = NO_GROUPING; char *groupingPointer = internalGrouping; while (digits > 0) { if (*groupingPointer == CHAR_MAX) { /* Disable grouping */ break; /* while */ } else if (*groupingPointer == 0) { /* Repeat last group */ if (step == NO_GROUPING) { /* Error in locale */ break; /* while */ } } else { step = *groupingPointer++; } if (digits > step) count += internalThousandSeparatorLength; digits -= step; } return count;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -