📄 trio.c.svn-base
字号:
* 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 */#if TRIO_C99# define QUALIFIER_SIZE_T 'z'# define QUALIFIER_PTRDIFF_T 't'# define QUALIFIER_INTMAX_T 'j'#endif#if TRIO_BSD || TRIO_GNU# define QUALIFIER_QUAD 'q'#endif#if TRIO_GNU# define QUALIFIER_SIZE_T_UPPER 'Z'#endif#if TRIO_MISC# define QUALIFIER_WIDECHAR 'w'#endif#if TRIO_MICROSOFT# define QUALIFIER_FIXED_SIZE 'I'#endif#if TRIO_EXTENSION# define QUALIFIER_QUOTE '\''# define QUALIFIER_STICKY '!'# define QUALIFIER_VARSIZE '&' /* This should remain undocumented */# define QUALIFIER_PARAM '@' /* Experimental */# define QUALIFIER_COLON ':' /* For scanlists */# define QUALIFIER_EQUAL '=' /* For scanlists */# define QUALIFIER_ROUNDING_UPPER 'R'#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_WIDECHAR trio_wchar_t *wstring;#endif trio_pointer_t pointer; union { trio_intmax_t as_signed; trio_uintmax_t as_unsigned; } number; double doubleNumber; double *doublePointer; trio_long_double_t longdoubleNumber; trio_long_double_t *longdoublePointer; int errorNumber; } data; /* For the user-defined specifier */ char user_name[MAX_USER_NAME]; char user_data[MAX_USER_DATA];} 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;/* 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;/************************************************************************* * * Internal Variables * *************************************************************************/static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.11 2003/04/03 15:28:27 veillard Exp $";/* * 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;#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 (.)" */static int internalDecimalPointLength = 1;static int internalThousandSeparatorLength = 1;static char internalDecimalPoint = '.';static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ".";static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ",";static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING };static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz";static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";static 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#if TRIO_EXTENSIONstatic 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_MINIMAL)# define TRIO_STRING_PUBLIC static# include "triostr.c"#endif /* defined(TRIO_MINIMAL) *//************************************************************************* * 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_LONG_UPPER: case QUALIFIER_CIRCUMFLEX:#if defined(QUALIFIER_SIZE_T) case QUALIFIER_SIZE_T:#endif#if defined(QUALIFIER_PTRDIFF_T) case QUALIFIER_PTRDIFF_T:#endif#if defined(QUALIFIER_INTMAX_T) case QUALIFIER_INTMAX_T:#endif#if defined(QUALIFIER_QUAD) case QUALIFIER_QUAD:#endif#if defined(QUALIFIER_SIZE_T_UPPER) case QUALIFIER_SIZE_T_UPPER:#endif#if defined(QUALIFIER_WIDECHAR) case QUALIFIER_WIDECHAR:#endif#if defined(QUALIFIER_QUOTE) case QUALIFIER_QUOTE:#endif#if defined(QUALIFIER_STICKY) case QUALIFIER_STICKY:#endif#if defined(QUALIFIER_VARSIZE) case QUALIFIER_VARSIZE:#endif#if defined(QUALIFIER_PARAM) case QUALIFIER_PARAM:#endif#if defined(QUALIFIER_FIXED_SIZE) case QUALIFIER_FIXED_SIZE:#endif#if defined(QUALIFIER_ROUNDING_UPPER) case QUALIFIER_ROUNDING_UPPER:#endif 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 ((internalLocaleValues->thousands_sep) && (internalLocaleValues->thousands_sep[0] != NIL)) { trio_copy_max(internalThousandSeparator, sizeof(internalThousandSeparator), internalLocaleValues->thousands_sep); internalThousandSeparatorLength = trio_length(internalThousandSeparator); } if ((internalLocaleValues->grouping) && (internalLocaleValues->grouping[0] != NIL)) { trio_copy_max(internalGrouping, sizeof(internalGrouping), internalLocaleValues->grouping); } }}#endif /* defined(USE_LOCALE) */TRIO_PRIVATE intTrioCalcThousandSeparatorLengthTRIO_ARGS1((digits), int digits){#if TRIO_EXTENSION 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;#else return 0;#endif}TRIO_PRIVATE BOOLEAN_TTrioFollowedBySeparatorTRIO_ARGS1((position), int position){#if TRIO_EXTENSION int step = 0; char *groupingPointer = internalGrouping; position--; if (position == 0) return FALSE; while (position > 0) { if (*groupingPointer == CHAR_MAX) { /* Disable grouping */ break; /* while */ } else if (*groupingPointer != 0) { step = *groupingPointer++; } if (step == 0) break; position -= step; } return (position == 0);#else return FALSE;#endif}/************************************************************************* * TrioGetPosition * * Get the %n$ position. */TRIO_PRIVATE intTrioGetPositionTRIO_ARGS2((format, indexPointer), TRIO_CONST char *format, int *indexPointer){#if TRIO_UNIX98 char *tmpformat; int number = 0; int index = *indexPointer; number = (int)trio_to_long(&format[index], &tmpformat, BASE_DECIMAL); index = (int)(tmpformat - format); if ((number != 0) && (QUALIFIER_POSITION == format[index++])) { *indexPointer = index; /* * number is decreased by 1, because n$ starts from 1, whereas * the array it is indexing starts from 0. */ return number - 1; }#endif return NO_POSITION;}#if TRIO_EXTENSION/************************************************************************* * TrioFindNamespace * * Find registered user-defined specifier. * The prev argument is used for optimization only. */TRIO_PRIVATE trio_userdef_t *TrioFindNamespaceTRIO_ARGS2((name, prev), TRIO_CONST char *name, trio_userdef_t **prev){ trio_userdef_t *def; if (internalEnterCriticalRegion) (void)internalEnterCriticalRegion(NULL); for (def = internalUserDef; def; def = def->next) { /* Case-sensitive string comparison */ if (trio_equal_case(def->name, name)) break; if (prev) *prev = def; } if (internalLeaveCriticalRegion) (void)internalLeaveCriticalRegion(NULL); return def;}#endif/************************************************************************* * TrioPower * * Description: * Calculate pow(base, exponent), where number and exponent are integers. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -