📄 trio.c.svn-base
字号:
/************************************************************************* * * $Id: trio.c,v 1.11 2003/04/03 15:28:27 veillard Exp $ * * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * ************************************************************************* * * A note to trio contributors: * * Avoid heap allocation at all costs to ensure that the trio functions * are async-safe. The exceptions are the printf/fprintf functions, which * uses fputc, and the asprintf functions and the <alloc> modifier, which * by design are required to allocate form the heap. * ************************************************************************//* * TODO: * - Scan is probably too permissive about its modifiers. * - C escapes in %#[] ? * - Multibyte characters (done for format parsing, except scan groups) * - Complex numbers? (C99 _Complex) * - Boolean values? (C99 _Bool) * - C99 NaN(n-char-sequence) missing. The n-char-sequence can be used * to print the mantissa, e.g. NaN(0xc000000000000000) * - Should we support the GNU %a alloc modifier? GNU has an ugly hack * for %a, because C99 used %a for other purposes. If specified as * %as or %a[ it is interpreted as the alloc modifier, otherwise as * the C99 hex-float. This means that you cannot scan %as as a hex-float * immediately followed by an 's'. * - Scanning of collating symbols. *//************************************************************************* * Trio include files */#include "wincecompat.h"#include "triodef.h"#include "trio.h"#include "triop.h"#include "trionan.h"#if !defined(TRIO_MINIMAL)# include "triostr.h"#endif/************************************************************************** * * Definitions * *************************************************************************/#include <math.h>#include <limits.h>#include <float.h>#if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_WIDECHAR# define TRIO_COMPILER_SUPPORTS_MULTIBYTE# if !defined(MB_LEN_MAX)# define MB_LEN_MAX 6# endif#endif#if (defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= 1100)) || defined(TRIO_COMPILER_BCB)# define TRIO_COMPILER_SUPPORTS_MSVC_INT#endif/************************************************************************* * Generic definitions */#if !(defined(DEBUG) || defined(NDEBUG))# define NDEBUG#endif#include <assert.h>#include <ctype.h>#if !defined(TRIO_COMPILER_SUPPORTS_C99)# define isblank(x) (((x)==32) || ((x)==9))#endif#if defined(TRIO_COMPILER_ANCIENT)# include <varargs.h>#else# include <stdarg.h>#endif#include <stddef.h>//#include <errno.h>#ifndef NULL# define NULL 0#endif#define NIL ((char)0)#ifndef FALSE# define FALSE (1 == 0)# define TRUE (! FALSE)#endif#define BOOLEAN_T int/* mincore() can be used for debugging purposes */#define VALID(x) (NULL != (x))#if TRIO_ERRORS /* * Encode the error code and the position. This is decoded * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION. */# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8)))#else# define TRIO_ERROR_RETURN(x,y) (-1)#endiftypedef unsigned long trio_flags_t;/************************************************************************* * Platform specific definitions */#if defined(TRIO_PLATFORM_UNIX)# include <unistd.h># include <signal.h># include <locale.h># define USE_LOCALE#endif /* TRIO_PLATFORM_UNIX */#if defined(TRIO_PLATFORM_VMS)# include <unistd.h>#endif#if defined(TRIO_PLATFORM_WIN32)//# include <io.h>//# define read _read//# define write _write#endif /* TRIO_PLATFORM_WIN32 */#if TRIO_WIDECHAR# if defined(TRIO_COMPILER_SUPPORTS_ISO94)# include <wchar.h># include <wctype.h>typedef wchar_t trio_wchar_t;typedef wint_t trio_wint_t;# elsetypedef char trio_wchar_t;typedef int trio_wint_t;# define WCONST(x) L ## x# define WEOF EOF# define iswalnum(x) isalnum(x)# define iswalpha(x) isalpha(x)# define iswblank(x) isblank(x)# define iswcntrl(x) iscntrl(x)# define iswdigit(x) isdigit(x)# define iswgraph(x) isgraph(x)# define iswlower(x) islower(x)# define iswprint(x) isprint(x)# define iswpunct(x) ispunct(x)# define iswspace(x) isspace(x)# define iswupper(x) isupper(x)# define iswxdigit(x) isxdigit(x)# endif#endif/************************************************************************* * Compiler dependent definitions *//* Support for long long */#ifndef __cplusplus# if !defined(USE_LONGLONG)# if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__)# define USE_LONGLONG# elif defined(TRIO_COMPILER_SUNPRO)# define USE_LONGLONG# elif defined(_LONG_LONG) || defined(_LONGLONG)# define USE_LONGLONG# endif# endif#endif/* The extra long numbers */#if defined(USE_LONGLONG)typedef signed long long int trio_longlong_t;typedef unsigned long long int trio_ulonglong_t;#elif defined(TRIO_COMPILER_SUPPORTS_MSVC_INT)typedef signed __int64 trio_longlong_t;typedef unsigned __int64 trio_ulonglong_t;#elsetypedef TRIO_SIGNED long int trio_longlong_t;typedef unsigned long int trio_ulonglong_t;#endif/* Maximal and fixed integer types */#if defined(TRIO_COMPILER_SUPPORTS_C99)# include <stdint.h>typedef intmax_t trio_intmax_t;typedef uintmax_t trio_uintmax_t;typedef int8_t trio_int8_t;typedef int16_t trio_int16_t;typedef int32_t trio_int32_t;typedef int64_t trio_int64_t;#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98)# include <inttypes.h>typedef intmax_t trio_intmax_t;typedef uintmax_t trio_uintmax_t;typedef int8_t trio_int8_t;typedef int16_t trio_int16_t;typedef int32_t trio_int32_t;typedef int64_t trio_int64_t;#elif defined(TRIO_COMPILER_SUPPORTS_MSVC_INT)typedef trio_longlong_t trio_intmax_t;typedef trio_ulonglong_t trio_uintmax_t;typedef __int8 trio_int8_t;typedef __int16 trio_int16_t;typedef __int32 trio_int32_t;typedef __int64 trio_int64_t;#elsetypedef trio_longlong_t trio_intmax_t;typedef trio_ulonglong_t trio_uintmax_t;# if defined(TRIO_INT8_T)typedef TRIO_INT8_T trio_int8_t;# elsetypedef TRIO_SIGNED char trio_int8_t;# endif# if defined(TRIO_INT16_T)typedef TRIO_INT16_T trio_int16_t;# elsetypedef TRIO_SIGNED short trio_int16_t;# endif# if defined(TRIO_INT32_T)typedef TRIO_INT32_T trio_int32_t;# elsetypedef TRIO_SIGNED int trio_int32_t;# endif# if defined(TRIO_INT64_T)typedef TRIO_INT64_T trio_int64_t;# elsetypedef trio_longlong_t trio_int64_t;# endif#endif#if !(defined(TRIO_COMPILER_SUPPORTS_C99) \ || defined(TRIO_COMPILER_SUPPORTS_UNIX01))# define floorl(x) floor((double)(x))# define fmodl(x,y) fmod((double)(x),(double)(y))# define powl(x,y) pow((double)(x),(double)(y))#endif#define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x))/************************************************************************* * Internal Definitions */#ifndef DECIMAL_DIG# define DECIMAL_DIG DBL_DIG#endif/* Long double sizes */#ifdef LDBL_DIG# define MAX_MANTISSA_DIGITS LDBL_DIG# define MAX_EXPONENT_DIGITS 4# define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP#else# define MAX_MANTISSA_DIGITS DECIMAL_DIG# define MAX_EXPONENT_DIGITS 3# define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP#endif#if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG)# undef LDBL_DIG# undef LDBL_MANT_DIG# undef LDBL_EPSILON# define LDBL_DIG DBL_DIG# define LDBL_MANT_DIG DBL_MANT_DIG# define LDBL_EPSILON DBL_EPSILON#endif/* The maximal number of digits is for base 2 */#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT)/* The width of a pointer. The number of bits in a hex digit is 4 */#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4)/* Infinite and Not-A-Number for floating-point */#define INFINITE_LOWER "inf"#define INFINITE_UPPER "INF"#define LONG_INFINITE_LOWER "infinite"#define LONG_INFINITE_UPPER "INFINITE"#define NAN_LOWER "nan"#define NAN_UPPER "NAN"/* Various constants */enum { TYPE_PRINT = 1, TYPE_SCAN = 2, /* Flags. FLAGS_LAST must be less than ULONG_MAX */ FLAGS_NEW = 0, FLAGS_STICKY = 1, FLAGS_SPACE = 2 * FLAGS_STICKY, FLAGS_SHOWSIGN = 2 * FLAGS_SPACE, FLAGS_LEFTADJUST = 2 * FLAGS_SHOWSIGN, FLAGS_ALTERNATIVE = 2 * FLAGS_LEFTADJUST, FLAGS_SHORT = 2 * FLAGS_ALTERNATIVE, FLAGS_SHORTSHORT = 2 * FLAGS_SHORT, FLAGS_LONG = 2 * FLAGS_SHORTSHORT, FLAGS_QUAD = 2 * FLAGS_LONG, FLAGS_LONGDOUBLE = 2 * FLAGS_QUAD, FLAGS_SIZE_T = 2 * FLAGS_LONGDOUBLE, FLAGS_PTRDIFF_T = 2 * FLAGS_SIZE_T, FLAGS_INTMAX_T = 2 * FLAGS_PTRDIFF_T, FLAGS_NILPADDING = 2 * FLAGS_INTMAX_T, FLAGS_UNSIGNED = 2 * FLAGS_NILPADDING, FLAGS_UPPER = 2 * FLAGS_UNSIGNED, FLAGS_WIDTH = 2 * FLAGS_UPPER, FLAGS_WIDTH_PARAMETER = 2 * FLAGS_WIDTH, FLAGS_PRECISION = 2 * FLAGS_WIDTH_PARAMETER, FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION, FLAGS_BASE = 2 * FLAGS_PRECISION_PARAMETER, FLAGS_BASE_PARAMETER = 2 * FLAGS_BASE, FLAGS_FLOAT_E = 2 * FLAGS_BASE_PARAMETER, FLAGS_FLOAT_G = 2 * FLAGS_FLOAT_E, FLAGS_QUOTE = 2 * FLAGS_FLOAT_G, FLAGS_WIDECHAR = 2 * FLAGS_QUOTE, FLAGS_ALLOC = 2 * FLAGS_WIDECHAR, FLAGS_IGNORE = 2 * FLAGS_ALLOC, FLAGS_IGNORE_PARAMETER = 2 * FLAGS_IGNORE, FLAGS_VARSIZE_PARAMETER = 2 * FLAGS_IGNORE_PARAMETER, FLAGS_FIXED_SIZE = 2 * FLAGS_VARSIZE_PARAMETER, FLAGS_LAST = FLAGS_FIXED_SIZE, /* Reused flags */ FLAGS_EXCLUDE = FLAGS_SHORT, FLAGS_USER_DEFINED = FLAGS_IGNORE, FLAGS_ROUNDING = FLAGS_INTMAX_T, /* Compounded flags */ FLAGS_ALL_VARSIZES = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T, FLAGS_ALL_SIZES = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT, NO_POSITION = -1, NO_WIDTH = 0, NO_PRECISION = -1, NO_SIZE = -1, /* Do not change these */ NO_BASE = -1, MIN_BASE = 2, MAX_BASE = 36, BASE_BINARY = 2, BASE_OCTAL = 8, BASE_DECIMAL = 10, BASE_HEX = 16, /* Maximal number of allowed parameters */ MAX_PARAMETERS = 64, /* Maximal number of characters in class */ MAX_CHARACTER_CLASS = UCHAR_MAX + 1, /* Maximal string lengths for user-defined specifiers */ MAX_USER_NAME = 64, MAX_USER_DATA = 256, /* Maximal length of locale separator strings */ MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX, /* Maximal number of integers in grouping */ MAX_LOCALE_GROUPS = 64, /* Initial size of asprintf buffer */ DYNAMIC_START_SIZE = 32};#define NO_GROUPING ((int)CHAR_MAX)/* Fundamental formatting parameter types */#define FORMAT_UNKNOWN 0#define FORMAT_INT 1#define FORMAT_DOUBLE 2#define FORMAT_CHAR 3#define FORMAT_STRING 4#define FORMAT_POINTER 5#define FORMAT_COUNT 6#define FORMAT_PARAMETER 7#define FORMAT_GROUP 8#if TRIO_GNU# define FORMAT_ERRNO 9#endif#if TRIO_EXTENSION# define FORMAT_USER_DEFINED 10#endif/* Character constants */#define CHAR_IDENTIFIER '%'#define CHAR_BACKSLASH '\\'#define CHAR_QUOTE '\"'#define CHAR_ADJUST ' '/* Character class expressions */#define CLASS_ALNUM "[:alnum:]"#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:]"/* * 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'#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'#define SPECIFIER_POINTER 'p'#define SPECIFIER_GROUP '['#define SPECIFIER_UNGROUP ']'#define SPECIFIER_COUNT 'n'#if TRIO_UNIX98# define SPECIFIER_CHAR_UPPER 'C'# define SPECIFIER_STRING_UPPER 'S'#endif#if TRIO_C99# define SPECIFIER_HEXFLOAT 'a'# define SPECIFIER_HEXFLOAT_UPPER 'A'#endif#if TRIO_GNU# define SPECIFIER_ERRNO 'm'#endif#if TRIO_EXTENSION# define SPECIFIER_BINARY 'b'# define SPECIFIER_BINARY_UPPER 'B'# 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 *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -