Files
mars-nwe/include/core/snprintf.h
Mario Fetka 90a7db3b3a
All checks were successful
Source release / source-package (push) Successful in 1m32s
0490 core: import NSS stdio formatter runtime
2026-06-13 21:50:42 +02:00

465 lines
17 KiB
C

/****************************************************************************
|
| (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 <limits.h>
#include <stdint.h>
#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 <defs.h>
//#include <locdata.h>
//#include <libfloat.h>
#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 <pshpack1.h>
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 <poppack.h>
#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