1141cc406Sopenharmony_ci#include "../include/sane/config.h" 2141cc406Sopenharmony_ci 3141cc406Sopenharmony_ci#ifndef HAVE_SNPRINTF 4141cc406Sopenharmony_ci 5141cc406Sopenharmony_ci/************************************************************************** 6141cc406Sopenharmony_ci * Copyright 1994-2003 Patrick Powell, San Diego, CA <papowell@lprng.com> 7141cc406Sopenharmony_ci **************************************************************************/ 8141cc406Sopenharmony_ci 9141cc406Sopenharmony_ci/* 10141cc406Sopenharmony_ci Overview: 11141cc406Sopenharmony_ci 12141cc406Sopenharmony_ci snprintf( char *buffer, int len, const char *format,...) 13141cc406Sopenharmony_ci plp_unsafe_snprintf( char *buffer, int len, const char *format,...) 14141cc406Sopenharmony_ci its horribly unsafe companion that does NOT protect you from 15141cc406Sopenharmony_ci the printing of evil control characters, but may be necessary 16141cc406Sopenharmony_ci See the man page documentation below 17141cc406Sopenharmony_ci 18141cc406Sopenharmony_ci This version of snprintf was developed originally for printing 19141cc406Sopenharmony_ci on a motley collection of specialized hardware that had NO IO 20141cc406Sopenharmony_ci library. Due to contractual restrictions, a clean room implementation 21141cc406Sopenharmony_ci of the printf() code had to be developed. 22141cc406Sopenharmony_ci 23141cc406Sopenharmony_ci The method chosen for printf was to be as paranoid as possible, 24141cc406Sopenharmony_ci as these platforms had NO memory protection, and very small 25141cc406Sopenharmony_ci address spaces. This made it possible to try to print 26141cc406Sopenharmony_ci very long strings, i.e. - all of memory, very easily. To guard 27141cc406Sopenharmony_ci against this, all printing was done via a buffer, generous enough 28141cc406Sopenharmony_ci to hold strings, but small enough to protect against overruns, 29141cc406Sopenharmony_ci etc. 30141cc406Sopenharmony_ci 31141cc406Sopenharmony_ci Strangely enough, this proved to be of immense importance when 32141cc406Sopenharmony_ci SPRINTFing to a buffer on a stack... The rest, of course, is 33141cc406Sopenharmony_ci well known, as buffer overruns in the stack are a common way to 34141cc406Sopenharmony_ci do horrible things to operating systems, security, etc etc. 35141cc406Sopenharmony_ci 36141cc406Sopenharmony_ci This version of snprintf is VERY limited by modern standards. 37141cc406Sopenharmony_ci 38141cc406Sopenharmony_ci Revision History: 39141cc406Sopenharmony_ci First Released Version - 1994. This version had NO comments. 40141cc406Sopenharmony_ci First Released Version - 1994. This version had NO comments. 41141cc406Sopenharmony_ci Second Major Released Version - Tue May 23 10:43:44 PDT 2000 42141cc406Sopenharmony_ci Configuration and other items changed. Read this doc. 43141cc406Sopenharmony_ci Treat this as a new version. 44141cc406Sopenharmony_ci Minor Revision - Mon Apr 1 09:41:28 PST 2002 45141cc406Sopenharmony_ci - fixed up some constants and casts 46141cc406Sopenharmony_ci 47141cc406Sopenharmony_ci COPYRIGHT AND TERMS OF USE: 48141cc406Sopenharmony_ci 49141cc406Sopenharmony_ci You may use, copy, distribute, or otherwise incorporate this software 50141cc406Sopenharmony_ci and documentation into any product or other item, provided that 51141cc406Sopenharmony_ci the copyright in the documentation and source code as well as the 52141cc406Sopenharmony_ci source code generated constant strings in the object, executable 53141cc406Sopenharmony_ci or other code remain in place and are present in executable modules 54141cc406Sopenharmony_ci or objects. 55141cc406Sopenharmony_ci 56141cc406Sopenharmony_ci You may modify this code as appropriate to your usage; however the 57141cc406Sopenharmony_ci modified version must be identified by changing the various source 58141cc406Sopenharmony_ci and object code identification strings as is appropriately noted 59141cc406Sopenharmony_ci in the source code. 60141cc406Sopenharmony_ci 61141cc406Sopenharmony_ci You can use this with the GNU CONFIGURE utility. 62141cc406Sopenharmony_ci This should define the following macros appropriately: 63141cc406Sopenharmony_ci 64141cc406Sopenharmony_ci HAVE_STDARG_H - if the <stdargs.h> include file is available 65141cc406Sopenharmony_ci HAVE_VARARG_H - if the <varargs.h> include file is available 66141cc406Sopenharmony_ci 67141cc406Sopenharmony_ci HAVE_STRERROR - if the strerror() routine is available. 68141cc406Sopenharmony_ci If it is not available, then examine the lines containing 69141cc406Sopenharmony_ci the tests below. 70141cc406Sopenharmony_ci 71141cc406Sopenharmony_ci HAVE_SYS_ERRLIST - have sys_errlist available 72141cc406Sopenharmony_ci HAVE_DECL_SYS_ERRLIST - sys_errlist declaration in include files 73141cc406Sopenharmony_ci HAVE_SYS_NERR - have sys_nerr available 74141cc406Sopenharmony_ci HAVE_DECL_SYS_NERR - sys_nerr declaration in include files 75141cc406Sopenharmony_ci 76141cc406Sopenharmony_ci HAVE_QUAD_T - if the quad_t type is defined 77141cc406Sopenharmony_ci HAVE_LONG_LONG - if the long long type is defined 78141cc406Sopenharmony_ci HAVE_LONG_DOUBLE - if the long double type is defined 79141cc406Sopenharmony_ci 80141cc406Sopenharmony_ci If you are using the GNU configure (autoconf) facility, add the 81141cc406Sopenharmony_ci following line to the configure.in file, to force checking for the 82141cc406Sopenharmony_ci quad_t and long long data types: 83141cc406Sopenharmony_ci 84141cc406Sopenharmony_ci 85141cc406Sopenharmony_ci AC_CHECK_HEADERS(stdlib.h,stdio.h,unistd.h,errno.h) 86141cc406Sopenharmony_ci AC_CHECK_FUNCS(strerror) 87141cc406Sopenharmony_ci AC_CACHE_CHECK(for errno, 88141cc406Sopenharmony_ci ac_cv_errno, 89141cc406Sopenharmony_ci [ 90141cc406Sopenharmony_ci AC_TRY_LINK(,[extern int errno; return (errno);], 91141cc406Sopenharmony_ci ac_cv_errno=yes, ac_cv_errno=no) 92141cc406Sopenharmony_ci ]) 93141cc406Sopenharmony_ci if test "$ac_cv_errno" = yes; then 94141cc406Sopenharmony_ci AC_DEFINE(HAVE_ERRNO) 95141cc406Sopenharmony_ci AC_CACHE_CHECK(for errno declaration, 96141cc406Sopenharmony_ci ac_cv_decl_errno, 97141cc406Sopenharmony_ci [ 98141cc406Sopenharmony_ci AC_TRY_COMPILE([ 99141cc406Sopenharmony_ci #include <stdio.h> 100141cc406Sopenharmony_ci #ifdef HAVE_STDLIB_H 101141cc406Sopenharmony_ci #include <stdlib.h> 102141cc406Sopenharmony_ci #endif 103141cc406Sopenharmony_ci #ifdef HAVE_UNISTD_H 104141cc406Sopenharmony_ci #include <unistd.h> 105141cc406Sopenharmony_ci #endif 106141cc406Sopenharmony_ci #ifdef HAVE_ERRNO_H 107141cc406Sopenharmony_ci #include <errno.h> 108141cc406Sopenharmony_ci ],[return(sys_nerr);], 109141cc406Sopenharmony_ci ac_cv_decl_errno=yes, ac_cv_decl_errno=no) 110141cc406Sopenharmony_ci ]) 111141cc406Sopenharmony_ci if test "$ac_cv_decl_errno" = yes; then 112141cc406Sopenharmony_ci AC_DEFINE(HAVE_DECL_ERRNO) 113141cc406Sopenharmony_ci fi; 114141cc406Sopenharmony_ci fi 115141cc406Sopenharmony_ci 116141cc406Sopenharmony_ci AC_CACHE_CHECK(for sys_nerr, 117141cc406Sopenharmony_ci ac_cv_sys_nerr, 118141cc406Sopenharmony_ci [ 119141cc406Sopenharmony_ci AC_TRY_LINK(,[extern int sys_nerr; return (sys_nerr);], 120141cc406Sopenharmony_ci ac_cv_sys_nerr=yes, ac_cv_sys_nerr=no) 121141cc406Sopenharmony_ci ]) 122141cc406Sopenharmony_ci if test "$ac_cv_sys_nerr" = yes; then 123141cc406Sopenharmony_ci AC_DEFINE(HAVE_SYS_NERR) 124141cc406Sopenharmony_ci AC_CACHE_CHECK(for sys_nerr declaration, 125141cc406Sopenharmony_ci ac_cv_decl_sys_nerr, 126141cc406Sopenharmony_ci [ 127141cc406Sopenharmony_ci AC_TRY_COMPILE([ 128141cc406Sopenharmony_ci #include <stdio.h> 129141cc406Sopenharmony_ci #ifdef HAVE_STDLIB_H 130141cc406Sopenharmony_ci #include <stdlib.h> 131141cc406Sopenharmony_ci #endif 132141cc406Sopenharmony_ci #ifdef HAVE_UNISTD_H 133141cc406Sopenharmony_ci #include <unistd.h> 134141cc406Sopenharmony_ci #endif],[return(sys_nerr);], 135141cc406Sopenharmony_ci ac_cv_decl_sys_nerr_def=yes, ac_cv_decl_sys_nerr_def=no) 136141cc406Sopenharmony_ci ]) 137141cc406Sopenharmony_ci if test "$ac_cv_decl_sys_nerr" = yes; then 138141cc406Sopenharmony_ci AC_DEFINE(HAVE_DECL_SYS_NERR) 139141cc406Sopenharmony_ci fi 140141cc406Sopenharmony_ci fi 141141cc406Sopenharmony_ci 142141cc406Sopenharmony_ci 143141cc406Sopenharmony_ci AC_CACHE_CHECK(for sys_errlist array, 144141cc406Sopenharmony_ci ac_cv_sys_errlist, 145141cc406Sopenharmony_ci [AC_TRY_LINK(,[extern char *sys_errlist[]; 146141cc406Sopenharmony_ci sys_errlist[0];], 147141cc406Sopenharmony_ci ac_cv_sys_errlist=yes, ac_cv_sys_errlist=no) 148141cc406Sopenharmony_ci ]) 149141cc406Sopenharmony_ci if test "$ac_cv_sys_errlist" = yes; then 150141cc406Sopenharmony_ci AC_DEFINE(HAVE_SYS_ERRLIST) 151141cc406Sopenharmony_ci AC_CACHE_CHECK(for sys_errlist declaration, 152141cc406Sopenharmony_ci ac_cv_sys_errlist_def, 153141cc406Sopenharmony_ci [AC_TRY_COMPILE([ 154141cc406Sopenharmony_ci #include <stdio.h> 155141cc406Sopenharmony_ci #include <errno.h> 156141cc406Sopenharmony_ci #ifdef HAVE_STDLIB_H 157141cc406Sopenharmony_ci #include <stdlib.h> 158141cc406Sopenharmony_ci #endif 159141cc406Sopenharmony_ci #ifdef HAVE_UNISTD_H 160141cc406Sopenharmony_ci #include <unistd.h> 161141cc406Sopenharmony_ci #endif],[char *s = sys_errlist[0]; return(*s);], 162141cc406Sopenharmony_ci ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no) 163141cc406Sopenharmony_ci ]) 164141cc406Sopenharmony_ci if test "$ac_cv_decl_sys_errlist" = yes; then 165141cc406Sopenharmony_ci AC_DEFINE(HAVE_DECL_SYS_ERRLIST) 166141cc406Sopenharmony_ci fi 167141cc406Sopenharmony_ci fi 168141cc406Sopenharmony_ci 169141cc406Sopenharmony_ci 170141cc406Sopenharmony_ci 171141cc406Sopenharmony_ci AC_CACHE_CHECK(checking for long long, 172141cc406Sopenharmony_ci ac_cv_long_long, 173141cc406Sopenharmony_ci [ 174141cc406Sopenharmony_ci AC_TRY_COMPILE([ 175141cc406Sopenharmony_ci #include <stdio.h> 176141cc406Sopenharmony_ci #include <sys/types.h> 177141cc406Sopenharmony_ci ], [printf("%d",sizeof(long long));], 178141cc406Sopenharmony_ci ac_cv_long_long=yes, ac_cv_long_long=no) 179141cc406Sopenharmony_ci ]) 180141cc406Sopenharmony_ci if test $ac_cv_long_long = yes; then 181141cc406Sopenharmony_ci AC_DEFINE(HAVE_LONG_LONG) 182141cc406Sopenharmony_ci fi 183141cc406Sopenharmony_ci 184141cc406Sopenharmony_ci AC_CACHE_CHECK(checking for long double, 185141cc406Sopenharmony_ci ac_cv_long_double, 186141cc406Sopenharmony_ci [ 187141cc406Sopenharmony_ci AC_TRY_COMPILE([ 188141cc406Sopenharmony_ci #include <stdio.h> 189141cc406Sopenharmony_ci #include <sys/types.h> 190141cc406Sopenharmony_ci ], [printf("%d",sizeof(long double));], 191141cc406Sopenharmony_ci ac_cv_long_double=yes, ac_cv_long_double=no) 192141cc406Sopenharmony_ci ]) 193141cc406Sopenharmony_ci if test $ac_cv_long_double = yes; then 194141cc406Sopenharmony_ci AC_DEFINE(HAVE_LONG_DOUBLE) 195141cc406Sopenharmony_ci fi 196141cc406Sopenharmony_ci 197141cc406Sopenharmony_ci AC_CACHE_CHECK(checking for quad_t, 198141cc406Sopenharmony_ci ac_cv_quad_t, 199141cc406Sopenharmony_ci [ 200141cc406Sopenharmony_ci AC_TRY_COMPILE([ 201141cc406Sopenharmony_ci #include <stdio.h> 202141cc406Sopenharmony_ci #include <sys/types.h> 203141cc406Sopenharmony_ci ], [printf("%d",sizeof(quad_t));], 204141cc406Sopenharmony_ci ac_cv_quad_t=yes, ac_cv_quad_t=no) 205141cc406Sopenharmony_ci ]) 206141cc406Sopenharmony_ci if test $ac_cv_quad_t = yes; then 207141cc406Sopenharmony_ci AC_DEFINE(HAVE_QUAD_T) 208141cc406Sopenharmony_ci fi 209141cc406Sopenharmony_ci 210141cc406Sopenharmony_ci 211141cc406Sopenharmony_ci 212141cc406Sopenharmony_ci NAME 213141cc406Sopenharmony_ci snprintf, plp_vsnprintf - formatted output conversion 214141cc406Sopenharmony_ci 215141cc406Sopenharmony_ci SYNOPSIS 216141cc406Sopenharmony_ci #include <stdio.h> 217141cc406Sopenharmony_ci #include <stdarg.h> 218141cc406Sopenharmony_ci 219141cc406Sopenharmony_ci int 220141cc406Sopenharmony_ci snprintf(const char *format, size_t size, va_list ap); 221141cc406Sopenharmony_ci int 222141cc406Sopenharmony_ci plp_unsafe_snprintf(const char *format, size_t size, va_list ap); 223141cc406Sopenharmony_ci 224141cc406Sopenharmony_ci AKA snprintf and unsafe_snprintf in the documentation below 225141cc406Sopenharmony_ci 226141cc406Sopenharmony_ci int 227141cc406Sopenharmony_ci vsnprintf(char *str, size_t size, const char *format, va_list ap); 228141cc406Sopenharmony_ci int 229141cc406Sopenharmony_ci unsafe_vsnprintf(char *str, size_t size, const char *format, va_list ap); 230141cc406Sopenharmony_ci 231141cc406Sopenharmony_ci AKA vsnprintf and unsafe_vsnprintf in the documentation below 232141cc406Sopenharmony_ci 233141cc406Sopenharmony_ci (Multithreaded Safe) 234141cc406Sopenharmony_ci 235141cc406Sopenharmony_ci DESCRIPTION 236141cc406Sopenharmony_ci The printf() family of functions produces output according to 237141cc406Sopenharmony_ci a format as described below. Snprintf(), and vsnprintf() 238141cc406Sopenharmony_ci write to the character string str. These functions write the 239141cc406Sopenharmony_ci output under the control of a format string that specifies 240141cc406Sopenharmony_ci how subsequent arguments (or arguments accessed via the 241141cc406Sopenharmony_ci variable-length argument facilities of stdarg(3)) are converted 242141cc406Sopenharmony_ci for output. These functions return the number of characters 243141cc406Sopenharmony_ci printed (not including the trailing `\0' used to end output 244141cc406Sopenharmony_ci to strings). Snprintf() and vsnprintf() will write at most 245141cc406Sopenharmony_ci size-1 of the characters printed into the output string (the 246141cc406Sopenharmony_ci size'th character then gets the terminating `\0'); if the 247141cc406Sopenharmony_ci return value is greater than or equal to the size argument, 248141cc406Sopenharmony_ci the string was too short and some of the printed characters 249141cc406Sopenharmony_ci were discarded. The size or str may be given as zero to find 250141cc406Sopenharmony_ci out how many characters are needed; in this case, the str 251141cc406Sopenharmony_ci argument is ignored. 252141cc406Sopenharmony_ci 253141cc406Sopenharmony_ci By default, the snprintf function will not format control 254141cc406Sopenharmony_ci characters (except new line and tab) in strings. This is a 255141cc406Sopenharmony_ci safety feature that has proven to be extremely critical when 256141cc406Sopenharmony_ci using snprintf for secure applications and when debugging. 257141cc406Sopenharmony_ci If you MUST have control characters formatted or printed, 258141cc406Sopenharmony_ci then use the unsafe_snprintf() and unsafe_vsnprintf() and on 259141cc406Sopenharmony_ci your own head be the consequences. You have been warned. 260141cc406Sopenharmony_ci 261141cc406Sopenharmony_ci There is one exception to the comments above, and that is 262141cc406Sopenharmony_ci the "%c" (character) format. It brutally assumes that the 263141cc406Sopenharmony_ci user will have performed the necessary 'isprint()' or other 264141cc406Sopenharmony_ci checks and uses the integer value as a character. 265141cc406Sopenharmony_ci 266141cc406Sopenharmony_ci The format string is composed of zero or more directives: 267141cc406Sopenharmony_ci ordinary characters (not %), which are copied unchanged to 268141cc406Sopenharmony_ci the output stream; and conversion specifications, each 269141cc406Sopenharmony_ci of which results in fetching zero or more subsequent arguments. 270141cc406Sopenharmony_ci Each conversion specification is introduced by the character 271141cc406Sopenharmony_ci %. The arguments must correspond properly (after type promotion) 272141cc406Sopenharmony_ci with the conversion specifier. After the %, the following 273141cc406Sopenharmony_ci appear in sequence: 274141cc406Sopenharmony_ci 275141cc406Sopenharmony_ci o Zero or more of the following flags: 276141cc406Sopenharmony_ci 277141cc406Sopenharmony_ci - A zero `0' character specifying zero padding. For 278141cc406Sopenharmony_ci all conversions except n, the converted value is padded 279141cc406Sopenharmony_ci on the left with zeros rather than blanks. If a 280141cc406Sopenharmony_ci precision is given with a numeric conversion (d, i, 281141cc406Sopenharmony_ci o, u, i, x, and X), the `0' flag is ignored. 282141cc406Sopenharmony_ci 283141cc406Sopenharmony_ci - A negative field width flag `-' indicates the converted 284141cc406Sopenharmony_ci value is to be left adjusted on the field boundary. Except 285141cc406Sopenharmony_ci for n conversions, the converted value is padded on 286141cc406Sopenharmony_ci the right with blanks, rather than on the left with 287141cc406Sopenharmony_ci blanks or zeros. A `-' overrides a `0' if both are 288141cc406Sopenharmony_ci given. 289141cc406Sopenharmony_ci 290141cc406Sopenharmony_ci - A space, specifying that a blank should be left before 291141cc406Sopenharmony_ci a positive number produced by a signed conversion (d, e, E, f, 292141cc406Sopenharmony_ci g, G, or i). 293141cc406Sopenharmony_ci 294141cc406Sopenharmony_ci - A `+' character specifying that a sign always be placed 295141cc406Sopenharmony_ci before a number produced by a signed conversion. A `+' overrides 296141cc406Sopenharmony_ci a space if both are used. 297141cc406Sopenharmony_ci 298141cc406Sopenharmony_ci o An optional decimal digit string specifying a minimum 299141cc406Sopenharmony_ci field width. If the converted value has fewer 300141cc406Sopenharmony_ci characters than the field width, it will be padded 301141cc406Sopenharmony_ci with spaces on the left (or right, if the 302141cc406Sopenharmony_ci left-adjustment flag has been given) to fill out 303141cc406Sopenharmony_ci the field width. 304141cc406Sopenharmony_ci 305141cc406Sopenharmony_ci o An optional precision, in the form of a period `.' followed 306141cc406Sopenharmony_ci by an optional digit string. If the digit string 307141cc406Sopenharmony_ci is omitted, the precision is taken as zero. This 308141cc406Sopenharmony_ci gives the minimum number of digits to appear for 309141cc406Sopenharmony_ci d, i, o, u, x, and X conversions, the number of 310141cc406Sopenharmony_ci digits to appear after the decimal-point for e, 311141cc406Sopenharmony_ci E, and f conversions, the maximum number of 312141cc406Sopenharmony_ci significant digits for g and G conversions, or 313141cc406Sopenharmony_ci the maximum number of characters to be printed 314141cc406Sopenharmony_ci from a string for s conversions. 315141cc406Sopenharmony_ci 316141cc406Sopenharmony_ci o The optional character h, specifying that a following d, 317141cc406Sopenharmony_ci i, o, u, x, or X conversion corresponds to a short 318141cc406Sopenharmony_ci int or unsigned short int argument, or that a 319141cc406Sopenharmony_ci following n conversion corresponds to a pointer 320141cc406Sopenharmony_ci to a short int argument. 321141cc406Sopenharmony_ci 322141cc406Sopenharmony_ci o The optional character l (ell) specifying that a following 323141cc406Sopenharmony_ci d, i, o, u, x, or X conversion applies to a pointer 324141cc406Sopenharmony_ci to a long int or unsigned long int argument, or 325141cc406Sopenharmony_ci that a following n conversion corresponds to a 326141cc406Sopenharmony_ci pointer to a long int argument. 327141cc406Sopenharmony_ci 328141cc406Sopenharmony_ci o The optional character q, specifying that a following d, 329141cc406Sopenharmony_ci i, o, u, x, or X conversion corresponds to a quad_t 330141cc406Sopenharmony_ci or u_quad_t argument, or that a following n 331141cc406Sopenharmony_ci conversion corresponds to a quad_t argument. 332141cc406Sopenharmony_ci This value is always printed in HEX notation. Tough. 333141cc406Sopenharmony_ci quad_t's are an OS system implementation, and should 334141cc406Sopenharmony_ci not be allowed. 335141cc406Sopenharmony_ci 336141cc406Sopenharmony_ci o The character L specifying that a following e, E, f, g, 337141cc406Sopenharmony_ci or G conversion corresponds to a long double 338141cc406Sopenharmony_ci argument. 339141cc406Sopenharmony_ci 340141cc406Sopenharmony_ci o A character that specifies the type of conversion to be applied. 341141cc406Sopenharmony_ci 342141cc406Sopenharmony_ci 343141cc406Sopenharmony_ci A field width or precision, or both, may be indicated by an asterisk `*' 344141cc406Sopenharmony_ci instead of a digit string. In this case, an int argument supplies the 345141cc406Sopenharmony_ci field width or precision. A negative field width is treated as a left 346141cc406Sopenharmony_ci adjustment flag followed by a positive field width; a negative precision 347141cc406Sopenharmony_ci is treated as though it were missing. 348141cc406Sopenharmony_ci 349141cc406Sopenharmony_ci The conversion specifiers and their meanings are: 350141cc406Sopenharmony_ci 351141cc406Sopenharmony_ci diouxX The int (or appropriate variant) argument is converted to signed 352141cc406Sopenharmony_ci decimal (d and i), unsigned octal (o), unsigned decimal 353141cc406Sopenharmony_ci (u), or unsigned hexadecimal (x and X) notation. The 354141cc406Sopenharmony_ci letters abcdef are used for x conversions; the letters 355141cc406Sopenharmony_ci ABCDEF are used for X conversions. The precision, if 356141cc406Sopenharmony_ci any, gives the minimum number of digits that must 357141cc406Sopenharmony_ci appear; if the converted value requires fewer digits, 358141cc406Sopenharmony_ci it is padded on the left with zeros. 359141cc406Sopenharmony_ci 360141cc406Sopenharmony_ci eE The double argument is rounded and converted in the style 361141cc406Sopenharmony_ci [-]d.ddde+-dd where there is one digit before the decimal-point 362141cc406Sopenharmony_ci character and the number of digits after it is equal 363141cc406Sopenharmony_ci to the precision; if the precision is missing, it is 364141cc406Sopenharmony_ci taken as 6; if the precision is zero, no decimal-point 365141cc406Sopenharmony_ci character appears. An E conversion uses the letter 366141cc406Sopenharmony_ci E (rather than e) to introduce the exponent. 367141cc406Sopenharmony_ci The exponent always contains at least two digits; if 368141cc406Sopenharmony_ci the value is zero, the exponent is 00. 369141cc406Sopenharmony_ci 370141cc406Sopenharmony_ci f The double argument is rounded and converted to decimal notation 371141cc406Sopenharmony_ci in the style [-]ddd.ddd, where the number of digits after the 372141cc406Sopenharmony_ci decimal-point character is equal to the precision specification. 373141cc406Sopenharmony_ci If the precision is missing, it is taken as 6; if the precision 374141cc406Sopenharmony_ci is explicitly zero, no decimal-point character appears. If a 375141cc406Sopenharmony_ci decimal point appears, at least one digit appears before it. 376141cc406Sopenharmony_ci 377141cc406Sopenharmony_ci g The double argument is converted in style f or e (or 378141cc406Sopenharmony_ci E for G conversions). The precision specifies the 379141cc406Sopenharmony_ci number of significant digits. If the precision is 380141cc406Sopenharmony_ci missing, 6 digits are given; if the precision is zero, 381141cc406Sopenharmony_ci it is treated as 1. Style e is used if the exponent 382141cc406Sopenharmony_ci from its conversion is less than -4 or greater than 383141cc406Sopenharmony_ci or equal to the precision. Trailing zeros are removed 384141cc406Sopenharmony_ci from the fractional part of the result; a decimal 385141cc406Sopenharmony_ci point appears only if it is followed by at least one 386141cc406Sopenharmony_ci digit. 387141cc406Sopenharmony_ci 388141cc406Sopenharmony_ci c The int argument is converted to an unsigned char, 389141cc406Sopenharmony_ci and the resulting character is written. 390141cc406Sopenharmony_ci 391141cc406Sopenharmony_ci s The ``char *'' argument is expected to be a pointer to an array 392141cc406Sopenharmony_ci of character type (pointer to a string). Characters 393141cc406Sopenharmony_ci from the array are written up to (but not including) 394141cc406Sopenharmony_ci a terminating NUL character; if a precision is 395141cc406Sopenharmony_ci specified, no more than the number specified are 396141cc406Sopenharmony_ci written. If a precision is given, no null character 397141cc406Sopenharmony_ci need be present; if the precision is not specified, 398141cc406Sopenharmony_ci or is greater than the size of the array, the array 399141cc406Sopenharmony_ci must contain a terminating NUL character. 400141cc406Sopenharmony_ci 401141cc406Sopenharmony_ci % A `%' is written. No argument is converted. The complete 402141cc406Sopenharmony_ci conversion specification is `%%'. 403141cc406Sopenharmony_ci 404141cc406Sopenharmony_ci In no case does a non-existent or small field width cause truncation of a 405141cc406Sopenharmony_ci field; if the result of a conversion is wider than the field width, the 406141cc406Sopenharmony_ci field is expanded to contain the conversion result. 407141cc406Sopenharmony_ci 408141cc406Sopenharmony_ci EXAMPLES 409141cc406Sopenharmony_ci To print a date and time in the form `Sunday, July 3, 10:02', where 410141cc406Sopenharmony_ci weekday and month are pointers to strings: 411141cc406Sopenharmony_ci 412141cc406Sopenharmony_ci #include <stdio.h> 413141cc406Sopenharmony_ci fprintf(stdout, "%s, %s %d, %.2d:%.2d\n", 414141cc406Sopenharmony_ci weekday, month, day, hour, min); 415141cc406Sopenharmony_ci 416141cc406Sopenharmony_ci To print pi to five decimal places: 417141cc406Sopenharmony_ci 418141cc406Sopenharmony_ci #include <math.h> 419141cc406Sopenharmony_ci #include <stdio.h> 420141cc406Sopenharmony_ci fprintf(stdout, "pi = %.5f\n", 4 * atan(1.0)); 421141cc406Sopenharmony_ci 422141cc406Sopenharmony_ci To allocate a 128 byte string and print into it: 423141cc406Sopenharmony_ci 424141cc406Sopenharmony_ci #include <stdio.h> 425141cc406Sopenharmony_ci #include <stdlib.h> 426141cc406Sopenharmony_ci #include <stdarg.h> 427141cc406Sopenharmony_ci char *newfmt(const char *fmt, ...) 428141cc406Sopenharmony_ci { 429141cc406Sopenharmony_ci char *p; 430141cc406Sopenharmony_ci va_list ap; 431141cc406Sopenharmony_ci if ((p = malloc(128)) == NULL) 432141cc406Sopenharmony_ci return (NULL); 433141cc406Sopenharmony_ci va_start(ap, fmt); 434141cc406Sopenharmony_ci (void) vsnprintf(p, 128, fmt, ap); 435141cc406Sopenharmony_ci va_end(ap); 436141cc406Sopenharmony_ci return (p); 437141cc406Sopenharmony_ci } 438141cc406Sopenharmony_ci 439141cc406Sopenharmony_ci SEE ALSO 440141cc406Sopenharmony_ci printf(1), scanf(3) 441141cc406Sopenharmony_ci 442141cc406Sopenharmony_ci STANDARDS 443141cc406Sopenharmony_ci Turkey C Standardization and wimpy POSIX folks did not define 444141cc406Sopenharmony_ci snprintf or vsnprintf(). 445141cc406Sopenharmony_ci 446141cc406Sopenharmony_ci BUGS 447141cc406Sopenharmony_ci The conversion formats %D, %O, and %U are not standard and are provided 448141cc406Sopenharmony_ci only for backward compatibility. The effect of padding the %p format 449141cc406Sopenharmony_ci with zeros (either by the `0' flag or by specifying a precision), and the 450141cc406Sopenharmony_ci benign effect (i.e., none) of the `#' flag on %n and %p conversions, as 451141cc406Sopenharmony_ci well as other nonsensical combinations such as %Ld, are not standard; 452141cc406Sopenharmony_ci such combinations should be avoided. 453141cc406Sopenharmony_ci 454141cc406Sopenharmony_ci The typedef names quad_t and u_quad_t are infelicitous. 455141cc406Sopenharmony_ci 456141cc406Sopenharmony_ci*/ 457141cc406Sopenharmony_ci 458141cc406Sopenharmony_ci 459141cc406Sopenharmony_ci#include <sys/types.h> 460141cc406Sopenharmony_ci#include <ctype.h> 461141cc406Sopenharmony_ci#include <stdlib.h> 462141cc406Sopenharmony_ci#include <stdio.h> 463141cc406Sopenharmony_ci#if defined(HAVE_STRING_H) 464141cc406Sopenharmony_ci# include <string.h> 465141cc406Sopenharmony_ci#endif 466141cc406Sopenharmony_ci#if defined(HAVE_STRINGS_H) 467141cc406Sopenharmony_ci# include <strings.h> 468141cc406Sopenharmony_ci#endif 469141cc406Sopenharmony_ci#if defined(HAVE_ERRNO_H) 470141cc406Sopenharmony_ci#include <errno.h> 471141cc406Sopenharmony_ci#endif 472141cc406Sopenharmony_ci 473141cc406Sopenharmony_ci/* 474141cc406Sopenharmony_ci * For testing, define these values 475141cc406Sopenharmony_ci */ 476141cc406Sopenharmony_ci#if 0 477141cc406Sopenharmony_ci#define HAVE_STDARG_H 1 478141cc406Sopenharmony_ci#define TEST 1 479141cc406Sopenharmony_ci#define HAVE_QUAD_T 1 480141cc406Sopenharmony_ci#endif 481141cc406Sopenharmony_ci 482141cc406Sopenharmony_ci/**** ENDINCLUDE ****/ 483141cc406Sopenharmony_ci 484141cc406Sopenharmony_ci/************************************************* 485141cc406Sopenharmony_ci * KEEP THIS STRING - MODIFY AT THE END WITH YOUR REVISIONS 486141cc406Sopenharmony_ci * i.e. - the LOCAL REVISIONS part is for your use 487141cc406Sopenharmony_ci *************************************************/ 488141cc406Sopenharmony_ci 489141cc406Sopenharmony_ci 490141cc406Sopenharmony_ci static char *const _id = "plp_snprintf V2000.08.18 Copyright Patrick Powell 1988-2000 " 491141cc406Sopenharmony_ci "$Id: plp_snprintf.c,v 1.4 2005/04/14 20:05:19 papowell Exp $" 492141cc406Sopenharmony_ci " LOCAL REVISIONS: renamed plp_snprintf to snprintf, conditionalized everything on HAVE_SNPRINTF"; 493141cc406Sopenharmony_ci 494141cc406Sopenharmony_ci/* varargs declarations: */ 495141cc406Sopenharmony_ci 496141cc406Sopenharmony_ci# undef HAVE_STDARGS /* let's hope that works everywhere (mj) */ 497141cc406Sopenharmony_ci# undef VA_LOCAL_DECL 498141cc406Sopenharmony_ci# undef VA_START 499141cc406Sopenharmony_ci# undef VA_SHIFT 500141cc406Sopenharmony_ci# undef VA_END 501141cc406Sopenharmony_ci 502141cc406Sopenharmony_ci#if defined(HAVE_STDARG_H) 503141cc406Sopenharmony_ci# include <stdarg.h> 504141cc406Sopenharmony_ci# define HAVE_STDARGS /* let's hope that works everywhere (mj) */ 505141cc406Sopenharmony_ci# define VA_LOCAL_DECL va_list ap; 506141cc406Sopenharmony_ci# define VA_START(f) va_start(ap, f) 507141cc406Sopenharmony_ci# define VA_SHIFT(v,t) ; /* no-op for ANSI */ 508141cc406Sopenharmony_ci# define VA_END va_end(ap) 509141cc406Sopenharmony_ci#else 510141cc406Sopenharmony_ci# if defined(HAVE_VARARGS_H) 511141cc406Sopenharmony_ci# include <varargs.h> 512141cc406Sopenharmony_ci# undef HAVE_STDARGS 513141cc406Sopenharmony_ci# define VA_LOCAL_DECL va_list ap; 514141cc406Sopenharmony_ci# define VA_START(f) va_start(ap) /* f is ignored! */ 515141cc406Sopenharmony_ci# define VA_SHIFT(v,t) v = va_arg(ap,t) 516141cc406Sopenharmony_ci# define VA_END va_end(ap) 517141cc406Sopenharmony_ci# else 518141cc406Sopenharmony_ci XX ** NO VARARGS ** XX 519141cc406Sopenharmony_ci# endif 520141cc406Sopenharmony_ci#endif 521141cc406Sopenharmony_ci 522141cc406Sopenharmony_ci union value { 523141cc406Sopenharmony_ci#if defined(HAVE_QUAD_T) 524141cc406Sopenharmony_ci quad_t qvalue; 525141cc406Sopenharmony_ci#endif 526141cc406Sopenharmony_ci#if defined(HAVE_LONG_LONG) 527141cc406Sopenharmony_ci long long value; 528141cc406Sopenharmony_ci#else 529141cc406Sopenharmony_ci long value; 530141cc406Sopenharmony_ci#endif 531141cc406Sopenharmony_ci double dvalue; 532141cc406Sopenharmony_ci}; 533141cc406Sopenharmony_ci 534141cc406Sopenharmony_ci#undef CVAL 535141cc406Sopenharmony_ci#define CVAL(s) (*((unsigned char *)s)) 536141cc406Sopenharmony_ci#define safestrlen(s) ((s)?strlen(s):0) 537141cc406Sopenharmony_ci 538141cc406Sopenharmony_ci 539141cc406Sopenharmony_ci static char * plp_Errormsg ( int err, char *buffer ); 540141cc406Sopenharmony_ci static void dopr( int visible_control, char **buffer, int *left, 541141cc406Sopenharmony_ci const char *format, va_list args ); 542141cc406Sopenharmony_ci static void fmtstr( int visible_control, char **buffer, int *left, 543141cc406Sopenharmony_ci char *value, int ljust, int len, int zpad, int precision ); 544141cc406Sopenharmony_ci static void fmtnum( char **buffer, int *left, 545141cc406Sopenharmony_ci union value *value, int base, int dosign, 546141cc406Sopenharmony_ci int ljust, int len, int zpad, int precision ); 547141cc406Sopenharmony_ci#if defined(HAVE_QUAD_T) 548141cc406Sopenharmony_ci static void fmtquad( char **buffer, int *left, 549141cc406Sopenharmony_ci union value *value, int base, int dosign, 550141cc406Sopenharmony_ci int ljust, int len, int zpad, int precision ); 551141cc406Sopenharmony_ci#endif 552141cc406Sopenharmony_ci static void fmtdouble( char **buffer, int *left, 553141cc406Sopenharmony_ci int fmt, double value, 554141cc406Sopenharmony_ci int ljust, int len, int zpad, int precision ); 555141cc406Sopenharmony_ci static void dostr( char **buffer, int *left, char *str ); 556141cc406Sopenharmony_ci static void dopr_outch( char **buffer, int *left, int c ); 557141cc406Sopenharmony_ci/* VARARGS3 */ 558141cc406Sopenharmony_ci#ifdef HAVE_STDARGS 559141cc406Sopenharmony_ci int plp_vsnprintf(char *str, size_t count, const char *fmt, va_list args) 560141cc406Sopenharmony_ci#else 561141cc406Sopenharmony_ci int plp_vsnprintf(char *str, size_t count, const char *fmt, va_list args) 562141cc406Sopenharmony_ci#endif 563141cc406Sopenharmony_ci 564141cc406Sopenharmony_ci{ 565141cc406Sopenharmony_ci int left; 566141cc406Sopenharmony_ci char *buffer; 567141cc406Sopenharmony_ci if( (int)count < 0 ) count = 0; 568141cc406Sopenharmony_ci left = count; 569141cc406Sopenharmony_ci if( count == 0 ) str = 0; 570141cc406Sopenharmony_ci buffer = str; 571141cc406Sopenharmony_ci dopr( 1, &buffer, &left, fmt, args ); 572141cc406Sopenharmony_ci /* fprintf(stderr,"str 0x%x, buffer 0x%x, count %d, left %d\n", 573141cc406Sopenharmony_ci (int)str, (int)buffer, count, left ); */ 574141cc406Sopenharmony_ci if( str && count > 0 ){ 575141cc406Sopenharmony_ci if( left > 0 ){ 576141cc406Sopenharmony_ci str[count-left] = 0; 577141cc406Sopenharmony_ci } else { 578141cc406Sopenharmony_ci str[count-1] = 0; 579141cc406Sopenharmony_ci } 580141cc406Sopenharmony_ci } 581141cc406Sopenharmony_ci return(count - left); 582141cc406Sopenharmony_ci} 583141cc406Sopenharmony_ci 584141cc406Sopenharmony_ci/* VARARGS3 */ 585141cc406Sopenharmony_ci#ifdef HAVE_STDARGS 586141cc406Sopenharmony_ci int plp_unsafe_vsnprintf(char *str, size_t count, const char *fmt, va_list args) 587141cc406Sopenharmony_ci#else 588141cc406Sopenharmony_ci int plp_unsafe_vsnprintf(char *str, size_t count, const char *fmt, va_list args) 589141cc406Sopenharmony_ci#endif 590141cc406Sopenharmony_ci{ 591141cc406Sopenharmony_ci int left; 592141cc406Sopenharmony_ci char *buffer; 593141cc406Sopenharmony_ci if( (int)count < 0 ) count = 0; 594141cc406Sopenharmony_ci left = count; 595141cc406Sopenharmony_ci if( count == 0 ) str = 0; 596141cc406Sopenharmony_ci buffer = str; 597141cc406Sopenharmony_ci dopr( 0, &buffer, &left, fmt, args ); 598141cc406Sopenharmony_ci /* fprintf(stderr,"str 0x%x, buffer 0x%x, count %d, left %d\n", 599141cc406Sopenharmony_ci (int)str, (int)buffer, count, left ); */ 600141cc406Sopenharmony_ci if( str && count > 0 ){ 601141cc406Sopenharmony_ci if( left > 0 ){ 602141cc406Sopenharmony_ci str[count-left] = 0; 603141cc406Sopenharmony_ci } else { 604141cc406Sopenharmony_ci str[count-1] = 0; 605141cc406Sopenharmony_ci } 606141cc406Sopenharmony_ci } 607141cc406Sopenharmony_ci return(count - left); 608141cc406Sopenharmony_ci} 609141cc406Sopenharmony_ci 610141cc406Sopenharmony_ci/* VARARGS3 */ 611141cc406Sopenharmony_ci#ifdef HAVE_STDARGS 612141cc406Sopenharmony_ci int snprintf (char *str,size_t count,const char *fmt,...) 613141cc406Sopenharmony_ci#else 614141cc406Sopenharmony_ci int snprintf (va_alist) va_dcl 615141cc406Sopenharmony_ci#endif 616141cc406Sopenharmony_ci{ 617141cc406Sopenharmony_ci#ifndef HAVE_STDARGS 618141cc406Sopenharmony_ci char *str; 619141cc406Sopenharmony_ci size_t count; 620141cc406Sopenharmony_ci char *fmt; 621141cc406Sopenharmony_ci#endif 622141cc406Sopenharmony_ci int n = 0; 623141cc406Sopenharmony_ci VA_LOCAL_DECL 624141cc406Sopenharmony_ci 625141cc406Sopenharmony_ci VA_START (fmt); 626141cc406Sopenharmony_ci VA_SHIFT (str, char *); 627141cc406Sopenharmony_ci VA_SHIFT (count, size_t ); 628141cc406Sopenharmony_ci VA_SHIFT (fmt, char *); 629141cc406Sopenharmony_ci n = plp_vsnprintf ( str, count, fmt, ap); 630141cc406Sopenharmony_ci VA_END; 631141cc406Sopenharmony_ci return( n ); 632141cc406Sopenharmony_ci} 633141cc406Sopenharmony_ci 634141cc406Sopenharmony_ci 635141cc406Sopenharmony_ci/* VARARGS3 */ 636141cc406Sopenharmony_ci#ifdef HAVE_STDARGS 637141cc406Sopenharmony_ci int plp_unsafe_snprintf (char *str,size_t count,const char *fmt,...) 638141cc406Sopenharmony_ci#else 639141cc406Sopenharmony_ci int plp_unsafe_snprintf (va_alist) va_dcl 640141cc406Sopenharmony_ci#endif 641141cc406Sopenharmony_ci{ 642141cc406Sopenharmony_ci#ifndef HAVE_STDARGS 643141cc406Sopenharmony_ci char *str; 644141cc406Sopenharmony_ci size_t count; 645141cc406Sopenharmony_ci char *fmt; 646141cc406Sopenharmony_ci#endif 647141cc406Sopenharmony_ci int n = 0; 648141cc406Sopenharmony_ci VA_LOCAL_DECL 649141cc406Sopenharmony_ci 650141cc406Sopenharmony_ci VA_START (fmt); 651141cc406Sopenharmony_ci VA_SHIFT (str, char *); 652141cc406Sopenharmony_ci VA_SHIFT (count, size_t ); 653141cc406Sopenharmony_ci VA_SHIFT (fmt, char *); 654141cc406Sopenharmony_ci n = plp_unsafe_vsnprintf ( str, count, fmt, ap); 655141cc406Sopenharmony_ci VA_END; 656141cc406Sopenharmony_ci return( n ); 657141cc406Sopenharmony_ci} 658141cc406Sopenharmony_ci static void dopr( int visible_control, char **buffer, int *left, const char *format, va_list args ) 659141cc406Sopenharmony_ci{ 660141cc406Sopenharmony_ci int ch; 661141cc406Sopenharmony_ci union value value; 662141cc406Sopenharmony_ci int longflag = 0; 663141cc406Sopenharmony_ci int quadflag = 0; 664141cc406Sopenharmony_ci char *strvalue; 665141cc406Sopenharmony_ci int ljust; 666141cc406Sopenharmony_ci int len; 667141cc406Sopenharmony_ci int zpad; 668141cc406Sopenharmony_ci int precision; 669141cc406Sopenharmony_ci int set_precision; 670141cc406Sopenharmony_ci double dval; 671141cc406Sopenharmony_ci int err = errno; 672141cc406Sopenharmony_ci int base = 0; 673141cc406Sopenharmony_ci int signed_val = 0; 674141cc406Sopenharmony_ci 675141cc406Sopenharmony_ci while( (ch = *format++) ){ 676141cc406Sopenharmony_ci switch( ch ){ 677141cc406Sopenharmony_ci case '%': 678141cc406Sopenharmony_ci longflag = quadflag = 679141cc406Sopenharmony_ci ljust = len = zpad = base = signed_val = 0; 680141cc406Sopenharmony_ci precision = -1; set_precision = 0; 681141cc406Sopenharmony_ci nextch: 682141cc406Sopenharmony_ci ch = *format++; 683141cc406Sopenharmony_ci switch( ch ){ 684141cc406Sopenharmony_ci case 0: 685141cc406Sopenharmony_ci dostr( buffer, left, "**end of format**" ); 686141cc406Sopenharmony_ci return; 687141cc406Sopenharmony_ci case '-': ljust = 1; goto nextch; 688141cc406Sopenharmony_ci case '.': set_precision = 1; precision = 0; goto nextch; 689141cc406Sopenharmony_ci case '*': 690141cc406Sopenharmony_ci if( set_precision ){ 691141cc406Sopenharmony_ci precision = va_arg( args, int ); 692141cc406Sopenharmony_ci } else { 693141cc406Sopenharmony_ci len = va_arg( args, int ); 694141cc406Sopenharmony_ci } 695141cc406Sopenharmony_ci goto nextch; 696141cc406Sopenharmony_ci case '0': /* set zero padding if len not set */ 697141cc406Sopenharmony_ci if(len==0 && set_precision == 0 ) zpad = '0'; 698141cc406Sopenharmony_ci case '1': case '2': case '3': 699141cc406Sopenharmony_ci case '4': case '5': case '6': 700141cc406Sopenharmony_ci case '7': case '8': case '9': 701141cc406Sopenharmony_ci if( set_precision ){ 702141cc406Sopenharmony_ci precision = precision*10 + ch - '0'; 703141cc406Sopenharmony_ci } else { 704141cc406Sopenharmony_ci len = len*10 + ch - '0'; 705141cc406Sopenharmony_ci } 706141cc406Sopenharmony_ci goto nextch; 707141cc406Sopenharmony_ci case 'l': ++longflag; goto nextch; 708141cc406Sopenharmony_ci case 'q': 709141cc406Sopenharmony_ci#if !defined( HAVE_QUAD_T ) 710141cc406Sopenharmony_ci dostr( buffer, left, "*no quad_t support *"); 711141cc406Sopenharmony_ci return; 712141cc406Sopenharmony_ci#endif 713141cc406Sopenharmony_ci quadflag = 1; 714141cc406Sopenharmony_ci goto nextch; 715141cc406Sopenharmony_ci case 'u': case 'U': 716141cc406Sopenharmony_ci if( base == 0 ){ base = 10; signed_val = 0; } 717141cc406Sopenharmony_ci case 'o': case 'O': 718141cc406Sopenharmony_ci if( base == 0 ){ base = 8; signed_val = 0; } 719141cc406Sopenharmony_ci case 'd': case 'D': 720141cc406Sopenharmony_ci if( base == 0 ){ base = 10; signed_val = 1; } 721141cc406Sopenharmony_ci case 'x': 722141cc406Sopenharmony_ci if( base == 0 ){ base = 16; signed_val = 0; } 723141cc406Sopenharmony_ci case 'X': 724141cc406Sopenharmony_ci if( base == 0 ){ base = -16; signed_val = 0; } 725141cc406Sopenharmony_ci#if defined( HAVE_QUAD_T ) 726141cc406Sopenharmony_ci if( quadflag ){ 727141cc406Sopenharmony_ci value.qvalue = va_arg( args, quad_t ); 728141cc406Sopenharmony_ci fmtquad( buffer, left, &value,base,signed_val, ljust, len, zpad, precision ); 729141cc406Sopenharmony_ci break; 730141cc406Sopenharmony_ci } else 731141cc406Sopenharmony_ci#endif 732141cc406Sopenharmony_ci if( longflag > 1 ){ 733141cc406Sopenharmony_ci#if defined(HAVE_LONG_LONG) 734141cc406Sopenharmony_ci if( signed_val ){ 735141cc406Sopenharmony_ci value.value = va_arg( args, long long ); 736141cc406Sopenharmony_ci } else { 737141cc406Sopenharmony_ci value.value = va_arg( args, unsigned long long ); 738141cc406Sopenharmony_ci } 739141cc406Sopenharmony_ci#else 740141cc406Sopenharmony_ci if( signed_val ){ 741141cc406Sopenharmony_ci value.value = va_arg( args, long ); 742141cc406Sopenharmony_ci } else { 743141cc406Sopenharmony_ci value.value = va_arg( args, unsigned long ); 744141cc406Sopenharmony_ci } 745141cc406Sopenharmony_ci#endif 746141cc406Sopenharmony_ci } else if( longflag ){ 747141cc406Sopenharmony_ci if( signed_val ){ 748141cc406Sopenharmony_ci value.value = va_arg( args, long ); 749141cc406Sopenharmony_ci } else { 750141cc406Sopenharmony_ci value.value = va_arg( args, unsigned long ); 751141cc406Sopenharmony_ci } 752141cc406Sopenharmony_ci } else { 753141cc406Sopenharmony_ci if( signed_val ){ 754141cc406Sopenharmony_ci value.value = va_arg( args, int ); 755141cc406Sopenharmony_ci } else { 756141cc406Sopenharmony_ci value.value = va_arg( args, unsigned int ); 757141cc406Sopenharmony_ci } 758141cc406Sopenharmony_ci } 759141cc406Sopenharmony_ci fmtnum( buffer, left, &value,base,signed_val, ljust, len, zpad, precision ); break; 760141cc406Sopenharmony_ci case 's': 761141cc406Sopenharmony_ci strvalue = va_arg( args, char *); 762141cc406Sopenharmony_ci fmtstr( visible_control, buffer, left, strvalue,ljust,len, zpad, precision ); 763141cc406Sopenharmony_ci break; 764141cc406Sopenharmony_ci case 'c': 765141cc406Sopenharmony_ci ch = va_arg( args, int ); 766141cc406Sopenharmony_ci { char b[2]; 767141cc406Sopenharmony_ci b[0] = ch; 768141cc406Sopenharmony_ci b[1] = 0; 769141cc406Sopenharmony_ci fmtstr( 0, buffer, left, b,ljust,len, zpad, precision ); 770141cc406Sopenharmony_ci } 771141cc406Sopenharmony_ci break; 772141cc406Sopenharmony_ci case 'f': case 'g': case 'e': 773141cc406Sopenharmony_ci dval = va_arg( args, double ); 774141cc406Sopenharmony_ci fmtdouble( buffer, left, ch, dval,ljust,len, zpad, precision ); break; 775141cc406Sopenharmony_ci case 'm': 776141cc406Sopenharmony_ci { char shortbuffer[32]; 777141cc406Sopenharmony_ci fmtstr( visible_control, buffer, left, 778141cc406Sopenharmony_ci plp_Errormsg(err, shortbuffer),ljust,len, zpad, precision ); 779141cc406Sopenharmony_ci } 780141cc406Sopenharmony_ci break; 781141cc406Sopenharmony_ci case '%': dopr_outch( buffer, left, ch ); continue; 782141cc406Sopenharmony_ci default: 783141cc406Sopenharmony_ci dostr( buffer, left, "???????" ); 784141cc406Sopenharmony_ci } 785141cc406Sopenharmony_ci longflag = 0; 786141cc406Sopenharmony_ci break; 787141cc406Sopenharmony_ci default: 788141cc406Sopenharmony_ci dopr_outch( buffer, left, ch ); 789141cc406Sopenharmony_ci break; 790141cc406Sopenharmony_ci } 791141cc406Sopenharmony_ci } 792141cc406Sopenharmony_ci} 793141cc406Sopenharmony_ci 794141cc406Sopenharmony_ci/* 795141cc406Sopenharmony_ci * Format '%[-]len[.precision]s' 796141cc406Sopenharmony_ci * - = left justify (ljust) 797141cc406Sopenharmony_ci * len = minimum length 798141cc406Sopenharmony_ci * precision = numbers of chars in string to use 799141cc406Sopenharmony_ci */ 800141cc406Sopenharmony_ci static void 801141cc406Sopenharmony_ci fmtstr( int visible_control, char **buffer, int *left, 802141cc406Sopenharmony_ci char *value, int ljust, int len, int zpad, int precision ) 803141cc406Sopenharmony_ci{ 804141cc406Sopenharmony_ci int padlen, strlenv, i, c; /* amount to pad */ 805141cc406Sopenharmony_ci 806141cc406Sopenharmony_ci if( value == 0 ){ 807141cc406Sopenharmony_ci value = "<NULL>"; 808141cc406Sopenharmony_ci } 809141cc406Sopenharmony_ci /* cheap strlen so you do not have library call */ 810141cc406Sopenharmony_ci for( strlenv = i = 0; (c=CVAL(value+i)); ++i ){ 811141cc406Sopenharmony_ci if( visible_control && iscntrl( c ) && c != '\t' && c != '\n' ){ 812141cc406Sopenharmony_ci ++strlenv; 813141cc406Sopenharmony_ci } 814141cc406Sopenharmony_ci ++strlenv; 815141cc406Sopenharmony_ci } 816141cc406Sopenharmony_ci if( precision > 0 && strlenv > precision ){ 817141cc406Sopenharmony_ci strlenv = precision; 818141cc406Sopenharmony_ci } 819141cc406Sopenharmony_ci padlen = len - strlenv; 820141cc406Sopenharmony_ci if( padlen < 0 ) padlen = 0; 821141cc406Sopenharmony_ci if( ljust ) padlen = -padlen; 822141cc406Sopenharmony_ci while( padlen > 0 ) { 823141cc406Sopenharmony_ci dopr_outch( buffer, left, ' ' ); 824141cc406Sopenharmony_ci --padlen; 825141cc406Sopenharmony_ci } 826141cc406Sopenharmony_ci /* output characters */ 827141cc406Sopenharmony_ci for( i = 0; i < strlenv && (c = CVAL(value+i)); ++i ){ 828141cc406Sopenharmony_ci if( visible_control && iscntrl( c ) && c != '\t' && c != '\n' ){ 829141cc406Sopenharmony_ci dopr_outch(buffer, left, '^'); 830141cc406Sopenharmony_ci c = ('@' | (c & 0x1F)); 831141cc406Sopenharmony_ci } 832141cc406Sopenharmony_ci dopr_outch(buffer, left, c); 833141cc406Sopenharmony_ci } 834141cc406Sopenharmony_ci while( padlen < 0 ) { 835141cc406Sopenharmony_ci dopr_outch( buffer, left, ' ' ); 836141cc406Sopenharmony_ci ++padlen; 837141cc406Sopenharmony_ci } 838141cc406Sopenharmony_ci} 839141cc406Sopenharmony_ci 840141cc406Sopenharmony_ci static void 841141cc406Sopenharmony_ci fmtnum( char **buffer, int *left, 842141cc406Sopenharmony_ci union value *value, int base, int dosign, int ljust, 843141cc406Sopenharmony_ci int len, int zpad, int precision ) 844141cc406Sopenharmony_ci{ 845141cc406Sopenharmony_ci int signvalue = 0; 846141cc406Sopenharmony_ci#if defined(HAVE_LONG_LONG) 847141cc406Sopenharmony_ci unsigned long long uvalue; 848141cc406Sopenharmony_ci#else 849141cc406Sopenharmony_ci unsigned long uvalue; 850141cc406Sopenharmony_ci#endif 851141cc406Sopenharmony_ci char convert[sizeof( union value) * 8 + 16]; 852141cc406Sopenharmony_ci int place = 0; 853141cc406Sopenharmony_ci int padlen = 0; /* amount to pad */ 854141cc406Sopenharmony_ci int caps = 0; 855141cc406Sopenharmony_ci 856141cc406Sopenharmony_ci /* fprintf(stderr,"value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", 857141cc406Sopenharmony_ci value, base, dosign, ljust, len, zpad );/ **/ 858141cc406Sopenharmony_ci uvalue = value->value; 859141cc406Sopenharmony_ci if( dosign ){ 860141cc406Sopenharmony_ci if( value->value < 0 ) { 861141cc406Sopenharmony_ci signvalue = '-'; 862141cc406Sopenharmony_ci uvalue = -value->value; 863141cc406Sopenharmony_ci } 864141cc406Sopenharmony_ci } 865141cc406Sopenharmony_ci if( base < 0 ){ 866141cc406Sopenharmony_ci caps = 1; 867141cc406Sopenharmony_ci base = -base; 868141cc406Sopenharmony_ci } 869141cc406Sopenharmony_ci do{ 870141cc406Sopenharmony_ci convert[place++] = 871141cc406Sopenharmony_ci (caps? "0123456789ABCDEF":"0123456789abcdef") 872141cc406Sopenharmony_ci [uvalue % (unsigned)base ]; 873141cc406Sopenharmony_ci uvalue = (uvalue / (unsigned)base ); 874141cc406Sopenharmony_ci }while(uvalue); 875141cc406Sopenharmony_ci convert[place] = 0; 876141cc406Sopenharmony_ci padlen = len - place; 877141cc406Sopenharmony_ci if( padlen < 0 ) padlen = 0; 878141cc406Sopenharmony_ci if( ljust ) padlen = -padlen; 879141cc406Sopenharmony_ci /* fprintf( stderr, "str '%s', place %d, sign %c, padlen %d\n", 880141cc406Sopenharmony_ci convert,place,signvalue,padlen); / **/ 881141cc406Sopenharmony_ci if( zpad && padlen > 0 ){ 882141cc406Sopenharmony_ci if( signvalue ){ 883141cc406Sopenharmony_ci dopr_outch( buffer, left, signvalue ); 884141cc406Sopenharmony_ci --padlen; 885141cc406Sopenharmony_ci signvalue = 0; 886141cc406Sopenharmony_ci } 887141cc406Sopenharmony_ci while( padlen > 0 ){ 888141cc406Sopenharmony_ci dopr_outch( buffer, left, zpad ); 889141cc406Sopenharmony_ci --padlen; 890141cc406Sopenharmony_ci } 891141cc406Sopenharmony_ci } 892141cc406Sopenharmony_ci while( padlen > 0 ) { 893141cc406Sopenharmony_ci dopr_outch( buffer, left, ' ' ); 894141cc406Sopenharmony_ci --padlen; 895141cc406Sopenharmony_ci } 896141cc406Sopenharmony_ci if( signvalue ) dopr_outch( buffer, left, signvalue ); 897141cc406Sopenharmony_ci while( place > 0 ) dopr_outch( buffer, left, convert[--place] ); 898141cc406Sopenharmony_ci while( padlen < 0 ){ 899141cc406Sopenharmony_ci dopr_outch( buffer, left, ' ' ); 900141cc406Sopenharmony_ci ++padlen; 901141cc406Sopenharmony_ci } 902141cc406Sopenharmony_ci} 903141cc406Sopenharmony_ci 904141cc406Sopenharmony_ci#if defined(HAVE_QUAD_T) 905141cc406Sopenharmony_ci 906141cc406Sopenharmony_ci static void 907141cc406Sopenharmony_ci fmtquad( char **buffer, int *left, 908141cc406Sopenharmony_ci union value *value, int base, int dosign, int ljust, 909141cc406Sopenharmony_ci int len, int zpad, int precision ) 910141cc406Sopenharmony_ci{ 911141cc406Sopenharmony_ci int signvalue = 0; 912141cc406Sopenharmony_ci int place = 0; 913141cc406Sopenharmony_ci int padlen = 0; /* amount to pad */ 914141cc406Sopenharmony_ci int caps = 0; 915141cc406Sopenharmony_ci int i, c; 916141cc406Sopenharmony_ci union { 917141cc406Sopenharmony_ci quad_t qvalue; 918141cc406Sopenharmony_ci unsigned char qconvert[sizeof(quad_t)]; 919141cc406Sopenharmony_ci } vvalue; 920141cc406Sopenharmony_ci char convert[2*sizeof(quad_t)+1]; 921141cc406Sopenharmony_ci 922141cc406Sopenharmony_ci /* fprintf(stderr,"value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", 923141cc406Sopenharmony_ci value, base, dosign, ljust, len, zpad );/ **/ 924141cc406Sopenharmony_ci vvalue.qvalue = value->qvalue; 925141cc406Sopenharmony_ci 926141cc406Sopenharmony_ci if( base < 0 ){ 927141cc406Sopenharmony_ci caps = 1; 928141cc406Sopenharmony_ci } 929141cc406Sopenharmony_ci 930141cc406Sopenharmony_ci for( i = 0; i < (int)sizeof(quad_t); ++i ){ 931141cc406Sopenharmony_ci c = vvalue.qconvert[i]; 932141cc406Sopenharmony_ci convert[2*i] = 933141cc406Sopenharmony_ci (caps? "0123456789ABCDEF":"0123456789abcdef")[ (c >> 4) & 0xF]; 934141cc406Sopenharmony_ci convert[2*i+1] = 935141cc406Sopenharmony_ci (caps? "0123456789ABCDEF":"0123456789abcdef")[ c & 0xF]; 936141cc406Sopenharmony_ci } 937141cc406Sopenharmony_ci convert[2*i] = 0; 938141cc406Sopenharmony_ci 939141cc406Sopenharmony_ci place = strlen(convert); 940141cc406Sopenharmony_ci padlen = len - place; 941141cc406Sopenharmony_ci if( padlen < 0 ) padlen = 0; 942141cc406Sopenharmony_ci if( ljust ) padlen = -padlen; 943141cc406Sopenharmony_ci /* fprintf( stderr, "str '%s', place %d, sign %c, padlen %d\n", 944141cc406Sopenharmony_ci convert,place,signvalue,padlen); / **/ 945141cc406Sopenharmony_ci if( zpad && padlen > 0 ){ 946141cc406Sopenharmony_ci if( signvalue ){ 947141cc406Sopenharmony_ci dopr_outch( buffer, left, signvalue ); 948141cc406Sopenharmony_ci --padlen; 949141cc406Sopenharmony_ci signvalue = 0; 950141cc406Sopenharmony_ci } 951141cc406Sopenharmony_ci while( padlen > 0 ){ 952141cc406Sopenharmony_ci dopr_outch( buffer, left, zpad ); 953141cc406Sopenharmony_ci --padlen; 954141cc406Sopenharmony_ci } 955141cc406Sopenharmony_ci } 956141cc406Sopenharmony_ci while( padlen > 0 ) { 957141cc406Sopenharmony_ci dopr_outch( buffer, left, ' ' ); 958141cc406Sopenharmony_ci --padlen; 959141cc406Sopenharmony_ci } 960141cc406Sopenharmony_ci if( signvalue ) dopr_outch( buffer, left, signvalue ); 961141cc406Sopenharmony_ci while( place > 0 ) dopr_outch( buffer, left, convert[--place] ); 962141cc406Sopenharmony_ci while( padlen < 0 ){ 963141cc406Sopenharmony_ci dopr_outch( buffer, left, ' ' ); 964141cc406Sopenharmony_ci ++padlen; 965141cc406Sopenharmony_ci } 966141cc406Sopenharmony_ci} 967141cc406Sopenharmony_ci 968141cc406Sopenharmony_ci#endif 969141cc406Sopenharmony_ci 970141cc406Sopenharmony_ci static void mystrcat(char *dest, char *src ) 971141cc406Sopenharmony_ci{ 972141cc406Sopenharmony_ci if( dest && src ){ 973141cc406Sopenharmony_ci dest += safestrlen(dest); 974141cc406Sopenharmony_ci strcpy(dest,src); 975141cc406Sopenharmony_ci } 976141cc406Sopenharmony_ci} 977141cc406Sopenharmony_ci 978141cc406Sopenharmony_ci static void 979141cc406Sopenharmony_ci fmtdouble( char **buffer, int *left, 980141cc406Sopenharmony_ci int fmt, double value, int ljust, int len, int zpad, int precision ) 981141cc406Sopenharmony_ci{ 982141cc406Sopenharmony_ci char convert[sizeof( union value) * 8 + 512]; 983141cc406Sopenharmony_ci char formatstr[128]; 984141cc406Sopenharmony_ci 985141cc406Sopenharmony_ci /* fprintf(stderr,"len %d, precision %d\n", len, precision ); */ 986141cc406Sopenharmony_ci if( len > 255 ){ 987141cc406Sopenharmony_ci len = 255; 988141cc406Sopenharmony_ci } 989141cc406Sopenharmony_ci if( precision > 255 ){ 990141cc406Sopenharmony_ci precision = 255; 991141cc406Sopenharmony_ci } 992141cc406Sopenharmony_ci if( precision >= 0 && len > 0 && precision > len ) precision = len; 993141cc406Sopenharmony_ci strcpy( formatstr, "%" ); /* 1 */ 994141cc406Sopenharmony_ci if( ljust ) mystrcat(formatstr, "-" ); /* 1 */ 995141cc406Sopenharmony_ci if( zpad ) mystrcat(formatstr, "0" ); /* 1 */ 996141cc406Sopenharmony_ci if( len >= 0 ){ 997141cc406Sopenharmony_ci sprintf( formatstr+strlen(formatstr), "%d", len ); /* 3 */ 998141cc406Sopenharmony_ci } 999141cc406Sopenharmony_ci if( precision >= 0 ){ 1000141cc406Sopenharmony_ci sprintf( formatstr+strlen(formatstr), ".%d", precision ); /* 3 */ 1001141cc406Sopenharmony_ci } 1002141cc406Sopenharmony_ci /* format string will be at most 10 chars long ... */ 1003141cc406Sopenharmony_ci sprintf( formatstr+strlen(formatstr), "%c", fmt ); 1004141cc406Sopenharmony_ci /* this is easier than trying to do the portable dtostr */ 1005141cc406Sopenharmony_ci /* fprintf(stderr,"format string '%s'\n", formatstr); */ 1006141cc406Sopenharmony_ci sprintf( convert, formatstr, value ); 1007141cc406Sopenharmony_ci dostr( buffer, left, convert ); 1008141cc406Sopenharmony_ci} 1009141cc406Sopenharmony_ci 1010141cc406Sopenharmony_ci static void dostr( char **buffer, int *left, char *str ) 1011141cc406Sopenharmony_ci{ 1012141cc406Sopenharmony_ci if(str)while(*str) dopr_outch( buffer, left, *str++ ); 1013141cc406Sopenharmony_ci} 1014141cc406Sopenharmony_ci 1015141cc406Sopenharmony_ci static void dopr_outch( char **buffer, int *left, int c ) 1016141cc406Sopenharmony_ci{ 1017141cc406Sopenharmony_ci if( *left > 0 ){ 1018141cc406Sopenharmony_ci *(*buffer)++ = c; 1019141cc406Sopenharmony_ci } 1020141cc406Sopenharmony_ci *left -= 1; 1021141cc406Sopenharmony_ci} 1022141cc406Sopenharmony_ci 1023141cc406Sopenharmony_ci 1024141cc406Sopenharmony_ci/**************************************************************************** 1025141cc406Sopenharmony_ci * static char *plp_errormsg( int err ) 1026141cc406Sopenharmony_ci * returns a printable form of the 1027141cc406Sopenharmony_ci * errormessage corresponding to the valie of err. 1028141cc406Sopenharmony_ci * This is the poor man's version of sperror(), not available on all systems 1029141cc406Sopenharmony_ci * Patrick Powell Tue Apr 11 08:05:05 PDT 1995 1030141cc406Sopenharmony_ci ****************************************************************************/ 1031141cc406Sopenharmony_ci/****************************************************************************/ 1032141cc406Sopenharmony_ci 1033141cc406Sopenharmony_ci#if !defined(HAVE_STRERROR) 1034141cc406Sopenharmony_ci# undef num_errors 1035141cc406Sopenharmony_ci# if defined(HAVE_SYS_ERRLIST) 1036141cc406Sopenharmony_ci# if !defined(HAVE_DECL_SYS_ERRLIST) 1037141cc406Sopenharmony_ci extern const char *const sys_errlist[]; 1038141cc406Sopenharmony_ci# endif 1039141cc406Sopenharmony_ci# if defined(HAVE_SYS_NERR) 1040141cc406Sopenharmony_ci# if !defined(HAVE_DECL_SYS_NERR) 1041141cc406Sopenharmony_ci extern int sys_nerr; 1042141cc406Sopenharmony_ci# endif 1043141cc406Sopenharmony_ci# define num_errors (sys_nerr) 1044141cc406Sopenharmony_ci# endif 1045141cc406Sopenharmony_ci# endif 1046141cc406Sopenharmony_ci# if !defined(num_errors) 1047141cc406Sopenharmony_ci# define num_errors (-1) /* always use "errno=%d" */ 1048141cc406Sopenharmony_ci# endif 1049141cc406Sopenharmony_ci#endif 1050141cc406Sopenharmony_ci 1051141cc406Sopenharmony_ci static char * plp_Errormsg ( int err, char *buffer /* int maxlen = 32 */) 1052141cc406Sopenharmony_ci{ 1053141cc406Sopenharmony_ci char *cp; 1054141cc406Sopenharmony_ci 1055141cc406Sopenharmony_ci#if defined(HAVE_STRERROR) 1056141cc406Sopenharmony_ci cp = (void *)strerror(err); 1057141cc406Sopenharmony_ci#else 1058141cc406Sopenharmony_ci# if defined(HAVE_SYS_ERRLIST) 1059141cc406Sopenharmony_ci if (err >= 0 && err < num_errors) { 1060141cc406Sopenharmony_ci cp = (void *)sys_errlist[err]; 1061141cc406Sopenharmony_ci } else 1062141cc406Sopenharmony_ci# endif 1063141cc406Sopenharmony_ci { 1064141cc406Sopenharmony_ci (void) sprintf (buffer, "errno=%d", err); 1065141cc406Sopenharmony_ci cp = buffer; 1066141cc406Sopenharmony_ci } 1067141cc406Sopenharmony_ci#endif 1068141cc406Sopenharmony_ci return (cp); 1069141cc406Sopenharmony_ci} 1070141cc406Sopenharmony_ci 1071141cc406Sopenharmony_ci#if defined(TEST) 1072141cc406Sopenharmony_ci#include <stdio.h> 1073141cc406Sopenharmony_ci int main( void ) 1074141cc406Sopenharmony_ci{ 1075141cc406Sopenharmony_ci char buffer[128]; 1076141cc406Sopenharmony_ci char *t; 1077141cc406Sopenharmony_ci char *test1 = "01234"; 1078141cc406Sopenharmony_ci int n; 1079141cc406Sopenharmony_ci errno = 1; 1080141cc406Sopenharmony_ci buffer[0] = 0; 1081141cc406Sopenharmony_ci n = snprintf( buffer, 0, (t="test")); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1082141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t="errno '%m'")); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1083141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1084141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%12s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1085141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%-12s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1086141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%12.2s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1087141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%-12.2s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1088141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1089141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%g"), 1.2345 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1090141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%12g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1091141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%12.1g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1092141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%12.2g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1093141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%12.3g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1094141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%0*d"), 6, 1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1095141cc406Sopenharmony_ci#if defined(HAVE_LONG_LONG) 1096141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%llx"), 1, 2, 3, 4 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1097141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%llx"), (long long)1, (long long)2 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1098141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%qx"), 1, 2, 3, 4 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1099141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%qx"), (quad_t)1, (quad_t)2 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1100141cc406Sopenharmony_ci#endif 1101141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "0%x, 0%x"), (char *)(0x01234567), (char *)0, 0, 0, 0); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1102141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "0%x, 0%x"), (char *)(0x01234567), (char *)0x89ABCDEF, 0, 0, 0); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1103141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "0%x, 0%x"), t, 0, 0, 0, 0); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1104141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%f"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1105141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%f"), 1.2345 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1106141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%12f"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1107141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%12.2f"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1108141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1109141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%.0f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1110141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%0.0f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1111141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%1.0f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1112141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%1.5f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1113141cc406Sopenharmony_ci n = snprintf( buffer, sizeof(buffer), (t = "%5.5f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); 1114141cc406Sopenharmony_ci return(0); 1115141cc406Sopenharmony_ci} 1116141cc406Sopenharmony_ci#endif 1117141cc406Sopenharmony_ci 1118141cc406Sopenharmony_ci 1119141cc406Sopenharmony_ci#endif /* HAVE_SNPRINTF */ 1120