/**************************************************************************** | | (C) Copyright 2000, 2003 Novell, Inc. | All Rights Reserved. | | This program is free software; you can redistribute it and/or | modify it under the terms of version 2 of the GNU General Public | License as published by the Free Software Foundation. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU General Public License | along with this program; if not, contact Novell, Inc. | | To contact Novell about this file by physical or electronic mail, | you may find current contact information at www.novell.com | |*************************************************************************** | | NSS Library | |--------------------------------------------------------------------------- | | $Author: taysom $ | $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $ | | $RCSfile$ | $Revision: 465 $ | |--------------------------------------------------------------------------- | This module is used to: | The is used by snprint() under Linux. From LIBC sources. +-------------------------------------------------------------------------*/ #ifndef _SNPRINTF_H_ #define _SNPRINTF_H_ #include #include #ifdef __cplusplus extern "C" { #endif // FixFixFix(__linux__) - this file needs to be cleaned up // Kludge area(start) //#ifndef __cplusplus /* because these may be done better in C++ */ //#ifdef min //#undef min //#endif //#ifdef max //#undef max //#endif //# define max(a, b) (((a) > (b)) ? (a) : (b)) //# define min(a, b) (((a) < (b)) ? (a) : (b)) //# define inrange(lo, x, hi) ((x) >= (lo) && (x) <= (hi)) // int (max)( int a, int b ); // int (min)( int a, int b ); //#endif #ifndef EOF #define EOF -1 #endif #ifdef __linux__ #define IS_DOUBLE_BYTE(p) (FALSE) // useful for code that is compiled in both char and wchar contexts #define ISDIGIT(c) ('0' <= (c) && (c) <= '9') #define ISSPACE(c) (' ' == (c) || (0x09 <= (c) && (c) <= 0x0D)) #ifndef LLONG_MIN # define LLONG_MIN (I64_CONST(-9223372036854775807)-1)/* max value of 'long long' */ #endif #endif #define _IOWRT 0x00000002 // currently writing ("w") #define _IOISASTR 0x00080000 // this is a temp 'string' file (ea. sscanf()) #define _IOISABNDSTR 0x00100000 // this is a bounded 'string' file, snprintf() ///* exact-width signed types... */ //#ifndef __linux__ //typedef signed char int8_t; //typedef short int int16_t; //typedef long int int32_t; //typedef SQUAD int64_t; // ///* exact-width unsigned types... */ //typedef unsigned char uint8_t; //typedef unsigned short int uint16_t; //typedef unsigned long int uint32_t; //typedef QUAD uint64_t; //#endif //typedef long ssize_t; /* buffer size plus return codes */ #define LIB_LDBL_MANT_DIG 64 #define LIB_LDBL_DIG 18 #define LIB_LDBL_MIN_EXP (-16381) #define LIB_LDBL_MIN_10_EXP (-4931) #define LIB_LDBL_MAX_EXP (+16384) #define LIB_LDBL_MAX_10_EXP (+4932) #define LDBL_MANT_DIG LIB_LDBL_MANT_DIG #define LDBL_DIG LIB_LDBL_DIG #define LDBL_MIN_EXP LIB_LDBL_MIN_EXP #define LDBL_MIN_10_EXP LIB_LDBL_MIN_10_EXP #define LDBL_MAX_EXP LIB_LDBL_MAX_EXP #define LDBL_MAX_10_EXP LIB_LDBL_MAX_10_EXP #define LDBL_MAX LIB_LDBL_MAX #define LDBL_EPSILON LIB_LDBL_EPSILON #define LDBL_MIN LIB_LDBL_MIN // Kludge area (end) //#include //#include //#include #ifdef WIDE # define CHAR wchar_t // wide character print engine # define UCHAR wuchar_t #else # define CHAR char // multibyte print engine # define UCHAR unsigned char #endif // 'flags' values for how numbers and strings behave... #define ffUNDEF 0x00000000 // right-justify, normal size #define ffZERO 0x00000001 // zero-pad #define ffDOT 0x00000002 // same as zero-pad for now #define ffPLUS 0x00000004 // prepend sign #define ffMINUS 0x00000008 // left-justify #define ffHALF 0x00000010 // word arg (16 bits) %h #define ffHALF_HALF 0x00000020 // byte arg (8 bits) %hh #define ffLONG 0x00000040 // long arg (32 bits) %l #define ffLONG_LONG 0x00000080 // long long/intmax_t arg (64 bits) %ll, %j #define ffLONG_DOUBLE 0x00000100 // long double arg (unsupported) #define ffUINT 0x00000200 // unsigned int #define ffPTRDIFF 0x00000400 // ptrdiff_t arg (signed 32 bits) %t #define ffVPTR 0x00000800 // pointer #define ffPOUND 0x00001000 // convert to alternate form (unsupported) #define ffSPACE 0x00002000 // space-pad string #define ffQUOTE 0x00004000 // enable numeric grouping (3,000 not 3000) #define ffCAPS 0x00008000 // upper-case equivalent of another pronoun #define ffEOF 0x00010000 // reached end of FILE or string (scan only) #define ffSTAR 0x00020000 // '*' #define ffSIGN 0x00040000 // floating point sign #define ffALLOC 0x00100000 // indicates a temporary allocation #define ffDASH 0x00200000 // #define ffAFTER 0x00400000 // #define ffBEFORE 0x00800000 // #define ffBLANK 0x01000000 // #define ffSHARP 0x02000000 // #define _ULTOS(p, v) do { *--(p) = (v) % 10 + '0'; } while ((v) /= 10) #define _ULLTOS(p, v) do { *--(p) = (v) % 10 + '0'; } while ((v) /= 10) //#define _ULLTOS(p, v) do { *--(p) = do_div(v, 10) + '0'; } while ( (v) ) /* ** Based on the conversion specifier in 'ch,' this determines the radix to be ** used in performing a numeric to string conversion. */ #define GET_RADIX(ch) \ (((ch) == 'x' || (ch) == 'X') \ ? 16 \ : ((ch) == 'o') \ ? 8 \ : ((ch) == 'b') \ ? 2 \ : 10) /* ** These upper bounds must be big enough, but need not be exact. ** Floating-specific values are checked when convert.c is compiled. ** ** NDIG_DEC - maximum decimal digits producable by convert_float() ** NDIG_HEX - maximum hexadecimal digits producable by convert_float() ** NDIG_EXP - maximum bytes for decimal exponents (e+d*d) ** ** NDIG_A_FMT - maximum bytes for %a (-0xh.h*hp+d*d) ** NDIG_E_FMT - maximum bytes for %e (-d.d*de+d*d) ** NDIG_F_FMT - maximum bytes for %f (-d*d.d*d) ** ** NDIG_INT - maximum bytes for integer formats (0b%b) ** ** NDIG_FMT - maximum bytes of the NDIG_?_FMT formats ** NDIG_MAX - maximum bytes of all the the numeric formats */ #define NDIG_DEC (2 + LDBL_DIG + 2) #define NDIG_HEX ((LDBL_MANT_DIG + 3) / 4) #define NDIG_EXP (2 + 6) #define NDIG_A_FMT (1 + 2 + 1 + NDIG_HEX + NDIG_EXP + 1) #define NDIG_E_FMT (1 + 1 + NDIG_DEC + NDIG_EXP) #define NDIG_F_FMT (1 + 1 + NDIG_DEC) #define NDIG_FMT (NDIG_A_FMT > NDIG_E_FMT ? NDIG_A_FMT : NDIG_E_FMT) #define NDIG_INT (2 + sizeof(uint64_t) * CHAR_BIT) #define NDIG_MAX (NDIG_INT > NDIG_FMT ? NDIG_INT : NDIG_FMT) #define CVT_INF 0 // decimal point for Infinity #define CVT_NAN 1 // decimal point for NaN #define CVT_CAPS 0x1 // capitalized version of these modes #define CVT_A 0x2 #define CVT_E 0x4 #define CVT_F 0x8 #ifdef DO_FLOATING_POINT typedef struct // holds incoming and outgoing information... { // ...for convert_float() UCHAR *buf; // generate digits in here int ndigits; // precision/number of digits int mode; // conversion mode int decimal; // exponent (offset to decimal point) int sign; // 0:nonnegative; 1:negative int len; // length of returned string union // incoming floating value { _dval dval; _ldval ldval; } val; } float_cvt_t; #endif typedef enum // all the various types that can be given to va_arg() { T_INT, // default T_LONG, T_DBL, T_LDBL, T_VPTR, T_CPTR, T_SPTR, T_IPTR, T_LPTR, T_FPTR, T_DPTR, T_LDPTR, T_PPTR, T_LLONG, T_LLPTR } ArgType; typedef union { ArgType type; // used by _parglist() va_list ap; // used for passing to va_arg() } va_list_U; typedef struct // holds incoming and outgoing information for _cvt's { unsigned char *buf; // generate digits in here int ndig; // precision/number of digits int mode; // conversion mode int decpt; // exponent (offset to decimal point) int sign; // 0:nonnegative; 1:negative int len; // length of returned string #ifdef DO_FLOATING_POINT union // incoming floating value { _dval dval; _ldval ldval; } val; #endif } Cvt; extern const char g_str_uc_hex[]; // "0123456789ABCDEF" extern const char g_str_lc_hex[]; // "0123456789abcdef" extern const char g_str_mixed_nan[];// "NaN" extern const char g_str_uc_nan[]; // "NAN" extern const char g_str_lc_nan[]; // "nan" extern const char g_str_mixed_inf[];// "Infinity" extern const char g_str_uc_inf[]; // "INFINITY" extern const char g_str_lc_inf[]; // "infinity" // prototypes... #ifdef DO_FLOATING_POINT UCHAR *convert_float( float_cvt_t *, const char *, const char * ); #endif void _parglist(const CHAR *fmt, va_list_U *arglist, int len, int pos, int scan); unsigned char *_cvt( Cvt *, const char *nanStr, const char *infStr ); unsigned char *_cvtl( register Cvt *cp, const char *nanStr, const char *infStr ); int __cputs ( const char *string ); //#if 0 //// Macro used by both the print and scan engines to set the locale when needed //#define SETLOC(vm, loc) \ //{ \ // if (!loc) /* Get a locale if we don't have one */ \ // { \ // if (!vm) /* Get the context if we don't have it */ \ // { \ // if (vm = _get_vm(0)) \ // { \ // loc = &vm->localeconv; \ // if (!loc->name[0]) \ // loc = &g_default_locale; \ // } \ // else \ // { \ // loc = &g_default_locale; \ // } \ // } \ // else if (!vm->localeconv.name[0]) \ // { \ // loc = &g_default_locale; \ // } \ // else \ // { \ // loc = &vm->localeconv; \ // } \ // } \ //} //#endif //#include struct lconv /* for the current locale... */ { int country; /* internal representations... */ int language; /* ibid */ char name[8]; /* as returned from setlocale(LC_ALL, NULL) */ /* -------------------------- [Numeric Conventions] --------------------- */ char decimal_point[4]; /* decimal point */ char thousands_sep[4]; /* separator for digits left of decimal */ char grouping[4]; /* digit grouping size */ /* -------------------------- [Monetary Conventions] -------------------- */ char currency_symbol[4]; /* currency symbol */ char mon_decimal_point[4]; /* decimal point */ char mon_thousands_sep[4]; /* separator for digits left of decimal */ char mon_grouping[8]; /* digit grouping sizes */ char positive_sign[4]; /* string indicating positive quantities */ char negative_sign[4]; /* string indicating negative quantities */ char frac_digits; /* count of digits right of decimal */ /* for positive monetary quantities: */ char p_cs_precedes; /* currency symbol precedes quantity */ char p_sep_by_space; /* currency symbol separated by blank */ char p_sign_posn; /* position of positive symbol */ /* for negative monetary quantities: */ char n_cs_precedes; /* currency symbol precedes quantity */ char n_sep_by_space; /* currency symbol separated by blank */ char n_sign_posn; /* position of negative symbol */ char reserved; /* (reserved for future use) */ /* -------------------------- [International Monetary Conventions] ------ */ char int_curr_symbol[15]; /* international currency symbol and separator */ char int_frac_digits; /* (international) digits right of decimal */ /* -------------------------- [Time and Date Conventions] --------------- */ int always_24; /* always enforce 24-hour display (Boolean) */ char hour_sep[4]; /* hour and seconds separator */ char hour_sans_sec_sep[4]; /* hour separator when no seconds displayed */ char date_sep[4]; /* month/day/year separator */ char time_fmt[16]; /* hours:minutes:seconds format (hh:mm:ss) */ char date_fmt[16]; /* month/day/year format (mm/dd/yyyy) */ char full_date_fmt[32]; /* weekday, month, day and year format */ char ampm[32]; /* delimited string indicating am and pm */ char AMPM[32]; /* delimited string indicating AM and PM */ char days[160]; /* delimited string of day names */ char day_abbrevs[160]; /* delimited string of abbreviated day names */ char months[160]; /* delimited string of month names */ char month_abbrevs[160]; /* delimited string of abbreviated month names */ }; /* sizeof(struct lconv) == 0x360 (864.) */ //#include #define _qcpy(d,s,n) (void *) ((char *) memcpy(d, s, n) + (n)) // Macro used by both the print and scan engines to set the locale when needed #define SET_LOC(loc) \ { \ if (!loc) /* Get a locale if we don't have one */ \ { \ loc = &g_default_locale; \ } \ } //#include "convert.h" //----------------------------------------------------------------------------- // F I L E ( S t r e a m ) S t r u c t u r e //----------------------------------------------------------------------------- typedef struct _iob // ANSI FILE_t stream structure { // this is no longer publicly-exposed // struct _iob *next; // the next open FILE_t // unsigned long signature; // 'StdF'--identifies this structure //# define kOpenStdioSig 'StdF' // --when valid and in use //# define kClosedStdioSig '----' // --when on free list // void *ofs; // pointer to base of OpenFileStructure // unsigned long state; // state of stream, errors, etc. //-0x10------------------------------------------------------------------------ // size_t bufsize; // size of buffer int avail; // available (unused/unread) room in buffer unsigned char *begptr; // start of buffer unsigned char *endptr; // end of buffer //-0x20------------------------------------------------------------------------ unsigned char *ptr; // next character from/to here in buffer // unsigned char buf[4]; // fake, micro buffer as a fall-back // int fildes; // underlying file descriptor // size_t nl_count; // count of '\r\n' sequences in the buffer //-0x30------------------------------------------------------------------------ // size_t begpos; // real position in file of the buffer start // size_t eofpos; // real position in file of the buffer end // thr_t *owner; // owner of this lock // void *lock; // for protected operations //-0x40------------------------------------------------------------------------ // char *tmpfile_name; // allocated/deallocated by tmpfile() et al. // pid_t popened_child; // on which pclose() will NXVmJoin()... // int *paddington[2]; } FILE_t; typedef struct // used by doprint.c and nwprint.c { // locals shared between _i[w[s]]doprint and other functions FILE_t *fp; // the stream; strings provide fake one unsigned char *curptr; // output placed here unsigned char *beg; // start of main generated bytes unsigned char *end; // one past main generated bytes UCHAR *radix; // points at radix, if appropriate const UCHAR *prefix; // bytes before main generated ones const unsigned char *suffix; // bytes after main generated ones const unsigned char *grp; // location in grouping string size_t nprefix; // length of prefix (none if 0) size_t nsuffix; // length of suffix (none if 0) size_t nsuf0; // length of zero-padding for suffix size_t nleft0; // number of zeros before main bytes size_t nright0; // number of zeros after main bytes size_t width; // minimum conversion length size_t prec; // precision, valid iff F_DOT unsigned long flags; // status about current conversion int roomleft; // space left before flush int total; // total generated bytes/characters int ngrp; // number of digits in current group UCHAR buf[NDIG_MAX]; // space for main generated bytes UCHAR suf[NDIG_MAX]; // variable suffixes built here } PStream; #ifdef __cplusplus } #endif #endif