Index: head/include/inttypes.h =================================================================== --- head/include/inttypes.h (revision 103011) +++ head/include/inttypes.h (revision 103012) @@ -1,58 +1,58 @@ /*- * Copyright (c) 2001 Mike Barcroft * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _INTTYPES_H_ #define _INTTYPES_H_ #include #include #ifndef __cplusplus #ifndef _WCHAR_T_DECLARED typedef __wchar_t wchar_t; #define _WCHAR_T_DECLARED #endif #endif typedef struct { intmax_t quot; /* Quotient. */ intmax_t rem; /* Remainder. */ } imaxdiv_t; __BEGIN_DECLS intmax_t imaxabs(intmax_t) __pure2; imaxdiv_t imaxdiv(intmax_t, intmax_t) __pure2; -intmax_t strtoimax(const char *__restrict, char **__restrict, int); -uintmax_t strtoumax(const char *__restrict, char **__restrict, int); +intmax_t strtoimax(const char * __restrict, char ** __restrict, int); +uintmax_t strtoumax(const char * __restrict, char ** __restrict, int); /* XXX: The following functions are missing the restrict type qualifier. */ intmax_t wcstoimax(const wchar_t *, wchar_t **, int); uintmax_t wcstoumax(const wchar_t *, wchar_t **, int); __END_DECLS #endif /* !_INTTYPES_H_ */ Index: head/include/search.h =================================================================== --- head/include/search.h (revision 103011) +++ head/include/search.h (revision 103012) @@ -1,54 +1,54 @@ /* $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $ */ /* $FreeBSD$ */ /* * Written by J.T. Conklin * Public domain. */ #ifndef _SEARCH_H_ #define _SEARCH_H_ #include #include #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif typedef struct entry { char *key; void *data; } ENTRY; typedef enum { FIND, ENTER } ACTION; typedef enum { preorder, postorder, endorder, leaf } VISIT; #ifdef _SEARCH_PRIVATE typedef struct node { char *key; struct node *llink, *rlink; } node_t; #endif __BEGIN_DECLS int hcreate(size_t); void hdestroy(void); ENTRY *hsearch(ENTRY, ACTION); -void *tdelete(const void *__restrict, void **__restrict, +void *tdelete(const void * __restrict, void ** __restrict, int (*)(const void *, const void *)); void *tfind(const void *, void **, int (*)(const void *, const void *)); void *tsearch(const void *, void **, int (*)(const void *, const void *)); void twalk(const void *, void (*)(const void *, VISIT, int)); __END_DECLS #endif /* !_SEARCH_H_ */ Index: head/include/stdio.h =================================================================== --- head/include/stdio.h (revision 103011) +++ head/include/stdio.h (revision 103012) @@ -1,437 +1,437 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)stdio.h 8.5 (Berkeley) 4/29/95 * $FreeBSD$ */ #ifndef _STDIO_H_ #define _STDIO_H_ #include #include #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #ifndef NULL #define NULL 0 #endif typedef __off_t fpos_t; #define _FSTDIO /* Define for new stdio with functions. */ /* * NB: to fit things in six character monocase externals, the stdio * code uses the prefix `__s' for stdio objects, typically followed * by a three-character attempt at a mnemonic. */ /* stdio buffers */ struct __sbuf { unsigned char *_base; int _size; }; /* hold a buncha junk that would grow the ABI */ struct __sFILEX; /* * stdio state variables. * * The following always hold: * * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR), * _lbfsize is -_bf._size, else _lbfsize is 0 * if _flags&__SRD, _w is 0 * if _flags&__SWR, _r is 0 * * This ensures that the getc and putc macros (or inline functions) never * try to write or read from a file that is in `read' or `write' mode. * (Moreover, they can, and do, automatically switch from read mode to * write mode, and back, on "r+" and "w+" files.) * * _lbfsize is used only to make the inline line-buffered output stream * code as compact as possible. * * _ub, _up, and _ur are used when ungetc() pushes back more characters * than fit in the current _bf, or when ungetc() pushes back a character * that does not match the previous one in _bf. When this happens, * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff * _ub._base!=NULL) and _up and _ur save the current values of _p and _r. * * NB: see WARNING above before changing the layout of this structure! */ typedef struct __sFILE { unsigned char *_p; /* current position in (some) buffer */ int _r; /* read space left for getc() */ int _w; /* write space left for putc() */ short _flags; /* flags, below; this FILE is free if 0 */ short _file; /* fileno, if Unix descriptor, else -1 */ struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */ int _lbfsize; /* 0 or -_bf._size, for inline putc */ /* operations */ void *_cookie; /* cookie passed to io functions */ int (*_close)(void *); int (*_read)(void *, char *, int); fpos_t (*_seek)(void *, fpos_t, int); int (*_write)(void *, const char *, int); /* separate buffer for long sequences of ungetc() */ struct __sbuf _ub; /* ungetc buffer */ struct __sFILEX *_extra; /* additions to FILE to not break ABI */ int _ur; /* saved _r when _r is counting ungetc data */ /* tricks to meet minimum requirements even when malloc() fails */ unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */ unsigned char _nbuf[1]; /* guarantee a getc() buffer */ /* separate buffer for fgetln() when line crosses buffer boundary */ struct __sbuf _lb; /* buffer for fgetln() */ /* Unix stdio files get aligned to block boundaries on fseek() */ int _blksize; /* stat.st_blksize (may be != _bf._size) */ fpos_t _offset; /* current lseek offset (see WARNING) */ } FILE; __BEGIN_DECLS extern FILE __sF[]; extern FILE *__stdinp; extern FILE *__stdoutp; extern FILE *__stderrp; __END_DECLS #define __SLBF 0x0001 /* line buffered */ #define __SNBF 0x0002 /* unbuffered */ #define __SRD 0x0004 /* OK to read */ #define __SWR 0x0008 /* OK to write */ /* RD and WR are never simultaneously asserted */ #define __SRW 0x0010 /* open for reading & writing */ #define __SEOF 0x0020 /* found EOF */ #define __SERR 0x0040 /* found error */ #define __SMBF 0x0080 /* _buf is from malloc */ #define __SAPP 0x0100 /* fdopen()ed in append mode */ #define __SSTR 0x0200 /* this is an sprintf/snprintf string */ #define __SOPT 0x0400 /* do fseek() optimization */ #define __SNPT 0x0800 /* do not do fseek() optimization */ #define __SOFF 0x1000 /* set iff _offset is in fact correct */ #define __SMOD 0x2000 /* true => fgetln modified _p text */ #define __SALC 0x4000 /* allocate string space dynamically */ #define __SIGN 0x8000 /* ignore this file in _fwalk */ /* * The following three definitions are for ANSI C, which took them * from System V, which brilliantly took internal interface macros and * made them official arguments to setvbuf(), without renaming them. * Hence, these ugly _IOxxx names are *supposed* to appear in user code. * * Although numbered as their counterparts above, the implementation * does not rely on this. */ #define _IOFBF 0 /* setvbuf should set fully buffered */ #define _IOLBF 1 /* setvbuf should set line buffered */ #define _IONBF 2 /* setvbuf should set unbuffered */ #define BUFSIZ 1024 /* size of buffer used by setbuf */ #define EOF (-1) /* * FOPEN_MAX is a minimum maximum, and is the number of streams that * stdio can provide without attempting to allocate further resources * (which could fail). Do not use this for anything. */ /* must be == _POSIX_STREAM_MAX */ #define FOPEN_MAX 20 /* must be <= OPEN_MAX */ #define FILENAME_MAX 1024 /* must be <= PATH_MAX */ /* System V/ANSI C; this is the wrong way to do this, do *not* use these. */ #if __XSI_VISIBLE #define P_tmpdir "/var/tmp/" #endif #define L_tmpnam 1024 /* XXX must be == PATH_MAX */ #define TMP_MAX 308915776 #ifndef SEEK_SET #define SEEK_SET 0 /* set file offset to offset */ #endif #ifndef SEEK_CUR #define SEEK_CUR 1 /* set file offset to current plus offset */ #endif #ifndef SEEK_END #define SEEK_END 2 /* set file offset to EOF plus offset */ #endif /* To be removed by 5.0-RELEASE */ #if (defined(__i386__) || defined(__alpha__)) && defined(_OLD_STDIO) #define stdin (&__sF[0]) #define stdout (&__sF[1]) #define stderr (&__sF[2]) #else #define stdin __stdinp #define stdout __stdoutp #define stderr __stderrp #endif __BEGIN_DECLS /* * Functions defined in ANSI C standard. */ void clearerr(FILE *); int fclose(FILE *); int feof(FILE *); int ferror(FILE *); int fflush(FILE *); int fgetc(FILE *); int fgetpos(FILE *, fpos_t *); char *fgets(char *, int, FILE *); FILE *fopen(const char *, const char *); -int fprintf(FILE *__restrict, const char *__restrict, ...); +int fprintf(FILE * __restrict, const char * __restrict, ...); int fputc(int, FILE *); int fputs(const char *, FILE *); size_t fread(void *, size_t, size_t, FILE *); FILE *freopen(const char *, const char *, FILE *); int fscanf(FILE *, const char *, ...); int fseek(FILE *, long, int); int fsetpos(FILE *, const fpos_t *); long ftell(FILE *); size_t fwrite(const void *, size_t, size_t, FILE *); int getc(FILE *); int getchar(void); char *gets(char *); void perror(const char *); -int printf(const char *__restrict, ...); +int printf(const char * __restrict, ...); int putc(int, FILE *); int putchar(int); int puts(const char *); int remove(const char *); int rename(const char *, const char *); void rewind(FILE *); int scanf(const char *, ...); -void setbuf(FILE *__restrict, char *__restrict); -int setvbuf(FILE *__restrict, char *__restrict, int, size_t); -int sprintf(char *__restrict, const char *__restrict, ...); +void setbuf(FILE * __restrict, char * __restrict); +int setvbuf(FILE * __restrict, char * __restrict, int, size_t); +int sprintf(char * __restrict, const char * __restrict, ...); int sscanf(const char *, const char *, ...); FILE *tmpfile(void); char *tmpnam(char *); int ungetc(int, FILE *); -int vfprintf(FILE *__restrict, const char *__restrict, +int vfprintf(FILE * __restrict, const char * __restrict, __va_list); -int vprintf(const char *__restrict, __va_list); -int vsprintf(char *__restrict, const char *__restrict, +int vprintf(const char * __restrict, __va_list); +int vsprintf(char * __restrict, const char * __restrict, __va_list); #if __ISO_C_VISIBLE >= 1999 -int snprintf(char *__restrict, size_t, const char *__restrict, +int snprintf(char * __restrict, size_t, const char * __restrict, ...) __printflike(3, 4); -int vsnprintf(char *__restrict, size_t, const char *__restrict, +int vsnprintf(char * __restrict, size_t, const char * __restrict, __va_list) __printflike(3, 0); #endif /* * Functions defined in all versions of POSIX 1003.1. */ #if __POSIX_VISIBLE /* size for cuserid(3); UT_NAMESIZE + 1, see */ #define L_cuserid 17 #define L_ctermid 1024 /* size for ctermid(3); PATH_MAX */ char *ctermid(char *); FILE *fdopen(int, const char *); int fileno(FILE *); #endif /* __POSIX_VISIBLE */ #if __POSIX_VISIBLE >= 199209 int pclose(FILE *); FILE *popen(const char *, const char *); #endif #if __POSIX_VISIBLE >= 199506 int ftrylockfile(FILE *); void flockfile(FILE *); void funlockfile(FILE *); /* * These are normally used through macros as defined below, but POSIX * requires functions as well. */ int getc_unlocked(FILE *); int getchar_unlocked(void); int putc_unlocked(int, FILE *); int putchar_unlocked(int); #endif #if __POSIX_VISIBLE >= 200112 int fseeko(FILE *, __off_t, int); __off_t ftello(FILE *); #endif #if __BSD_VISIBLE || __XSI_VISIBLE > 0 && __XSI_VISIBLE < 600 int getw(FILE *); int putw(int, FILE *); #endif /* BSD or X/Open before issue 6 */ #if __XSI_VISIBLE char *tempnam(const char *, const char *); #endif /* * Routines that are purely local. */ #if __BSD_VISIBLE int asprintf(char **, const char *, ...) __printflike(2, 3); char *ctermid_r(char *); char *fgetln(FILE *, size_t *); #if __GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ >= 3 #define __ATTR_FORMAT_ARG __attribute__((__format_arg__(2))) #else #define __ATTR_FORMAT_ARG #endif __const char *fmtcheck(const char *, const char *) __ATTR_FORMAT_ARG; int fpurge(FILE *); void setbuffer(FILE *, char *, int); int setlinebuf(FILE *); int vasprintf(char **, const char *, __va_list) __printflike(2, 0); int vscanf(const char *, __va_list) __scanflike(1, 0); int vsscanf(const char *, const char *, __va_list) __scanflike(2, 0); /* * The system error table contains messages for the first sys_nerr * positive errno values. Use strerror() or strerror_r() from * instead. */ extern __const int sys_nerr; extern __const char *__const sys_errlist[]; /* * This is a #define because the function is used internally and * (unlike vfscanf) the name __vfscanf is guaranteed not to collide * with a user function when _ANSI_SOURCE or _POSIX_SOURCE is defined. */ #define vfscanf __vfscanf /* * Stdio function-access interface. */ FILE *funopen(const void *, int (*)(void *, char *, int), int (*)(void *, const char *, int), fpos_t (*)(void *, fpos_t, int), int (*)(void *)); #define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0) #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) /* * Portability hacks. See . */ #ifndef _FTRUNCATE_DECLARED #define _FTRUNCATE_DECLARED int ftruncate(int, __off_t); #endif #ifndef _LSEEK_DECLARED #define _LSEEK_DECLARED __off_t lseek(int, __off_t, int); #endif #ifndef _MMAP_DECLARED #define _MMAP_DECLARED void *mmap(void *, size_t, int, int, int, __off_t); #endif #ifndef _TRUNCATE_DECLARED #define _TRUNCATE_DECLARED int truncate(const char *, __off_t); #endif #endif /* __BSD_VISIBLE */ /* * Functions internal to the implementation. */ int __srget(FILE *); int __vfscanf(FILE *, const char *, __va_list); int __svfscanf(FILE *, const char *, __va_list); int __swbuf(int, FILE *); /* * The __sfoo macros are here so that we can * define function versions in the C library. */ #define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) #if defined(__GNUC__) && defined(__STDC__) static __inline int __sputc(int _c, FILE *_p) { if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) return (*_p->_p++ = _c); else return (__swbuf(_c, _p)); } #else /* * This has been tuned to generate reasonable code on the vax using pcc. */ #define __sputc(c, p) \ (--(p)->_w < 0 ? \ (p)->_w >= (p)->_lbfsize ? \ (*(p)->_p = (c)), *(p)->_p != '\n' ? \ (int)*(p)->_p++ : \ __swbuf('\n', p) : \ __swbuf((int)(c), p) : \ (*(p)->_p = (c), (int)*(p)->_p++)) #endif #define __sfeof(p) (((p)->_flags & __SEOF) != 0) #define __sferror(p) (((p)->_flags & __SERR) != 0) #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) #define __sfileno(p) ((p)->_file) /* * See ISO/IEC 9945-1 ANSI/IEEE Std 1003.1 Second Edition 1996-07-12 * B.8.2.7 for the rationale behind the *_unlocked() macros. */ #define feof_unlocked(p) __sfeof(p) #define ferror_unlocked(p) __sferror(p) #define clearerr_unlocked(p) __sclearerr(p) #define fileno_unlocked(p) __sfileno(p) #define getc_unlocked(fp) __sgetc(fp) #define putc_unlocked(x, fp) __sputc(x, fp) #define getchar_unlocked() getc_unlocked(stdin) #define putchar_unlocked(x) putc_unlocked(x, stdout) __END_DECLS #endif /* !_STDIO_H_ */ Index: head/include/stdlib.h =================================================================== --- head/include/stdlib.h (revision 103011) +++ head/include/stdlib.h (revision 103012) @@ -1,214 +1,214 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)stdlib.h 8.5 (Berkeley) 5/19/95 * $FreeBSD$ */ #ifndef _STDLIB_H_ #define _STDLIB_H_ #include #include #if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE) #ifndef _RUNE_T_DECLARED typedef __rune_t rune_t; #define _RUNE_T_DECLARED #endif #endif #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #ifndef __cplusplus #ifndef _WCHAR_T_DECLARED typedef __wchar_t wchar_t; #define _WCHAR_T_DECLARED #endif #endif typedef struct { int quot; /* quotient */ int rem; /* remainder */ } div_t; typedef struct { long quot; /* quotient */ long rem; /* remainder */ } ldiv_t; #if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE) #ifdef __LONG_LONG_SUPPORTED /* LONGLONG */ typedef struct { long long quot; long long rem; } lldiv_t; #endif #endif #ifndef NULL #define NULL 0 #endif #define EXIT_FAILURE 1 #define EXIT_SUCCESS 0 #define RAND_MAX 0x7fffffff extern int __mb_cur_max; #define MB_CUR_MAX __mb_cur_max __BEGIN_DECLS void abort(void) __dead2; int abs(int) __pure2; int atexit(void (*)(void)); double atof(const char *); int atoi(const char *); long atol(const char *); void *bsearch(const void *, const void *, size_t, size_t, int (*)(const void *, const void *)); void *calloc(size_t, size_t); div_t div(int, int) __pure2; void exit(int) __dead2; void free(void *); char *getenv(const char *); long labs(long) __pure2; ldiv_t ldiv(long, long) __pure2; void *malloc(size_t); void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); int rand(void); void *realloc(void *, size_t); void srand(unsigned); -double strtod(const char *__restrict, char **__restrict); -long strtol(const char *__restrict, char **__restrict, int); +double strtod(const char * __restrict, char ** __restrict); +long strtol(const char * __restrict, char ** __restrict, int); unsigned long - strtoul(const char *__restrict, char **__restrict, int); + strtoul(const char * __restrict, char ** __restrict, int); int system(const char *); int mblen(const char *, size_t); -size_t mbstowcs(wchar_t *__restrict , const char *__restrict, size_t); +size_t mbstowcs(wchar_t * __restrict , const char * __restrict, size_t); int wctomb(char *, wchar_t); -int mbtowc(wchar_t *__restrict, const char *__restrict, size_t); -size_t wcstombs(char *__restrict, const wchar_t *__restrict, size_t); +int mbtowc(wchar_t * __restrict, const char * __restrict, size_t); +size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t); #if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE) extern const char *_malloc_options; extern void (*_malloc_message)(const char *p1, const char *p2, const char *p3, const char *p4); int putenv(const char *); int setenv(const char *, const char *, int); double drand48(void); double erand48(unsigned short[3]); long jrand48(unsigned short[3]); void lcong48(unsigned short[7]); long lrand48(void); long mrand48(void); long nrand48(unsigned short[3]); unsigned short *seed48(unsigned short[3]); void srand48(long); void *alloca(size_t); /* built-in for gcc */ /* getcap(3) functions */ __uint32_t arc4random(void); void arc4random_addrandom(unsigned char *dat, int datlen); void arc4random_stir(void); #ifdef __LONG_LONG_SUPPORTED /* LONGLONG */ long long atoll(const char *); #endif char *getbsize(int *, long *); char *cgetcap(char *, const char *, int); int cgetclose(void); int cgetent(char **, char **, const char *); int cgetfirst(char **, char **); int cgetmatch(const char *, const char *); int cgetnext(char **, char **); int cgetnum(char *, const char *, long *); int cgetset(const char *); int cgetstr(char *, const char *, char **); int cgetustr(char *, const char *, char **); int daemon(int, int); char *devname(int, int); int getloadavg(double [], int); __const char * getprogname(void); int heapsort(void *, size_t, size_t, int (*)(const void *, const void *)); char *initstate(unsigned long, char *, long); #ifdef __LONG_LONG_SUPPORTED /* LONGLONG */ long long llabs(long long) __pure2; lldiv_t lldiv(long long, long long) __pure2; #endif int mergesort(void *, size_t, size_t, int (*)(const void *, const void *)); int radixsort(const unsigned char **, int, const unsigned char *, unsigned); int sradixsort(const unsigned char **, int, const unsigned char *, unsigned); int rand_r(unsigned *); long random(void); void *reallocf(void *, size_t); char *realpath(const char *, char resolved_path[]); void setprogname(const char *); char *setstate(char *); void sranddev(void); void srandom(unsigned long); void srandomdev(void); #ifdef __LONG_LONG_SUPPORTED /* LONGLONG */ long long - strtoll(const char *__restrict, char **__restrict, int); + strtoll(const char * __restrict, char ** __restrict, int); #endif __int64_t strtoq(const char *, char **, int); #ifdef __LONG_LONG_SUPPORTED /* LONGLONG */ unsigned long long - strtoull(const char *__restrict, char **__restrict, int); + strtoull(const char * __restrict, char ** __restrict, int); #endif __uint64_t strtouq(const char *, char **, int); void unsetenv(const char *); #endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */ __END_DECLS #endif /* !_STDLIB_H_ */ Index: head/include/time.h =================================================================== --- head/include/time.h (revision 103011) +++ head/include/time.h (revision 103012) @@ -1,159 +1,159 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)time.h 8.3 (Berkeley) 1/21/94 */ /* * $FreeBSD$ */ #ifndef _TIME_H_ #define _TIME_H_ #include #include #if __POSIX_VISIBLE > 0 && __POSIX_VISIBLE < 200112 || __BSD_VISIBLE /* * Frequency of the clock ticks reported by times(). Deprecated - use * sysconf(_SC_CLK_TCK) instead. (Removed in 1003.1-2001.) */ #define CLK_TCK 128 #endif /* Frequency of the clock ticks reported by clock(). */ #define CLOCKS_PER_SEC 128 #ifndef NULL #define NULL 0 #endif #ifndef _CLOCK_T_DECLARED typedef __clock_t clock_t; #define _CLOCK_T_DECLARED #endif #ifndef _TIME_T_DECLARED typedef __time_t time_t; #define _TIME_T_DECLARED #endif #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #if __POSIX_VISIBLE >= 199309 /* * New in POSIX 1003.1b-1993. */ #ifndef _CLOCKID_T_DECLARED typedef __clockid_t clockid_t; #define _CLOCKID_T_DECLARED #endif #ifndef _TIMER_T_DECLARED typedef __timer_t timer_t; #define _TIMER_T_DECLARED #endif #include #endif /* __POSIX_VISIBLE >= 199309 */ struct tm { int tm_sec; /* seconds after the minute [0-60] */ int tm_min; /* minutes after the hour [0-59] */ int tm_hour; /* hours since midnight [0-23] */ int tm_mday; /* day of the month [1-31] */ int tm_mon; /* months since January [0-11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday [0-6] */ int tm_yday; /* days since January 1 [0-365] */ int tm_isdst; /* Daylight Savings Time flag */ long tm_gmtoff; /* offset from UTC in seconds */ char *tm_zone; /* timezone abbreviation */ }; #if __POSIX_VISIBLE extern char *tzname[]; #endif __BEGIN_DECLS char *asctime(const struct tm *); clock_t clock(void); char *ctime(const time_t *); double difftime(time_t, time_t); struct tm *gmtime(const time_t *); struct tm *localtime(const time_t *); time_t mktime(struct tm *); -size_t strftime(char *__restrict, size_t, const char *__restrict, - const struct tm *__restrict); +size_t strftime(char * __restrict, size_t, const char * __restrict, + const struct tm * __restrict); time_t time(time_t *); #if __POSIX_VISIBLE void tzset(void); #endif #if __POSIX_VISIBLE >= 199309 int clock_getres(clockid_t, struct timespec *); int clock_gettime(clockid_t, struct timespec *); int clock_settime(clockid_t, const struct timespec *); int nanosleep(const struct timespec *, struct timespec *); #endif /* __POSIX_VISIBLE >= 199309 */ #if __POSIX_VISIBLE >= 199506 char *asctime_r(const struct tm *, char *); char *ctime_r(const time_t *, char *); struct tm *gmtime_r(const time_t *, struct tm *); struct tm *localtime_r(const time_t *, struct tm *); #endif #if __XSI_VISIBLE -char *strptime(const char *__restrict, const char *__restrict, - struct tm *__restrict); +char *strptime(const char * __restrict, const char * __restrict, + struct tm * __restrict); #endif #if __BSD_VISIBLE char *timezone(int, int); void tzsetwall(void); time_t timelocal(struct tm * const); time_t timegm(struct tm * const); #endif /* __BSD_VISIBLE */ __END_DECLS #endif /* !_TIME_H_ */ Index: head/include/unistd.h =================================================================== --- head/include/unistd.h (revision 103011) +++ head/include/unistd.h (revision 103012) @@ -1,307 +1,307 @@ /*- * Copyright (c) 1991, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)unistd.h 8.12 (Berkeley) 4/27/95 * $FreeBSD$ */ #ifndef _UNISTD_H_ #define _UNISTD_H_ #include #include /* XXX adds too much pollution. */ #include #include #ifndef _GID_T_DECLARED typedef __gid_t gid_t; #define _GID_T_DECLARED #endif #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #ifndef _SSIZE_T_DECLARED typedef __ssize_t ssize_t; #define _SSIZE_T_DECLARED #endif #ifndef _UID_T_DECLARED typedef __uid_t_ uid_t; #define _UID_T_DECLARED #endif /* * XXX missing type definitions for off_t, pid_t and useconds_t. */ #define STDIN_FILENO 0 /* standard input file descriptor */ #define STDOUT_FILENO 1 /* standard output file descriptor */ #define STDERR_FILENO 2 /* standard error file descriptor */ #ifndef NULL #define NULL 0 /* null pointer constant */ #endif #if __XSI_VISIBLE || __POSIX_VISIBLE >= 200112 #define F_ULOCK 0 /* unlock locked section */ #define F_LOCK 1 /* lock a section for exclusive use */ #define F_TLOCK 2 /* test and lock a section for exclusive use */ #define F_TEST 3 /* test a section for locks by other procs */ #endif __BEGIN_DECLS /* 1003.1-1990 */ void _exit(int) __dead2; int access(const char *, int); unsigned int alarm(unsigned int); int chdir(const char *); int chown(const char *, uid_t, gid_t); int close(int); int dup(int); int dup2(int, int); int eaccess(const char *, int); int execl(const char *, const char *, ...); int execle(const char *, const char *, ...); int execlp(const char *, const char *, ...); int execv(const char *, char * const *); int execve(const char *, char * const *, char * const *); int execvp(const char *, char * const *); pid_t fork(void); long fpathconf(int, int); char *getcwd(char *, size_t); gid_t getegid(void); uid_t geteuid(void); gid_t getgid(void); int getgroups(int, gid_t []); char *getlogin(void); pid_t getpgrp(void); pid_t getpid(void); pid_t getppid(void); uid_t getuid(void); int isatty(int); int link(const char *, const char *); #ifndef _LSEEK_DECLARED #define _LSEEK_DECLARED off_t lseek(int, off_t, int); #endif long pathconf(const char *, int); int pause(void); int pipe(int *); ssize_t read(int, void *, size_t); int rmdir(const char *); int setgid(gid_t); int setpgid(pid_t, pid_t); void setproctitle(const char *_fmt, ...) __printf0like(1, 2); pid_t setsid(void); int setuid(uid_t); unsigned int sleep(unsigned int); long sysconf(int); pid_t tcgetpgrp(int); int tcsetpgrp(int, pid_t); char *ttyname(int); int unlink(const char *); ssize_t write(int, const void *, size_t); /* 1003.2-1992 */ #if __POSIX_VISIBLE >= 199209 size_t confstr(int, char *, size_t); int getopt(int, char * const [], const char *); extern char *optarg; /* getopt(3) external variables */ extern int optind, opterr, optopt; #define _CS_PATH 1 /* default value of PATH */ #endif /* ISO/IEC 9945-1: 1996 */ #if __POSIX_VISIBLE >= 199506 int fsync(int); /* * ftruncate() was in the POSIX Realtime Extension (it's used for shared * memory), but truncate() was not. */ #ifndef _FTRUNCATE_DECLARED #define _FTRUNCATE_DECLARED int ftruncate(int, off_t); #endif int getlogin_r(char *, int); #endif /* 1003.1-2001 */ #if __POSIX_VISIBLE >= 200112 int fchown(int, uid_t, gid_t); int gethostname(char *, int /* socklen_t */); int setegid(gid_t); int seteuid(uid_t); /* X/Open mistake copied by POSIX */ #define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 2 #define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS 3 #define _CS_POSIX_V6_ILP32_OFF32_LIBS 4 #define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS 5 #define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS 6 #define _CS_POSIX_V6_ILP32_OFFBIG_LIBS 7 #define _CS_POSIX_V6_LP64_OFF64_CFLAGS 8 #define _CS_POSIX_V6_LP64_OFF64_LDFLAGS 9 #define _CS_POSIX_V6_LP64_OFF64_LIBS 10 #define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS 11 #define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS 12 #define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS 13 #define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 14 #endif /* * symlink() was originally in POSIX.1a, which was withdrawn after * being overtaken by events (1003.1-2001). It was in XPG4.2, and of * course has been in BSD practically forever. */ #if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE >= 402 || __BSD_VISIBLE -int symlink(const char *__restrict, const char *__restrict); +int symlink(const char * __restrict, const char * __restrict); #endif /* X/Open System Interfaces */ #if __XSI_VISIBLE char *crypt(const char *, const char *); /* char *ctermid(char *); */ /* XXX ??? */ int encrypt(char *, int); int fchdir(int); int getpgid(pid_t _pid); int getsid(pid_t _pid); char *getwd(char *); /* LEGACY: obsoleted by getcwd() */ int lchown(const char *, uid_t, gid_t); int lockf(int, int, off_t); int nice(int); ssize_t pread(int, void *, size_t, off_t); ssize_t pwrite(int, const void *, size_t, off_t); int setpgrp(pid_t _pid, pid_t _pgrp); /* obsoleted by setpgid() */ int setregid(gid_t, gid_t); int setreuid(uid_t, uid_t); -/* void swab(const void *__restrict, void *__restrict, ssize_t); */ +/* void swab(const void * __restrict, void * __restrict, ssize_t); */ void sync(void); unsigned int ualarm(unsigned int, unsigned int); int usleep(unsigned int); pid_t vfork(void); /* See comment at ftruncate() above. */ #ifndef _TRUNCATE_DECLARED #define _TRUNCATE_DECLARED int truncate(const char *, off_t); #endif #endif /* __XSI_VISIBLE */ #if __BSD_VISIBLE struct timeval; /* select(2) */ int acct(const char *); int async_daemon(void); int brk(const void *); int chroot(const char *); const char * crypt_get_format(void); int crypt_set_format(const char *); int des_cipher(const char *, char *, long, int); int des_setkey(const char *key); void endusershell(void); int exect(const char *, char * const *, char * const *); char *fflagstostr(u_long); int getdomainname(char *, int); int getdtablesize(void); int getgrouplist(const char *, gid_t, gid_t *, int *); long gethostid(void); mode_t getmode(const void *, mode_t); int getpagesize(void) __pure2; char *getpass(const char *); int getpeereid(int, uid_t *, gid_t *); int getresgid(gid_t *, gid_t *, gid_t *); int getresuid(uid_t *, uid_t *, uid_t *); char *getusershell(void); int initgroups(const char *, gid_t); int iruserok(unsigned long, int, const char *, const char *); int iruserok_sa(const void *, int, int, const char *, const char *); int issetugid(void); char *mkdtemp(char *); int mknod(const char *, mode_t, dev_t); int mkstemp(char *); int mkstemps(char *, int); char *mktemp(char *); int nfsclnt(int, void *); int nfssvc(int, void *); int profil(char *, size_t, vm_offset_t, int); int rcmd(char **, int, const char *, const char *, const char *, int *); int rcmd_af(char **, int, const char *, const char *, const char *, int *, int); int rcmdsh(char **, int, const char *, const char *, const char *, const char *); char *re_comp(const char *); int re_exec(const char *); int readlink(const char *, char *, int); int reboot(int); int revoke(const char *); pid_t rfork(int); pid_t rfork_thread(int, void *, int (*)(void *), void *); int rresvport(int *); int rresvport_af(int *, int); int ruserok(const char *, int, const char *, const char *); void *sbrk(intptr_t); int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); int setdomainname(const char *, int); int setgroups(int, const gid_t *); void sethostid(long); int sethostname(const char *, int); int setkey(const char *); int setlogin(const char *); void *setmode(const char *); int setresgid(gid_t, gid_t, gid_t); int setresuid(uid_t, uid_t, uid_t); int setrgid(gid_t); int setruid(uid_t); void setusershell(void); int strtofflags(char **, u_long *, u_long *); int swapon(const char *); int syscall(int, ...); off_t __syscall(quad_t, ...); int ttyslot(void); int undelete(const char *); int unwhiteout(const char *); void *valloc(size_t); /* obsoleted by malloc() */ extern char *suboptarg; /* getsubopt(3) external variable */ int getsubopt(char **, char * const *, char **); extern int optreset; /* getopt(3) external variable */ #endif /* __BSD_VISIBLE */ __END_DECLS #endif /* !_UNISTD_H_ */ Index: head/include/wchar.h =================================================================== --- head/include/wchar.h (revision 103011) +++ head/include/wchar.h (revision 103012) @@ -1,166 +1,166 @@ /*- * Copyright (c)1999 Citrus Project, * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /*- * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Julian Coleman. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the NetBSD * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * $NetBSD: wchar.h,v 1.8 2000/12/22 05:31:42 itojun Exp $ */ #ifndef _WCHAR_H_ #define _WCHAR_H_ #include #include #include #ifndef NULL #define NULL 0 #endif #ifndef _MBSTATE_T_DECLARED typedef __mbstate_t mbstate_t; #define _MBSTATE_T_DECLARED #endif #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #ifndef __cplusplus #ifndef _WCHAR_T_DECLARED typedef __wchar_t wchar_t; #define _WCHAR_T_DECLARED #endif #endif #ifndef _WCTYPE_T typedef unsigned long wctype_t; #define _WCTYPE_T #endif #ifndef _WINT_T_DECLARED typedef __wint_t wint_t; #define _WINT_T_DECLARED #endif #ifndef WEOF #define WEOF ((wint_t)-1) #endif __BEGIN_DECLS wint_t btowc(int); wint_t fgetwc(FILE *); wchar_t * - fgetws(wchar_t *__restrict, int, FILE *__restrict); + fgetws(wchar_t * __restrict, int, FILE * __restrict); wint_t fputwc(wchar_t, FILE *); -int fputws(const wchar_t *__restrict, FILE *__restrict); +int fputws(const wchar_t * __restrict, FILE * __restrict); int fwide(FILE *, int); wint_t getwc(FILE *); wint_t getwchar(void); size_t mbrlen(const char * __restrict, size_t, mbstate_t * __restrict); size_t mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); int mbsinit(const mbstate_t *); size_t mbsrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, mbstate_t * __restrict); wint_t putwc(wchar_t, FILE *); wint_t putwchar(wchar_t); wint_t ungetwc(wint_t, FILE *); size_t wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); wchar_t *wcscat(wchar_t * __restrict, const wchar_t * __restrict); wchar_t *wcschr(const wchar_t *, wchar_t); int wcscmp(const wchar_t *, const wchar_t *); wchar_t *wcscpy(wchar_t * __restrict, const wchar_t * __restrict); size_t wcscspn(const wchar_t *, const wchar_t *); size_t wcslcat(wchar_t *, const wchar_t *, size_t); size_t wcslcpy(wchar_t *, const wchar_t *, size_t); size_t wcslen(const wchar_t *); wchar_t *wcsncat(wchar_t * __restrict, const wchar_t * __restrict, size_t); int wcsncmp(const wchar_t *, const wchar_t *, size_t); wchar_t *wcsncpy(wchar_t * __restrict , const wchar_t * __restrict, size_t); wchar_t *wcspbrk(const wchar_t *, const wchar_t *); wchar_t *wcsrchr(const wchar_t *, wchar_t); size_t wcsrtombs(char * __restrict, const wchar_t ** __restrict, size_t, mbstate_t * __restrict); size_t wcsspn(const wchar_t *, const wchar_t *); wchar_t *wcsstr(const wchar_t *, const wchar_t *); int wctob(wint_t); wchar_t *wmemchr(const wchar_t *, wchar_t, size_t); int wmemcmp(const wchar_t *, const wchar_t *, size_t); wchar_t *wmemcpy(wchar_t * __restrict, const wchar_t * __restrict, size_t); wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t); wchar_t *wmemset(wchar_t *, wchar_t, size_t); #if __XSI_VISIBLE int wcswidth(const wchar_t *, size_t); int wcwidth(wchar_t); #endif __END_DECLS #define getwc(fp) fgetwc(fp) #define getwchar() fgetwc(stdin) #define putwc(wc, fp) fputwc(wc, fp) #define putwchar(wc) fputwc(wc, stdout) #endif /* !_WCHAR_H_ */ Index: head/lib/libc/gen/statvfs.3 =================================================================== --- head/lib/libc/gen/statvfs.3 (revision 103011) +++ head/lib/libc/gen/statvfs.3 (revision 103012) @@ -1,185 +1,185 @@ .\" .\" Copyright 2002 Massachusetts Institute of Technology .\" .\" Permission to use, copy, modify, and distribute this software and .\" its documentation for any purpose and without fee is hereby .\" granted, provided that both the above copyright notice and this .\" permission notice appear in all copies, that both the above .\" copyright notice and this permission notice appear in all .\" supporting documentation, and that the name of M.I.T. not be used .\" in advertising or publicity pertaining to distribution of the .\" software without specific, written prior permission. M.I.T. makes .\" no representations about the suitability of this software for any .\" purpose. It is provided "as is" without express or implied .\" warranty. .\" .\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS .\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, .\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT .\" SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF .\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND .\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" .Dd July 13, 2002 .Dt STATVFS 3 .Os .Sh NAME .Nm statvfs , .Nm fstatvfs .Nd retrieve filesystem information .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/statvfs.h .Ft int -.Fn statvfs "const char *restrict path" "struct statvfs *restrict buf" +.Fn statvfs "const char * restrict path" "struct statvfs * restrict buf" .Ft int .Fn fstatvfs "int fd" "struct statvfs *buf" .Sh DESCRIPTION The .Fn statvfs and .Fn fstatvfs functions fill the structure pointed to by .Fa buf with garbage. This garbage will occasionally bear resemblance to filesystem statistics, but portable applications must not depend on this. Applications must pass a pathname or file descriptor which refers to a file on the filesystem in which they are interested. .Pp The .Vt statvfs structure contains the following members: .Bl -tag -offset indent -width "f_namemax" .It Va f_namemax The maximum length in bytes of a file name on this filesystem. Applications should use .Xr pathconf 3 instead. .It Va f_fsid Not meaningful in this implementation. .It Va f_frsize The size in bytes of the minimum unit of allocation on this filesystem. (This corresponds to the .Va f_bsize member of .Vt "struct statfs" . ) .It Va f_bsize The preferred length of I/O requests for files on this filesystem. (Corresponds to the .Va f_iosize member of .Vt "struct statfs" . ) .It Va f_flag Flags describing mount options for this filesystem; see below. .El .Pp In addition, there are three members of type .Vt fsfilcnt_t , which represent counts of file serial numbers .Pq Em i.e. , No inodes ; these are named .Va f_files , .Va f_favail , and .Va f_ffree , and represent the number of file serial numbers which exist in total, are available to unprivileged processes, and are available to privileged processes, respectively. Likewise, the members .Va f_blocks , .Va f_bavail , and .Va f_bfree (all of type .Vt fsblkcnt_t ) represent the respective allocation-block counts. .Pp There are two flags defined for the .Va f_flag member: .Bl -tag -offset indent -width "ST_NOSUID" .It Dv ST_RDONLY The filesystem is mounted read-only. .It Dv ST_NOSUID The semantics of the .Dv S_ISUID and .Dv S_ISGID file mode bits are not supported by, or are disabled on, this filesystem. .El .Sh IMPLEMENTATION NOTES The .Fn statvfs and .Fn fstatvfs functions are implemented as wrappers around the .Fn statfs and .Fn fstatfs functions, respectively. Not all the information provided by those functions is made available through this interface. .Sh RETURN VALUES .Rv -std statvfs fstatvfs .Sh ERRORS The .Fn statvfs and .Fn fstatvfs functions may fail for any of the reasons documented for .Xr statfs 2 or .Xr fstatfs 2 and .Xr pathconf 3 or .Xr fpathconf 3 , respectively. In addition, .Fn statvfs and .Fn fstatvfs functions may also fail for the following reason: .Bl -tag -width Er .It Bq Er EOVERFLOW One or more of the filesystem statistics has a value which cannot be represented by the data types used in .Vt "struct statvfs" . .El .Sh SEE ALSO .Xr statfs 2 , .Xr pathconf 3 .Sh STANDARDS The .Fn statvfs and .Fn fstatvfs functions conform to .St -p1003.1-2001 . As standardized, portable applications cannot depend on these functions returning any valid information at all. This implementation attempts to provide as much useful information as is provided by the underlying filesystem, subject to the limitations of the specified data types. .Sh HISTORY The .Nm function first appeared in .Fx 5.0 . .Sh AUTHORS The .Nm function and this manual page were written by .An Garrett Wollman Aq wollman@FreeBSD.org . Index: head/lib/libc/gen/statvfs.c =================================================================== --- head/lib/libc/gen/statvfs.c (revision 103011) +++ head/lib/libc/gen/statvfs.c (revision 103012) @@ -1,160 +1,160 @@ /* * Copyright 2002 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that both the above copyright notice and this * permission notice appear in all copies, that both the above * copyright notice and this permission notice appear in all * supporting documentation, and that the name of M.I.T. not be used * in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. M.I.T. makes * no representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include "un-namespace.h" static int sfs2svfs(const struct statfs *from, struct statvfs *to); int fstatvfs(int fd, struct statvfs *result) { struct statfs sfs; int rv; long pcval; rv = _fstatfs(fd, &sfs); if (rv != 0) return (rv); rv = sfs2svfs(&sfs, result); if (rv != 0) return (rv); /* * Whether pathconf's -1 return means error or unlimited does not * make any difference in this best-effort implementation. */ pcval = _fpathconf(fd, _PC_NAME_MAX); if (pcval == -1) result->f_namemax = ~0UL; else result->f_namemax = (unsigned long)pcval; return (0); } int -statvfs(const char *__restrict path, struct statvfs *__restrict result) +statvfs(const char * __restrict path, struct statvfs * __restrict result) { struct statfs sfs; int rv; long pcval; rv = statfs(path, &sfs); if (rv != 0) return (rv); sfs2svfs(&sfs, result); /* * Whether pathconf's -1 return means error or unlimited does not * make any difference in this best-effort implementation. */ pcval = pathconf(path, _PC_NAME_MAX); if (pcval == -1) result->f_namemax = ~0UL; else result->f_namemax = (unsigned long)pcval; return (0); } static int sfs2svfs(const struct statfs *from, struct statvfs *to) { static const struct statvfs zvfs; *to = zvfs; if (from->f_flags & MNT_RDONLY) to->f_flag |= ST_RDONLY; if (from->f_flags & MNT_NOSUID) to->f_flag |= ST_NOSUID; /* XXX should we clamp negative values? */ #define COPY(field) \ do { \ to->field = from->field; \ if (from->field != to->field) { \ errno = EOVERFLOW; \ return (-1); \ } \ } while(0) COPY(f_bavail); COPY(f_bfree); COPY(f_blocks); COPY(f_ffree); COPY(f_files); to->f_bsize = from->f_iosize; to->f_frsize = from->f_bsize; to->f_favail = to->f_ffree; return (0); } #ifdef MAIN #include #include #include int main(int argc, char **argv) { struct statvfs buf; if (statvfs(argv[1], &buf) < 0) err(1, "statvfs"); #define SHOW(field) \ printf(#field ": %ju\n", (uintmax_t)buf.field) SHOW(f_bavail); SHOW(f_bfree); SHOW(f_blocks); SHOW(f_favail); SHOW(f_ffree); SHOW(f_files); SHOW(f_bsize); SHOW(f_frsize); SHOW(f_namemax); printf("f_flag: %lx\n", (unsigned long)buf.f_flag); return 0; } #endif /* MAIN */ Index: head/lib/libc/locale/mbrlen.3 =================================================================== --- head/lib/libc/locale/mbrlen.3 (revision 103011) +++ head/lib/libc/locale/mbrlen.3 (revision 103012) @@ -1,113 +1,113 @@ .\" Copyright (c) 2002 Tim J. Robbins .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .Dd August 16, 2002 .Dt MBRLEN 3 .Os .Sh NAME .Nm mbrlen .Nd "get number of bytes in a character (restartable)" .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In wchar.h .Ft size_t -.Fn mbrlen "const char *restrict s" "size_t n" "mbstate_t *restrict ps" +.Fn mbrlen "const char * restrict s" "size_t n" "mbstate_t * restrict ps" .Sh DESCRIPTION The .Fn mbrlen function determines the the number of bytes constituting the multibyte character sequence pointer to by .Fa s . .Pp It is equivalent to: .Pp .Dl "mbrtowc(NULL, s, n, ps);" .Pp Except that when .Fa ps is a NULL pointer, .Fn mbrlen uses its own static, internal .Ft mbstate_t object to keep track of shift state. .Sh RETURN VALUES The .Fn mbrlen functions returns: .Bl -tag -width indent .It 0 The first .Fa n or fewer bytes of .Fa s represent the null wide character (L'\e0'). .It >0 The first .Fa n or fewer bytes of .Fa s represent a valid character, .Fn mbrtowc returns the length (in bytes) of the multibyte sequence. .It Xo .No ( Ns .Ft size_t Ns .No ) Ns \&-2 .Xc The first .Fa n bytes of .Fa s are an incomplete multibyte sequence. .It Xo .No ( Ns .Ft size_t Ns .No ) Ns \&-1 .Xc The byte sequence pointed to by .Fa s is an invalid multibyte sequence. .El .Sh ERRORS The .Fn mbrlen function will fail if: .Bl -tag -width Er .\".It Bq Er EINVAL .\"Invalid argument. .It Bq Er EILSEQ An invalid multibyte sequence was detected. .El .Sh SEE ALSO .Xr mblen 3 , .Xr mbrtowc 3 .Sh STANDARDS The .Fn mbrlen function conforms to .St -isoC-99 . .Sh BUGS The current implementation does not support shift states. Index: head/lib/libc/locale/mbrlen.c =================================================================== --- head/lib/libc/locale/mbrlen.c (revision 103011) +++ head/lib/libc/locale/mbrlen.c (revision 103012) @@ -1,37 +1,37 @@ /*- * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include size_t -mbrlen(const char *__restrict s, size_t n, mbstate_t *__restrict ps __unused) +mbrlen(const char * __restrict s, size_t n, mbstate_t * __restrict ps __unused) { return (mbrtowc(NULL, s, n, NULL)); } Index: head/lib/libc/locale/mbrtowc.3 =================================================================== --- head/lib/libc/locale/mbrtowc.3 (revision 103011) +++ head/lib/libc/locale/mbrtowc.3 (revision 103012) @@ -1,142 +1,142 @@ .\" Copyright (c) 2002 Tim J. Robbins .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .Dd August 15, 2002 .Dt MBRTOWC 3 .Os .Sh NAME .Nm mbrtowc .Nd "convert a character to a wide-character code (restartable)" .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In wchar.h .Ft size_t -.Fn mbrtowc "wchar_t *restrict pwc" "const char *restrict s" "size_t n" "mbstate_t *restrict ps" +.Fn mbrtowc "wchar_t * restrict pwc" "const char * restrict s" "size_t n" "mbstate_t * restrict ps" .Sh DESCRIPTION The .Fn mbrtowc function inspects at most .Fa n bytes pointed to by .Fa s and interprets them as a multibyte character sequence according to the current setting of .Ev LC_CTYPE . If .Fa pwc is not .Dv NULL , the multibyte character which .Fa s represents is stored in the .Ft wchar_t it points to. .Pp If .Fa s is .Dv NULL , .Fn mbrtowc behaves as if .Fa pwc was .Dv NULL , .Fa s was an empty string ("") and .Fa n was 1. .Pp The .Ft mbstate_t argument, .Fa ps , is used to keep track of the shift state. If it is .Dv NULL , .Fn mbrtowc uses an internal, static .Ft mbstate_t object. .Sh RETURN VALUES The .Fn mbrtowc functions returns: .Bl -tag -width indent .It 0 The first .Fa n or fewer bytes of .Fa s represent the null wide character (L'\e0'). .It >0 The first .Fa n or fewer bytes of .Fa s represent a valid character, .Fn mbrtowc returns the length (in bytes) of the multibyte sequence. .It Xo .No ( Ns .Ft size_t Ns .No ) Ns \&-2 .Xc The first .Fa n bytes of .Fa s are an incomplete multibyte sequence. .It Xo .No ( Ns .Ft size_t Ns .No ) Ns \&-1 .Xc The byte sequence pointed to by .Fa s is an invalid multibyte sequence. .El .Sh ERRORS The .Fn mbrtowc function will fail if: .Bl -tag -width Er .\".It Bq Er EINVAL .\"Invalid argument. .It Bq Er EILSEQ An invalid multibyte sequence was detected. .El .Sh SEE ALSO .Xr mbtowc 3 , .Xr setlocale 3 , .Xr wcrtomb 3 .Sh STANDARDS The .Fn mbrtowc function conforms to .St -isoC-99 . .Sh BUGS The current implementation does not support shift states. Index: head/lib/libc/locale/mbrtowc.c =================================================================== --- head/lib/libc/locale/mbrtowc.c (revision 103011) +++ head/lib/libc/locale/mbrtowc.c (revision 103012) @@ -1,81 +1,81 @@ /*- * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include size_t -mbrtowc(wchar_t *__restrict pwc, const char *__restrict s, size_t n, - mbstate_t *__restrict ps __unused) +mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps __unused) { const char *e; rune_t r; if (s == NULL) { pwc = NULL; s = ""; n = 1; } if (*s == '\0') { if (pwc != NULL) *pwc = L'\0'; return (0); } if ((r = sgetrune(s, n, &e)) == _INVALID_RUNE) { /* * The design of sgetrune() doesn't give us any way to tell * between incomplete and invalid multibyte sequences. */ if (n >= (size_t)MB_CUR_MAX) { /* * If we have been supplied with at least MB_CUR_MAX * bytes and still cannot find a valid character, the * data must be invalid. */ errno = EILSEQ; return ((size_t)-1); } /* * .. otherwise, it's an incomplete character or an invalid * character we cannot detect yet. */ return ((size_t)-2); } if (pwc != NULL) *pwc = (wchar_t)r; return ((size_t)(e - s)); } Index: head/lib/libc/locale/mbsrtowcs.3 =================================================================== --- head/lib/libc/locale/mbsrtowcs.3 (revision 103011) +++ head/lib/libc/locale/mbsrtowcs.3 (revision 103012) @@ -1,108 +1,108 @@ .\" Copyright (c) 2002 Tim J. Robbins .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .Dd August 16, 2002 .Dt MBSRTOWCS 3 .Os .Sh NAME .Nm mbsrtowcs .Nd "convert a character string to a wide-character string (restartable)" .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In wchar.h .Ft size_t -.Fn mbsrtowcs "wchar_t *restrict dst" "const char **restrict src" "size_t len" "mbstate_t *restrict ps" +.Fn mbsrtowcs "wchar_t * restrict dst" "const char ** restrict src" "size_t len" "mbstate_t * restrict ps" .Sh DESCRIPTION The .Fn mbsrtowcs function converts a sequence of multibyte characters pointed to indirectly by .Fa src into a sequence of corresponding wide characters and stores at most .Fa len of them in the .Ft wchar_t array pointed to by .Fa dst , until it encounters a terminating null character ('\e0'). .Pp If .Fa dst is .Dv NULL , no characters are stored. .Pp If .Fa dst is not .Dv NULL , the pointer pointed to by .Fa src is updated to point to the character after the one that conversion stopped at. If conversion stops because a null character is encountered, .No * Ns Fa src is set to .Dv NULL . .Pp The .Ft mbstate_t argument, .Fa ps , is used to keep track of the shift state. If it is .Dv NULL , .Fn mbsrtowcs uses an internal, static .Ft mbstate_t object. .Sh RETURN VALUES The .Fn mbsrtowcs function returns the number of wide characters stored in the array pointed to by .Fa dst if successful, otherwise it returns .No ( Ns .Ft size_t Ns .No ) Ns -1 . .Sh ERRORS The .Fn mbsrtowcs function will fail if: .Bl -tag -width Er .It Bq Er EILSEQ An invalid multibyte character sequence was encountered. .El .Sh SEE ALSO .Xr mbrtowc 3 , .Xr mbstowcs 3 , .Xr wcsrtombs 3 .Sh STANDARDS The .Fn mbsrtowcs function conforms to .St -isoC-99 . .Sh BUGS The current implementation does not support shift states. Index: head/lib/libc/locale/mbsrtowcs.c =================================================================== --- head/lib/libc/locale/mbsrtowcs.c (revision 103011) +++ head/lib/libc/locale/mbsrtowcs.c (revision 103012) @@ -1,74 +1,74 @@ /*- * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include size_t -mbsrtowcs(wchar_t *__restrict dst, const char **__restrict src, size_t len, - mbstate_t *__restrict ps __unused) +mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len, + mbstate_t * __restrict ps __unused) { const char *s; size_t nchr; wchar_t wc; int nb; s = *src; nchr = 0; if (dst == NULL) { for (;;) { if ((nb = (int)mbrtowc(&wc, s, MB_CUR_MAX, NULL)) < 0) /* Invalid sequence - mbrtowc() sets errno. */ return ((size_t)-1); else if (nb == 0) return (nchr); s += nb; nchr++; } /*NOTREACHED*/ } while (len-- > 0) { if ((nb = (int)mbrtowc(dst, s, MB_CUR_MAX, NULL)) < 0) { *src = s; return ((size_t)-1); } else if (nb == 0) { *src = NULL; return (nchr); } s += nb; nchr++; dst++; } *src = s; return (nchr); } Index: head/lib/libc/locale/mbstowcs.c =================================================================== --- head/lib/libc/locale/mbstowcs.c (revision 103011) +++ head/lib/libc/locale/mbstowcs.c (revision 103012) @@ -1,88 +1,88 @@ /*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include size_t mbstowcs(pwcs, s, n) - wchar_t *__restrict pwcs; - const char *__restrict s; + wchar_t * __restrict pwcs; + const char * __restrict s; size_t n; { char const *e; int cnt = 0; rune_t r; if (!s) { errno = EINVAL; return (-1); } if (pwcs == NULL) { /* Convert and count only, do not store. */ while ((r = sgetrune(s, MB_LEN_MAX, &e)) != _INVALID_RUNE && r != 0) { s = e; cnt++; } if (r == _INVALID_RUNE) { errno = EILSEQ; return (-1); } } /* Convert, store and count characters. */ while (n-- > 0) { *pwcs = sgetrune(s, MB_LEN_MAX, &e); if (*pwcs == _INVALID_RUNE) { errno = EILSEQ; return (-1); } if (*pwcs++ == 0) break; s = e; ++cnt; } return (cnt); } Index: head/lib/libc/locale/mbtowc.c =================================================================== --- head/lib/libc/locale/mbtowc.c (revision 103011) +++ head/lib/libc/locale/mbtowc.c (revision 103012) @@ -1,64 +1,64 @@ /*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include int mbtowc(pwc, s, n) - wchar_t *__restrict pwc; - const char *__restrict s; + wchar_t * __restrict pwc; + const char * __restrict s; size_t n; { char const *e; rune_t r; if (s == 0 || *s == 0) return (0); /* No support for state dependent encodings. */ if ((r = sgetrune(s, n, &e)) == _INVALID_RUNE) { errno = EILSEQ; return (s - e); } if (pwc) *pwc = r; return (e - s); } Index: head/lib/libc/locale/multibyte.3 =================================================================== --- head/lib/libc/locale/multibyte.3 (revision 103011) +++ head/lib/libc/locale/multibyte.3 (revision 103012) @@ -1,246 +1,246 @@ .\" Copyright (c) 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Donn Seeley of BSDI. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)multibyte.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" .Dd June 4, 1993 .Dt MULTIBYTE 3 .Os .Sh NAME .Nm mblen , .Nm mbstowcs , .Nm mbtowc , .Nm wcstombs , .Nm wctomb .Nd multibyte character support for C .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdlib.h .Ft int .Fn mblen "const char *mbchar" "size_t nbytes" .Ft size_t -.Fn mbstowcs "wchar_t *restrict wcstring" "const char *restrict mbstring" "size_t nwchars" +.Fn mbstowcs "wchar_t * restrict wcstring" "const char * restrict mbstring" "size_t nwchars" .Ft int -.Fn mbtowc "wchar_t *restrict wcharp" "const char *restrict mbchar" "size_t nbytes" +.Fn mbtowc "wchar_t * restrict wcharp" "const char * restrict mbchar" "size_t nbytes" .Ft size_t -.Fn wcstombs "char *restrict mbstring" "const wchar_t *restrict wcstring" "size_t nbytes" +.Fn wcstombs "char * restrict mbstring" "const wchar_t * restrict wcstring" "size_t nbytes" .Ft int .Fn wctomb "char *mbchar" "wchar_t wchar" .Sh DESCRIPTION The basic elements of some written natural languages such as Chinese cannot be represented uniquely with single C .Va char Ns s . The C standard supports two different ways of dealing with extended natural language encodings, .Em wide characters and .Em multibyte characters. Wide characters are an internal representation which allows each basic element to map to a single object of type .Va wchar_t . Multibyte characters are used for input and output and code each basic element as a sequence of C .Va char Ns s . Individual basic elements may map into one or more (up to .Dv MB_LEN_MAX ) bytes in a multibyte character. .Pp The current locale .Pq Xr setlocale 3 governs the interpretation of wide and multibyte characters. The locale category .Dv LC_CTYPE specifically controls this interpretation. The .Va wchar_t type is wide enough to hold the largest value in the wide character representations for all locales. .Pp Multibyte strings may contain .Sq shift indicators to switch to and from particular modes within the given representation. If explicit bytes are used to signal shifting, these are not recognized as separate characters but are lumped with a neighboring character. There is always a distinguished .Sq initial shift state. The .Fn mbstowcs and .Fn wcstombs functions assume that multibyte strings are interpreted starting from the initial shift state. The .Fn mblen , .Fn mbtowc and .Fn wctomb functions maintain static shift state internally. A call with a null .Fa mbchar pointer returns nonzero if the current locale requires shift states, zero otherwise; if shift states are required, the shift state is reset to the initial state. The internal shift states are undefined after a call to .Fn setlocale with the .Dv LC_CTYPE or .Dv LC_ALL categories. .Pp For convenience in processing, the wide character with value 0 (the null wide character) is recognized as the wide character string terminator, and the character with value 0 (the null byte) is recognized as the multibyte character string terminator. Null bytes are not permitted within multibyte characters. .Pp The .Fn mblen function computes the length in bytes of a multibyte character .Fa mbchar . Up to .Fa nbytes bytes are examined. .Pp The .Fn mbtowc function converts a multibyte character .Fa mbchar into a wide character and stores the result in the object pointed to by .Fa wcharp . Up to .Fa nbytes bytes are examined. .Pp The .Fn wctomb function converts a wide character .Fa wchar into a multibyte character and stores the result in .Fa mbchar . The object pointed to by .Fa mbchar must be large enough to accommodate the multibyte character. .Pp The .Fn mbstowcs function converts a multibyte character string .Fa mbstring into a wide character string .Fa wcstring . No more than .Fa nwchars wide characters are stored. A terminating null wide character is appended if there is room. .Pp The .Fn wcstombs function converts a wide character string .Fa wcstring into a multibyte character string .Fa mbstring . Up to .Fa nbytes bytes are stored in .Fa mbstring . Partial multibyte characters at the end of the string are not stored. The multibyte character string is null terminated if there is room. .Sh "RETURN VALUES If multibyte characters are not supported in the current locale, all of these functions will return \-1 if characters can be processed, otherwise 0. .Pp If .Fa mbchar is .Dv NULL , the .Fn mblen , .Fn mbtowc and .Fn wctomb functions return nonzero if shift states are supported, zero otherwise. If .Fa mbchar is valid, then these functions return the number of bytes processed in .Fa mbchar , or \-1 if no multibyte character could be recognized or converted. .Pp The .Fn mbstowcs function returns the number of wide characters converted, not counting any terminating null wide character. The .Fn wcstombs function returns the number of bytes converted, not counting any terminating null byte. If any invalid multibyte characters are encountered, both functions return \-1. .Sh "SEE ALSO .Xr btowc 3 , .Xr mbrune 3 , .Xr rune 3 , .Xr setlocale 3 , .Xr euc 4 , .Xr utf2 4 .Sh STANDARDS The .Fn mblen , .Fn mbstowcs , .Fn mbtowc , .Fn wcstombs and .Fn wctomb functions conform to .St -isoC . .Sh BUGS The current implementation does not support shift states. Index: head/lib/libc/locale/wcrtomb.3 =================================================================== --- head/lib/libc/locale/wcrtomb.3 (revision 103011) +++ head/lib/libc/locale/wcrtomb.3 (revision 103012) @@ -1,106 +1,106 @@ .\" Copyright (c) 2002 Tim J. Robbins .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .Dd August 15, 2002 .Dt WCRTOMB 3 .Os .Sh NAME .Nm wcrtomb .Nd "convert a wide-character code to a character (restartable)" .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In wchar.h .Ft size_t -.Fn wcrtomb "char *restrict s" "wchar_t wc" "mbstate_t *restrict ps" +.Fn wcrtomb "char * restrict s" "wchar_t wc" "mbstate_t * restrict ps" .Sh DESCRIPTION The .Fn wcrtomb function stores a multibyte sequence representing the wide character .Fa wc , including any necessary shift sequences, to the character array .Fa s , storing a maximum of .Dv MB_CUR_MAX bytes. .Pp If .Fa s is .Dv NULL , .Fn wcrtomb behaves as if .Fa s pointed to an internal buffer and .Fa wc was a null wide character (L'\e0'). .Pp The .Ft mbstate_t argument, .Fa ps , is used to keep track of the shift state. If it is .Dv NULL , .Fn wcrtomb uses an internal, static .Ft mbstate_t object. .Sh RETURN VALUES The .Fn wcrtomb functions returns the length (in bytes) of the multibyte sequence needed to represent .Fa wc , or .No ( Ns .Ft size_t Ns .No ) Ns \&-1 if .Fa wc is not a valid wide character code. .Sh ERRORS The .Fn wcrtomb function will fail if: .Bl -tag -width Er .\".It Bq Er EINVAL .\"Invalid argument. .It Bq Er EILSEQ An invalid wide character code was specified. .El .Sh SEE ALSO .Xr mbrtowc 3 , .Xr setlocale 3 , .Xr wctomb 3 .Sh STANDARDS The .Fn wcrtomb function conforms to .St -isoC-99 . .Sh BUGS The current implementation does not support shift states. Index: head/lib/libc/locale/wcrtomb.c =================================================================== --- head/lib/libc/locale/wcrtomb.c (revision 103011) +++ head/lib/libc/locale/wcrtomb.c (revision 103012) @@ -1,46 +1,46 @@ /*- * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include size_t -wcrtomb(char *__restrict s, wchar_t wc, mbstate_t *__restrict ps __unused) +wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps __unused) { char *e; sputrune(wc, s, MB_CUR_MAX, &e); if (e == NULL) { errno = EILSEQ; return ((size_t)-1); } return ((size_t)(e - s)); } Index: head/lib/libc/locale/wcsrtombs.3 =================================================================== --- head/lib/libc/locale/wcsrtombs.3 (revision 103011) +++ head/lib/libc/locale/wcsrtombs.3 (revision 103012) @@ -1,108 +1,108 @@ .\" Copyright (c) [year] [your name] .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .Dd August 16, 2002 .Dt WCSRTOMBS 3 .Os .Sh NAME .Nm wcsrtombs .Nd "convert a wide-character string to a character string (restartable)" .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In wchar.h .Ft size_t -.Fn wcsrtombs "char *restrict dst" "const wchar_t **restrict src" "size_t len" "mbstate_t *restrict ps" +.Fn wcsrtombs "char * restrict dst" "const wchar_t ** restrict src" "size_t len" "mbstate_t * restrict ps" .Sh DESCRIPTION The .Fn wcsrtombs function converts a string of wide characters indirectly pointed to by .Fa src to a corresponding multibyte character string stored in the array pointed to by .Fa dst . No more than .Fa len bytes are written to .Fa dst . .Pp If .Fa dst is .Dv NULL , no characters are stored. .Pp If .Fa dst is not .Dv NULL , the pointer pointed to by .Fa src is updated to point to the character after the one that conversion stopped at. If conversion stops because a null character is encountered, .No * Ns Fa src is set to .Dv NULL . .Pp The .Ft mbstate_t argument, .Fa ps , is used to keep track of the shift state. If it is .Dv NULL , .Fn wcsrtombs uses an internal, static .Ft mbstate_t object. .Sh RETURN VALUES The .Fn wcsrtombs function returns the number of bytes stored in the array pointed to by .Fa dst (not including any terminating null), if successful, otherwise it returns .No ( Ns .Ft size_t Ns .No ) Ns -1 . .Sh ERRORS The .Fn wcsrtombs function will fail if: .Bl -tag -width Er .It Bq Er EILSEQ An invalid wide character was encountered. .El .Sh SEE ALSO .Xr mbsrtowcs 3 , .Xr wcstombs 3 , .Xr wcrtomb 3 .Sh STANDARDS The .Fn wcsrtombs function conforms to .St -isoC-99 . .Sh BUGS The current implementation does not support shift states. Index: head/lib/libc/locale/wcsrtombs.c =================================================================== --- head/lib/libc/locale/wcsrtombs.c (revision 103011) +++ head/lib/libc/locale/wcsrtombs.c (revision 103012) @@ -1,90 +1,90 @@ /*- * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include size_t -wcsrtombs(char *__restrict dst, const wchar_t **__restrict src, size_t len, - mbstate_t *__restrict ps __unused) +wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len, + mbstate_t * __restrict ps __unused) { char buf[MB_LEN_MAX]; const wchar_t *s; size_t nbytes; int nb; s = *src; nbytes = 0; if (dst == NULL) { for (;;) { if ((nb = (int)wcrtomb(buf, *s, NULL)) < 0) /* Invalid character - wcrtomb() sets errno. */ return ((size_t)-1); else if (*s == L'\0') return (nbytes + nb - 1); s++; nbytes += nb; } /*NOTREACHED*/ } while (len > 0) { if (len > (size_t)MB_CUR_MAX) { /* Enough space to translate in-place. */ if ((nb = (int)wcrtomb(dst, *s, NULL)) < 0) { *src = s; return ((size_t)-1); } } else { /* May not be enough space; use temp. buffer. */ if ((nb = (int)wcrtomb(buf, *s, NULL)) < 0) { *src = s; return ((size_t)-1); } if (nb > (int)len) /* MB sequence for character won't fit. */ break; memcpy(dst, buf, nb); } if (*s == L'\0') { *src = NULL; return (nbytes + nb - 1); } s++; dst += nb; len -= nb; nbytes += nb; } *src = s; return (nbytes); } Index: head/lib/libc/locale/wcstombs.c =================================================================== --- head/lib/libc/locale/wcstombs.c (revision 103011) +++ head/lib/libc/locale/wcstombs.c (revision 103012) @@ -1,94 +1,94 @@ /*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include size_t wcstombs(s, pwcs, n) - char *__restrict s; - const wchar_t *__restrict pwcs; + char * __restrict s; + const wchar_t * __restrict pwcs; size_t n; { char buf[MB_LEN_MAX]; char *e; int cnt, nb; if (!pwcs || n > INT_MAX) { errno = EINVAL; return (-1); } cnt = 0; if (s == NULL) { /* Convert and count only, do not store. */ while (*pwcs != L'\0') { if (!sputrune(*pwcs++, buf, MB_LEN_MAX, &e)) { errno = EILSEQ; return (-1); } cnt += e - buf; } return (cnt); } /* Convert, store and count characters. */ nb = n; while (nb > 0) { if (*pwcs == 0) { *s = 0; break; } if (!sputrune(*pwcs++, s, nb, &e)) { errno = EILSEQ; return (-1); } if (!e) /* too long */ return (cnt); cnt += e - s; nb -= e - s; s = e; } return (cnt); } Index: head/lib/libc/net/inet.3 =================================================================== --- head/lib/libc/net/inet.3 (revision 103011) +++ head/lib/libc/net/inet.3 (revision 103012) @@ -1,276 +1,276 @@ .\" Copyright (c) 1983, 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" From: @(#)inet.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" .Dd June 17, 1996 .Dt INET 3 .Os .Sh NAME .Nm inet_aton , .Nm inet_addr , .Nm inet_network , .Nm inet_ntoa , .Nm inet_ntop , .Nm inet_pton , .Nm inet_makeaddr , .Nm inet_lnaof , .Nm inet_netof .Nd Internet address manipulation routines .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/types.h .In sys/socket.h .In netinet/in.h .In arpa/inet.h .Ft int .Fn inet_aton "const char *cp" "struct in_addr *pin" .Ft in_addr_t .Fn inet_addr "const char *cp" .Ft in_addr_t .Fn inet_network "const char *cp" .Ft char * .Fn inet_ntoa "struct in_addr in" .Ft const char * .Fo inet_ntop .Fa "int af" -.Fa "const void *restrict src" -.Fa "char *restrict dst" +.Fa "const void * restrict src" +.Fa "char * restrict dst" .Fa "socklen_t size" .Fc .Ft int -.Fn inet_pton "int af" "const char *restrict src" "void *restrict dst" +.Fn inet_pton "int af" "const char * restrict src" "void * restrict dst" .Ft struct in_addr .Fn inet_makeaddr "in_addr_t net" "in_addr_t lna" .Ft in_addr_t .Fn inet_lnaof "struct in_addr in" .Ft in_addr_t .Fn inet_netof "struct in_addr in" .Sh DESCRIPTION The routines .Fn inet_aton , .Fn inet_addr and .Fn inet_network interpret character strings representing numbers expressed in the Internet standard .Ql .\& notation. .Pp The .Fn inet_pton function converts a presentation format address (that is, printable form as held in a character string) to network format (usually a .Ft struct in_addr or some other internal binary representation, in network byte order). It returns 1 if the address was valid for the specified address family, or 0 if the address wasn't parseable in the specified address family, or -1 if some system error occurred (in which case .Va errno will have been set). This function is presently valid for .Dv AF_INET and .Dv AF_INET6 . .Pp The .Fn inet_aton routine interprets the specified character string as an Internet address, placing the address into the structure provided. It returns 1 if the string was successfully interpreted, or 0 if the string is invalid. The .Fn inet_addr and .Fn inet_network functions return numbers suitable for use as Internet addresses and Internet network numbers, respectively. .Pp The function .Fn inet_ntop converts an address from network format (usually a .Ft struct in_addr or some other binary form, in network byte order) to presentation format (suitable for external display purposes). It returns NULL if a system error occurs (in which case, .Va errno will have been set), or it returns a pointer to the destination string. This function is presently valid for .Dv AF_INET and .Dv AF_INET6 . .Pp The routine .Fn inet_ntoa takes an Internet address and returns an .Tn ASCII string representing the address in .Ql .\& notation. The routine .Fn inet_makeaddr takes an Internet network number and a local network address and constructs an Internet address from it. The routines .Fn inet_netof and .Fn inet_lnaof break apart Internet host addresses, returning the network number and local network address part, respectively. .Pp All Internet addresses are returned in network order (bytes ordered from left to right). All network numbers and local address parts are returned as machine byte order integer values. .Sh INTERNET ADDRESSES Values specified using the .Ql .\& notation take one of the following forms: .Bd -literal -offset indent a.b.c.d a.b.c a.b a .Ed .Pp When four parts are specified, each is interpreted as a byte of data and assigned, from left to right, to the four bytes of an Internet address. Note that when an Internet address is viewed as a 32-bit integer quantity on the .Tn VAX the bytes referred to above appear as .Dq Li d.c.b.a . That is, .Tn VAX bytes are ordered from right to left. .Pp When a three part address is specified, the last part is interpreted as a 16-bit quantity and placed in the right-most two bytes of the network address. This makes the three part address format convenient for specifying Class B network addresses as .Dq Li 128.net.host . .Pp When a two part address is supplied, the last part is interpreted as a 24-bit quantity and placed in the right most three bytes of the network address. This makes the two part address format convenient for specifying Class A network addresses as .Dq Li net.host . .Pp When only one part is given, the value is stored directly in the network address without any byte rearrangement. .Pp All numbers supplied as .Dq parts in a .Ql .\& notation may be decimal, octal, or hexadecimal, as specified in the C language (i.e., a leading 0x or 0X implies hexadecimal; otherwise, a leading 0 implies octal; otherwise, the number is interpreted as decimal). .Pp The .Fn inet_aton and .Fn inet_ntoa functions are semi-deprecated in favor of the .Xr addr2ascii 3 family. However, since those functions are not yet widely implemented, portable programs cannot rely on their presence and will continue to use the .Xr inet 3 functions for some time. .Sh DIAGNOSTICS The constant .Dv INADDR_NONE is returned by .Fn inet_addr and .Fn inet_network for malformed requests. .Sh SEE ALSO .Xr addr2ascii 3 , .Xr byteorder 3 , .Xr gethostbyname 3 , .Xr getnetent 3 , .Xr inet_net 3 , .Xr hosts 5 , .Xr networks 5 .Rs .%R RFC .%N 2373 .%D July 1998 .%T "IP Version 6 Addressing Architecture" .Re .Sh STANDARDS The .Fn inet_ntop and .Fn inet_pton functions conform to .St -xns5.2 . Note that .Fn inet_pton does not accept 1-, 2-, or 3-part dotted addresses; all four parts must be specified and are interpreted only as decimal values. This is a narrower input set than that accepted by .Fn inet_aton . .Sh HISTORY These functions appeared in .Bx 4.2 . .Sh BUGS The value .Dv INADDR_NONE (0xffffffff) is a valid broadcast address, but .Fn inet_addr cannot return that value without indicating failure. The newer .Fn inet_aton function does not share this problem. The problem of host byte ordering versus network byte ordering is confusing. The string returned by .Fn inet_ntoa resides in a static memory area. .Pp Inet_addr should return a .Fa struct in_addr . Index: head/lib/libc/net/inet_ntop.c =================================================================== --- head/lib/libc/net/inet_ntop.c (revision 103011) +++ head/lib/libc/net/inet_ntop.c (revision 103012) @@ -1,188 +1,188 @@ /* Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #if defined(LIBC_SCCS) && !defined(lint) static char rcsid[] = "$Id: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static const char *inet_ntop4(const u_char *src, char *dst, socklen_t size); static const char *inet_ntop6(const u_char *src, char *dst, socklen_t size); /* char * * inet_ntop(af, src, dst, size) * convert a network format address to presentation format. * return: * pointer to presentation format address (`dst'), or NULL (see errno). * author: * Paul Vixie, 1996. */ const char * -inet_ntop(int af, const void *__restrict src, char *__restrict dst, +inet_ntop(int af, const void * __restrict src, char * __restrict dst, socklen_t size) { switch (af) { case AF_INET: return (inet_ntop4(src, dst, size)); case AF_INET6: return (inet_ntop6(src, dst, size)); default: errno = EAFNOSUPPORT; return (NULL); } /* NOTREACHED */ } /* const char * * inet_ntop4(src, dst, size) * format an IPv4 address, more or less like inet_ntoa() * return: * `dst' (as a const) * notes: * (1) uses no statics * (2) takes a u_char* not an in_addr as input * author: * Paul Vixie, 1996. */ static const char * inet_ntop4(const u_char *src, char *dst, socklen_t size) { static const char fmt[] = "%u.%u.%u.%u"; if ((socklen_t)snprintf(dst, size, fmt, src[0], src[1], src[2], src[3]) >= size) { errno = ENOSPC; return (NULL); } return (dst); } /* const char * * inet_ntop6(src, dst, size) * convert IPv6 binary address into presentation (printable) format * author: * Paul Vixie, 1996. */ static const char * inet_ntop6(const u_char *src, char *dst, socklen_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; struct { int base, len; } best, cur; u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; int i; /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof words); for (i = 0; i < NS_IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; cur.base = -1; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) *tp++ = ':'; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) return (NULL); tp += strlen(tp); break; } tp += sprintf(tp, "%x", words[i]); } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) *tp++ = ':'; *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((socklen_t)(tp - tmp) > size) { errno = ENOSPC; return (NULL); } strcpy(dst, tmp); return (dst); } /* * Weak aliases for applications that use certain private entry points, * and fail to include . */ #undef inet_ntop __weak_reference(__inet_ntop, inet_ntop); Index: head/lib/libc/net/inet_pton.c =================================================================== --- head/lib/libc/net/inet_pton.c (revision 103011) +++ head/lib/libc/net/inet_pton.c (revision 103012) @@ -1,215 +1,215 @@ /* $KAME: inet_pton.c,v 1.5 2001/08/20 02:32:40 itojun Exp $ */ /* Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static int inet_pton4(const char *src, u_char *dst); static int inet_pton6(const char *src, u_char *dst); /* int * inet_pton(af, src, dst) * convert from presentation format (which usually means ASCII printable) * to network format (which is usually some kind of binary format). * return: * 1 if the address was valid for the specified address family * 0 if the address wasn't valid (`dst' is untouched in this case) * -1 if some other error occurred (`dst' is untouched in this case, too) * author: * Paul Vixie, 1996. */ int -inet_pton(int af, const char *__restrict src, void *__restrict dst) +inet_pton(int af, const char * __restrict src, void * __restrict dst) { switch (af) { case AF_INET: return (inet_pton4(src, dst)); case AF_INET6: return (inet_pton6(src, dst)); default: errno = EAFNOSUPPORT; return (-1); } /* NOTREACHED */ } /* int * inet_pton4(src, dst) * like inet_aton() but without all the hexadecimal and shorthand. * return: * 1 if `src' is a valid dotted quad, else 0. * notice: * does not touch `dst' unless it's returning 1. * author: * Paul Vixie, 1996. */ static int inet_pton4(const char *src, u_char *dst) { static const char digits[] = "0123456789"; int saw_digit, octets, ch; u_char tmp[NS_INADDRSZ], *tp; saw_digit = 0; octets = 0; *(tp = tmp) = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr(digits, ch)) != NULL) { u_int new = *tp * 10 + (pch - digits); if (new > 255) return (0); *tp = new; if (! saw_digit) { if (++octets > 4) return (0); saw_digit = 1; } } else if (ch == '.' && saw_digit) { if (octets == 4) return (0); *++tp = 0; saw_digit = 0; } else return (0); } if (octets < 4) return (0); memcpy(dst, tmp, NS_INADDRSZ); return (1); } /* int * inet_pton6(src, dst) * convert presentation level address to network order binary form. * return: * 1 if `src' is a valid [RFC1884 2.2] address, else 0. * notice: * (1) does not touch `dst' unless it's returning 1. * (2) :: in a full address is silently ignored. * credit: * inspired by Mark Andrews. * author: * Paul Vixie, 1996. */ static int inet_pton6(const char *src, u_char *dst) { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; int ch, saw_xdigit; u_int val; memset((tp = tmp), '\0', NS_IN6ADDRSZ); endp = tp + NS_IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') return (0); curtok = src; saw_xdigit = 0; val = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { val <<= 4; val |= (pch - xdigits); if (val > 0xffff) return (0); saw_xdigit = 1; continue; } if (ch == ':') { curtok = src; if (!saw_xdigit) { if (colonp) return (0); colonp = tp; continue; } if (tp + NS_INT16SZ > endp) return (0); *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; saw_xdigit = 0; val = 0; continue; } if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0) { tp += NS_INADDRSZ; saw_xdigit = 0; break; /* '\0' was seen by inet_pton4(). */ } return (0); } if (saw_xdigit) { if (tp + NS_INT16SZ > endp) return (0); *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; } if (colonp != NULL) { /* * Since some memmove()'s erroneously fail to handle * overlapping regions, we'll do the shift by hand. */ const int n = tp - colonp; int i; for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; } tp = endp; } if (tp != endp) return (0); memcpy(dst, tmp, NS_IN6ADDRSZ); return (1); } /* * Weak aliases for applications that use certain private entry points, * and fail to include . */ #undef inet_pton __weak_reference(__inet_pton, inet_pton); Index: head/lib/libc/stdio/fgetws.3 =================================================================== --- head/lib/libc/stdio/fgetws.3 (revision 103011) +++ head/lib/libc/stdio/fgetws.3 (revision 103012) @@ -1,122 +1,122 @@ .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Chris Torek and the American National Standards Committee X3, .\" on Information Processing Systems. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)fgets.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/stdio/fgets.3,v 1.16 2002/05/31 05:01:17 archie Exp .\" $FreeBSD$ .\" .Dd August 6, 2002 .Dt FGETWS 3 .Os .Sh NAME .Nm fgetws .Nd get a line of wide characters from a stream .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdio.h .In wchar.h .Ft "wchar_t *" -.Fn fgetws "wchar_t *restrict ws" "int n" "FILE *restrict fp" +.Fn fgetws "wchar_t * restrict ws" "int n" "FILE * restrict fp" .Sh DESCRIPTION The .Fn fgetws function reads at most one less than the number of characters specified by .Fa n from the given .Fa fp and stores them in the wide character string .Fa ws . Reading stops when a newline character is found, at end-of-file or error. The newline, if any, is retained. If any characters are read and there is no error, a .Ql \e0 character is appended to end the string. .Sh RETURN VALUES Upon successful completion, .Fn fgetws returns .Fa ws . If end-of-file occurs before any characters are read, .Fn fgetws returns .Dv NULL and the buffer contents remain unchanged. If an error occurs, .Fn fgetws returns .Dv NULL and the buffer contents are indeterminate. The .Fn fgetws function does not distinguish between end-of-file and error, and callers must use .Xr feof 3 and .Xr ferror 3 to determine which occurred. .Sh ERRORS .Bl -tag -width Er .It Bq Er EBADF The given .Fa fp argument is not a readable stream. .It Bq Er EILSEQ The data obtained from the input stream does not form a valid multibyte character. .El .Pp The function .Fn fgetws may also fail and set .Va errno for any of the errors specified for the routines .Xr fflush 3 , .Xr fstat 2 , .Xr read 2 , or .Xr malloc 3 . .Sh SEE ALSO .Xr feof 3 , .Xr ferror 3 , .Xr fgets 3 .Sh STANDARDS The .Fn fgetws function conforms to .St -p1003.1-2001 . Index: head/lib/libc/stdio/fgetws.c =================================================================== --- head/lib/libc/stdio/fgetws.c (revision 103011) +++ head/lib/libc/stdio/fgetws.c (revision 103012) @@ -1,70 +1,70 @@ /*- * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" wchar_t * -fgetws(wchar_t *__restrict ws, int n, FILE *__restrict fp) +fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp) { wchar_t *wsp; long r; ORIENTLOCK(fp, 1); if (n <= 0) return (NULL); wsp = ws; while (n-- > 1) { /* XXX Inefficient */ if ((r = fgetrune(fp)) == _INVALID_RUNE) { errno = EILSEQ; return (NULL); } if (r == EOF) { if (wsp == ws) /* EOF/error, no characters read yet. */ return (NULL); break; } *wsp++ = (wchar_t)r; if (r == L'\n') break; } *wsp++ = L'\0'; return (ws); } Index: head/lib/libc/stdio/fprintf.c =================================================================== --- head/lib/libc/stdio/fprintf.c (revision 103011) +++ head/lib/libc/stdio/fprintf.c (revision 103012) @@ -1,56 +1,56 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)fprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include int -fprintf(FILE *__restrict fp, const char *__restrict fmt, ...) +fprintf(FILE * __restrict fp, const char * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vfprintf(fp, fmt, ap); va_end(ap); return (ret); } Index: head/lib/libc/stdio/fputws.3 =================================================================== --- head/lib/libc/stdio/fputws.3 (revision 103011) +++ head/lib/libc/stdio/fputws.3 (revision 103012) @@ -1,89 +1,89 @@ .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Chris Torek and the American National Standards Committee X3, .\" on Information Processing Systems. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)fputs.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/stdio/fputs.3,v 1.8 2001/10/01 16:08:59 ru Exp .\" $FreeBSD$ .\" .Dd August 6, 2002 .Dt FPUTWS 3 .Os .Sh NAME .Nm fputws .Nd output a line of wide characters to a stream .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdio.h .In wchar.h .Ft int -.Fn fputws "const wchar_t *restrict ws" "FILE *restrict fp" +.Fn fputws "const wchar_t * restrict ws" "FILE * restrict fp" .Sh DESCRIPTION The .Fn fputws function writes the wide character string pointed to by .Fa ws to the stream pointed to by .Fa fp . .Sh RETURN VALUES The .Fn fputws function returns 0 on success and -1 on error. .Sh ERRORS .Bl -tag -width Er .It Bq Er EBADF The .Fa fp argument supplied is not a writable stream. .El .Pp The .Fn fputws function may also fail and set .Va errno for any of the errors specified for the routine .Xr write 2 . .Sh SEE ALSO .Xr ferror 3 , .Xr fputs 3 , .Xr putwc 3 , .Xr stdio 3 .Sh STANDARDS The .Fn fputws function conforms to .St -p1003.1-2001 . Index: head/lib/libc/stdio/fputws.c =================================================================== --- head/lib/libc/stdio/fputws.c (revision 103011) +++ head/lib/libc/stdio/fputws.c (revision 103012) @@ -1,51 +1,51 @@ /*- * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" int -fputws(const wchar_t *__restrict ws, FILE *__restrict fp) +fputws(const wchar_t * __restrict ws, FILE * __restrict fp) { ORIENTLOCK(fp, 1); /* XXX Inefficient */ while (*ws != '\0') if (fputrune((rune_t)*ws++, fp) == EOF) return (-1); return (0); } Index: head/lib/libc/stdio/printf.3 =================================================================== --- head/lib/libc/stdio/printf.3 (revision 103011) +++ head/lib/libc/stdio/printf.3 (revision 103012) @@ -1,860 +1,860 @@ .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Chris Torek and the American National Standards Committee X3, .\" on Information Processing Systems. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)printf.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" .Dd November 8, 2001 .Dt PRINTF 3 .Os .Sh NAME .Nm printf , fprintf , sprintf , snprintf , asprintf , .Nm vprintf , vfprintf, vsprintf , vsnprintf , vasprintf .Nd formatted output conversion .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdio.h .Ft int -.Fn printf "const char *restrict format" ... +.Fn printf "const char * restrict format" ... .Ft int -.Fn fprintf "FILE *restrict stream" "const char *restrict format" ... +.Fn fprintf "FILE * restrict stream" "const char * restrict format" ... .Ft int -.Fn sprintf "char *restrict str" "const char *restrict format" ... +.Fn sprintf "char * restrict str" "const char * restrict format" ... .Ft int -.Fn snprintf "char *restrict str" "size_t size" "const char *restrict format" ... +.Fn snprintf "char * restrict str" "size_t size" "const char * restrict format" ... .Ft int .Fn asprintf "char **ret" "const char *format" ... .In stdarg.h .Ft int -.Fn vprintf "const char *restrict format" "va_list ap" +.Fn vprintf "const char * restrict format" "va_list ap" .Ft int -.Fn vfprintf "FILE *restrict stream" "const char *restrict format" "va_list ap" +.Fn vfprintf "FILE * restrict stream" "const char * restrict format" "va_list ap" .Ft int -.Fn vsprintf "char *restrict str" "const char *restrict format" "va_list ap" +.Fn vsprintf "char * restrict str" "const char * restrict format" "va_list ap" .Ft int -.Fn vsnprintf "char *restrict str" "size_t size" "const char *restrict format" "va_list ap" +.Fn vsnprintf "char * restrict str" "size_t size" "const char * restrict format" "va_list ap" .Ft int .Fn vasprintf "char **ret" "const char *format" "va_list ap" .Sh DESCRIPTION The .Fn printf family of functions produces output according to a .Fa format as described below. .Fn Printf and .Fn vprintf write output to .Pa stdout , the standard output stream; .Fn fprintf and .Fn vfprintf write output to the given output .Fa stream ; .Fn sprintf , .Fn snprintf , .Fn vsprintf , and .Fn vsnprintf write to the character string .Fa str ; and .Fn asprintf and .Fn vasprintf dynamically allocate a new string with .Xr malloc 3 . .Pp These functions write the output under the control of a .Fa format string that specifies how subsequent arguments (or arguments accessed via the variable-length argument facilities of .Xr stdarg 3 ) are converted for output. .Pp These functions return the number of characters printed (not including the trailing .Ql \e0 used to end output to strings), except for .Fn snprintf and .Fn vsnprintf , which return the number of characters that would have been printed if the .Fa size were unlimited (again, not including the final .Ql \e0 ) . .Pp .Fn Asprintf and .Fn vasprintf set .Fa *ret to be a pointer to a buffer sufficiently large to hold the formatted string. This pointer should be passed to .Xr free 3 to release the allocated storage when it is no longer needed. If sufficient space cannot be allocated, .Fn asprintf and .Fn vasprintf will return \-1 and set .Fa ret to be a .Dv NULL pointer. .Pp .Fn Snprintf and .Fn vsnprintf will write at most .Fa size Ns \-1 of the characters printed into the output string (the .Fa size Ns 'th character then gets the terminating .Ql \e0 ) ; if the return value is greater than or equal to the .Fa size argument, the string was too short and some of the printed characters were discarded. The output is always null-terminated. .Pp .Fn Sprintf and .Fn vsprintf effectively assume an infinite .Fa size . .Pp The format string is composed of zero or more directives: ordinary .\" multibyte characters (not .Cm % ) , which are copied unchanged to the output stream; and conversion specifications, each of which results in fetching zero or more subsequent arguments. Each conversion specification is introduced by the .Cm % character. The arguments must correspond properly (after type promotion) with the conversion specifier. After the .Cm % , the following appear in sequence: .Bl -bullet .It An optional field, consisting of a decimal digit string followed by a .Cm $ , specifying the next argument to access. If this field is not provided, the argument following the last argument accessed will be used. Arguments are numbered starting at .Cm 1 . If unaccessed arguments in the format string are interspersed with ones that are accessed the results will be indeterminate. .It Zero or more of the following flags: .Bl -tag -width ".So \ Sc (space)" .It Sq Cm # The value should be converted to an .Dq alternate form . For .Cm c , d , i , n , p , s , and .Cm u conversions, this option has no effect. For .Cm o conversions, the precision of the number is increased to force the first character of the output string to a zero (except if a zero value is printed with an explicit precision of zero). For .Cm x and .Cm X conversions, a non-zero result has the string .Ql 0x (or .Ql 0X for .Cm X conversions) prepended to it. For .Cm a , A , e , E , f , F , g , and .Cm G conversions, the result will always contain a decimal point, even if no digits follow it (normally, a decimal point appears in the results of those conversions only if a digit follows). For .Cm g and .Cm G conversions, trailing zeros are not removed from the result as they would otherwise be. .It So Cm 0 Sc (zero) Zero padding. For all conversions except .Cm n , the converted value is padded on the left with zeros rather than blanks. If a precision is given with a numeric conversion .Cm ( d , i , o , u , i , x , and .Cm X ) , the .Cm 0 flag is ignored. .It Sq Cm \- A negative field width flag; the converted value is to be left adjusted on the field boundary. Except for .Cm n conversions, the converted value is padded on the right with blanks, rather than on the left with blanks or zeros. A .Cm \- overrides a .Cm 0 if both are given. .It So "\ " Sc (space) A blank should be left before a positive number produced by a signed conversion .Cm ( a , A , d , e , E , f , F , g , G , or .Cm i ) . .It Sq Cm + A sign must always be placed before a number produced by a signed conversion. A .Cm + overrides a space if both are used. .It Sq Cm ' Decimal conversions .Cm ( d , u , or .Cm i ) or the integral portion of a floating point conversion .Cm ( f or .Cm F ) should be grouped and separated by thousands using the non-monetary separator returned by .Xr localeconv 3 . .El .It An optional decimal digit string specifying a minimum field width. If the converted value has fewer characters than the field width, it will be padded with spaces on the left (or right, if the left-adjustment flag has been given) to fill out the field width. .It An optional precision, in the form of a period .Cm \&. followed by an optional digit string. If the digit string is omitted, the precision is taken as zero. This gives the minimum number of digits to appear for .Cm d , i , o , u , x , and .Cm X conversions, the number of digits to appear after the decimal-point for .Cm a , A , e , E , f , and .Cm F conversions, the maximum number of significant digits for .Cm g and .Cm G conversions, or the maximum number of characters to be printed from a string for .Cm s conversions. .It An optional length modifier, that specifies the size of the argument. The following length modifiers are valid for the .Cm d , i , n , o , u , x , or .Cm X conversion: .Bl -column ".Cm q Em (deprecated)" ".Vt signed char" ".Vt unsigned long long" ".Vt long long *" .It Sy Modifier Ta Cm d , i Ta Cm o , u , x , X Ta Cm n .It Cm hh Ta Vt "signed char" Ta Vt "unsigned char" Ta Vt "signed char *" .It Cm h Ta Vt short Ta Vt "unsigned short" Ta Vt "short *" .It Cm l No (ell) Ta Vt long Ta Vt "unsigned long" Ta Vt "long *" .It Cm ll No (ell ell) Ta Vt "long long" Ta Vt "unsigned long long" Ta Vt "long long *" .It Cm j Ta Vt intmax_t Ta Vt uintmax_t Ta Vt "intmax_t *" .It Cm t Ta Vt ptrdiff_t Ta (see note) Ta Vt "ptrdiff_t *" .It Cm z Ta (see note) Ta Vt size_t Ta (see note) .It Cm q Em (deprecated) Ta Vt quad_t Ta Vt u_quad_t Ta Vt "quad_t *" .El .Pp Note: the .Cm t modifier, when applied to a .Cm o , u , x , or .Cm X conversion, indicates that the argument is of an unsigned type equivalent in size to a .Vt ptrdiff_t . The .Cm z modifier, when applied to a .Cm d or .Cm i conversion, indicates that the argument is of a signed type equivalent in size to a .Vt size_t . Similarly, when applied to an .Cm n conversion, it indicates that the argument is a pointer to a signed type equivalent in size to a .Vt size_t . .Pp The following length modifier is valid for the .Cm a , A , e , E , f , F , g , or .Cm G conversion: .Bl -column ".Sy Modifier" ".Cm a , A , e , E , f , F , g , G" .It Sy Modifier Ta Cm a , A , e , E , f , F , g , G .It Cm L Ta Vt "long double" .El .Pp The following length modifier is valid for the .Cm c or .Cm s conversion: .Bl -column ".Sy Modifier" ".Vt wint_t" ".Vt wchar_t *" .It Sy Modifier Ta Cm c Ta Cm s .It Cm l No (ell) Ta Vt wint_t Ta Vt "wchar_t *" .El .It A character that specifies the type of conversion to be applied. .El .Pp A field width or precision, or both, may be indicated by an asterisk .Ql * or an asterisk followed by one or more decimal digits and a .Ql $ instead of a digit string. In this case, an .Vt int argument supplies the field width or precision. A negative field width is treated as a left adjustment flag followed by a positive field width; a negative precision is treated as though it were missing. If a single format directive mixes positional .Pq Li nn$ and non-positional arguments, the results are undefined. .Pp The conversion specifiers and their meanings are: .Bl -tag -width ".Cm diouxX" .It Cm diouxX The .Vt int (or appropriate variant) argument is converted to signed decimal .Cm ( d and .Cm i ) , unsigned octal .Pq Cm o , unsigned decimal .Pq Cm u , or unsigned hexadecimal .Cm ( x and .Cm X ) notation. The letters .Dq Li abcdef are used for .Cm x conversions; the letters .Dq Li ABCDEF are used for .Cm X conversions. The precision, if any, gives the minimum number of digits that must appear; if the converted value requires fewer digits, it is padded on the left with zeros. .It Cm DOU The .Vt "long int" argument is converted to signed decimal, unsigned octal, or unsigned decimal, as if the format had been .Cm ld , lo , or .Cm lu respectively. These conversion characters are deprecated, and will eventually disappear. .It Cm eE The .Vt double argument is rounded and converted in the style .Sm off .Oo \- Oc Ar d Li \&. Ar ddd Li e \\*[Pm] Ar dd .Sm on where there is one digit before the decimal-point character and the number of digits after it is equal to the precision; if the precision is missing, it is taken as 6; if the precision is zero, no decimal-point character appears. An .Cm E conversion uses the letter .Ql E (rather than .Ql e ) to introduce the exponent. The exponent always contains at least two digits; if the value is zero, the exponent is 00. .Pp For .Cm a , A , e , E , f , F , g , and .Cm G conversions, positive and negative infinity are represented as .Li inf and .Li -inf respectively when using the lowercase conversion character, and .Li INF and .Li -INF respectively when using the uppercase conversion character. Similarly, NaN is represented as .Li nan when using the lowercase conversion, and .Li NAN when using the uppercase conversion. .It Cm fF The .Vt double argument is rounded and converted to decimal notation in the style .Sm off .Oo \- Oc Ar ddd Li \&. Ar ddd , .Sm on where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; if the precision is explicitly zero, no decimal-point character appears. If a decimal point appears, at least one digit appears before it. .It Cm gG The .Vt double argument is converted in style .Cm f or .Cm e (or .Cm F or .Cm E for .Cm G conversions). The precision specifies the number of significant digits. If the precision is missing, 6 digits are given; if the precision is zero, it is treated as 1. Style .Cm e is used if the exponent from its conversion is less than \-4 or greater than or equal to the precision. Trailing zeros are removed from the fractional part of the result; a decimal point appears only if it is followed by at least one digit. .It Cm aA The .Vt double argument is converted to hexadecimal notation in the style .Sm off .Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \\*[Pm] Oc Ar d , .Sm on where the number of digits after the hexadecimal-point character is equal to the precision specification. If the precision is missing, it is taken as enough to exactly represent the floating-point number; if the precision is explicitly zero, no hexadecimal-point character appears. This is an exact conversion of the mantissa+exponent internal floating point representation; the .Sm off .Oo \- Oc Li 0x Ar h Li \&. Ar hhh .Sm on portion represents exactly the mantissa; only denormalized mantissas have a zero value to the left of the hexadecimal point. The .Cm p is a literal character .Ql p ; the exponent is preceded by a positive or negative sign and is represented in decimal, using only enough characters to represent the exponent. The .Cm A conversion uses the prefix .Dq Li 0X (rather than .Dq Li 0x ) , the letters .Dq Li ABCDEF (rather than .Dq Li abcdef ) to represent the hex digits, and the letter .Ql P (rather than .Ql p ) to separate the mantissa and exponent. .It Cm C Treated as .Cm c with the .Cm l (ell) modifier. .It Cm c The .Vt int argument is converted to an .Vt "unsigned char" , and the resulting character is written. .Pp If the .Cm l (ell) modifier is used, the .Vt wint_t argument shall be converted to a .Vt wchar_t , and the (potentially multi-byte) sequence representing the single wide character is written, including any shift sequences. If a shift sequence is used, the shift state is also restored to the original state after the character. .It Cm S Treated as .Cm s with the .Cm l (ell) modifier. .It Cm s The .Vt "char *" argument is expected to be a pointer to an array of character type (pointer to a string). Characters from the array are written up to (but not including) a terminating .Dv NUL character; if a precision is specified, no more than the number specified are written. If a precision is given, no null character need be present; if the precision is not specified, or is greater than the size of the array, the array must contain a terminating .Dv NUL character. .Pp If the .Cm l (ell) modifier is used, the .Vt "wchar_t *" argument is expected to be a pointer to an array of wide characters (pointer to a wide string). For each wide character in the string, the (potentially multi-byte) sequence representing the wide character is written, including any shift sequences. If any shift sequence is used, the shift state is also restored to the original state after the string. Wide characters from the array are written up to (but not including) a terminating wide .Dv NUL character; if a precision is specified, no more than the number of bytes specified are written (including shift sequences). Partial characters are never written. If a precision is given, no null character need be present; if the precision is not specified, or is greater than the number of bytes required to render the multibyte representation of the string, the array must contain a terminating wide .Dv NUL character. .It Cm p The .Vt "void *" pointer argument is printed in hexadecimal (as if by .Ql %#x or .Ql %#lx ) . .It Cm n The number of characters written so far is stored into the integer indicated by the .Vt "int *" (or variant) pointer argument. No argument is converted. .It Cm % A .Ql % is written. No argument is converted. The complete conversion specification is .Ql %% . .El .Pp The decimal point character is defined in the program's locale (category .Dv LC_NUMERIC ) . .Pp In no case does a non-existent or small field width cause truncation of a numeric field; if the result of a conversion is wider than the field width, the field is expanded to contain the conversion result. .Sh EXAMPLES To print a date and time in the form .Dq Li "Sunday, July 3, 10:02" , where .Fa weekday and .Fa month are pointers to strings: .Bd -literal -offset indent #include fprintf(stdout, "%s, %s %d, %.2d:%.2d\en", weekday, month, day, hour, min); .Ed .Pp To print \*(Pi to five decimal places: .Bd -literal -offset indent #include #include fprintf(stdout, "pi = %.5f\en", 4 * atan(1.0)); .Ed .Pp To allocate a 128 byte string and print into it: .Bd -literal -offset indent #include #include #include char *newfmt(const char *fmt, ...) { char *p; va_list ap; if ((p = malloc(128)) == NULL) return (NULL); va_start(ap, fmt); (void) vsnprintf(p, 128, fmt, ap); va_end(ap); return (p); } .Ed .Sh SECURITY CONSIDERATIONS The .Fn sprintf and .Fn vsprintf functions are easily misused in a manner which enables malicious users to arbitrarily change a running program's functionality through a buffer overflow attack. Because .Fn sprintf and .Fn vsprintf assume an infinitely long string, callers must be careful not to overflow the actual space; this is often hard to assure. For safety, programmers should use the .Fn snprintf interface instead. For example: .Bd -literal void foo(const char *arbitrary_string, const char *and_another) { char onstack[8]; #ifdef BAD /* * This first sprintf is bad behavior. Do not use sprintf! */ sprintf(onstack, "%s, %s", arbitrary_string, and_another); #else /* * The following two lines demonstrate better use of * snprintf(). */ snprintf(onstack, sizeof(onstack), "%s, %s", arbitrary_string, and_another); #endif } .Ed .Pp The .Fn printf and .Fn sprintf family of functions are also easily misused in a manner allowing malicious users to arbitrarily change a running program's functionality by either causing the program to print potentially sensitive data .Dq "left on the stack" , or causing it to generate a memory fault or bus error by dereferencing an invalid pointer. .Pp .Cm %n can be used to write arbitrary data to potentially carefully-selected addresses. Programmers are therefore strongly advised to never pass untrusted strings as the .Fa format argument, as an attacker can put format specifiers in the string to mangle your stack, leading to a possible security hole. This holds true even if the string was built using a function like .Fn snprintf , as the resulting string may still contain user-supplied conversion specifiers for later interpolation by .Fn printf . .Pp Always use the proper secure idiom: .Pp .Dl "snprintf(buffer, sizeof(buffer), \*q%s\*q, string);" .Sh SEE ALSO .Xr printf 1 , .Xr scanf 3 , .Xr setlocale 3 .Rs .%T "The FreeBSD Security Architecture" .Re (See .Pa "/usr/share/doc/{to be determined}" . ) .Sh STANDARDS Subject to the caveats noted in the .Sx BUGS section below, the .Fn fprintf , .Fn printf , .Fn sprintf , .Fn vprintf , .Fn vfprintf , and .Fn vsprintf functions conform to .St -ansiC and .St -isoC-99 . With the same reservation, the .Fn snprintf and .Fn vsnprintf functions conform to .St -isoC-99 . .Sh HISTORY The functions .Fn asprintf and .Fn vasprintf first appeared in the .Tn GNU C library. These were implemented by .An Peter Wemm Aq peter@FreeBSD.org in .Fx 2.2 , but were later replaced with a different implementation from .An Todd C. Miller Aq Todd.Miller@courtesan.com for .Ox 2.3 . .Sh BUGS The conversion formats .Cm \&%D , \&%O , and .Cm %U are not standard and are provided only for backward compatibility. The effect of padding the .Cm %p format with zeros (either by the .Cm 0 flag or by specifying a precision), and the benign effect (i.e., none) of the .Cm # flag on .Cm %n and .Cm %p conversions, as well as other nonsensical combinations such as .Cm %Ld , are not standard; such combinations should be avoided. .Pp The .Nm family of functions currently lack the ability to use the .Cm ' flag in conjunction with the .Cm f conversion specifier. The .Cm a and .Cm A conversion specifiers have not yet been implemented. The .Cm l (ell) modifier for the .Cm c and .Cm s conversion specifiers, for wide characters and strings, have not yet been implemented. The .Cm L modifier for floating point formats simply round the .Vt "long double" argument to .Vt double , providing no additional precision. Index: head/lib/libc/stdio/printf.c =================================================================== --- head/lib/libc/stdio/printf.c (revision 103011) +++ head/lib/libc/stdio/printf.c (revision 103012) @@ -1,56 +1,56 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)printf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include int -printf(char const *__restrict fmt, ...) +printf(char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vfprintf(stdout, fmt, ap); va_end(ap); return (ret); } Index: head/lib/libc/stdio/setbuf.3 =================================================================== --- head/lib/libc/stdio/setbuf.3 (revision 103011) +++ head/lib/libc/stdio/setbuf.3 (revision 103012) @@ -1,205 +1,205 @@ .\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" the American National Standards Committee X3, on Information .\" Processing Systems. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)setbuf.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" .Dd June 4, 1993 .Dt SETBUF 3 .Os .Sh NAME .Nm setbuf , .Nm setbuffer , .Nm setlinebuf , .Nm setvbuf .Nd stream buffering operations .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdio.h .Ft void -.Fn setbuf "FILE *restrict stream" "char *restrict buf" +.Fn setbuf "FILE * restrict stream" "char * restrict buf" .Ft void .Fn setbuffer "FILE *stream" "char *buf" "int size" .Ft int .Fn setlinebuf "FILE *stream" .Ft int -.Fn setvbuf "FILE *restrict stream" "char *restrict buf" "int mode" "size_t size" +.Fn setvbuf "FILE * restrict stream" "char * restrict buf" "int mode" "size_t size" .Sh DESCRIPTION The three types of buffering available are unbuffered, block buffered, and line buffered. When an output stream is unbuffered, information appears on the destination file or terminal as soon as written; when it is block buffered many characters are saved up and written as a block; when it is line buffered characters are saved up until a newline is output or input is read from any stream attached to a terminal device (typically stdin). The function .Xr fflush 3 may be used to force the block out early. (See .Xr fclose 3 . ) .Pp Normally all files are block buffered. When the first .Tn I/O operation occurs on a file, .Xr malloc 3 is called, and an optimally-sized buffer is obtained. If a stream refers to a terminal (as .Em stdout normally does) it is line buffered. The standard error stream .Em stderr is always unbuffered. .Pp The .Fn setvbuf function may be used to alter the buffering behavior of a stream. The .Fa mode parameter must be one of the following three macros: .Bl -tag -width _IOFBF -offset indent .It Dv _IONBF unbuffered .It Dv _IOLBF line buffered .It Dv _IOFBF fully buffered .El .Pp The .Fa size parameter may be given as zero to obtain deferred optimal-size buffer allocation as usual. If it is not zero, then except for unbuffered files, the .Fa buf argument should point to a buffer at least .Fa size bytes long; this buffer will be used instead of the current buffer. (If the .Fa size argument is not zero but .Fa buf is .Dv NULL , a buffer of the given size will be allocated immediately, and released on close. This is an extension to ANSI C; portable code should use a size of 0 with any .Dv NULL buffer.) .Pp The .Fn setvbuf function may be used at any time, but may have peculiar side effects (such as discarding input or flushing output) if the stream is ``active''. Portable applications should call it only once on any given stream, and before any .Tn I/O is performed. .Pp The other three calls are, in effect, simply aliases for calls to .Fn setvbuf . Except for the lack of a return value, the .Fn setbuf function is exactly equivalent to the call .Pp .Dl "setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);" .Pp The .Fn setbuffer function is the same, except that the size of the buffer is up to the caller, rather than being determined by the default .Dv BUFSIZ . The .Fn setlinebuf function is exactly equivalent to the call: .Pp .Dl "setvbuf(stream, (char *)NULL, _IOLBF, 0);" .Sh RETURN VALUES The .Fn setvbuf function returns 0 on success, or .Dv EOF if the request cannot be honored (note that the stream is still functional in this case). .Pp The .Fn setlinebuf function returns what the equivalent .Fn setvbuf would have returned. .Sh SEE ALSO .Xr fclose 3 , .Xr fopen 3 , .Xr fread 3 , .Xr malloc 3 , .Xr printf 3 , .Xr puts 3 .Sh STANDARDS The .Fn setbuf and .Fn setvbuf functions conform to .St -isoC . .Sh BUGS The .Fn setbuffer and .Fn setlinebuf functions are not portable to versions of .Bx before .Bx 4.2 . On .Bx 4.2 and .Bx 4.3 systems, .Fn setbuf always uses a suboptimal buffer size and should be avoided. Index: head/lib/libc/stdio/setbuf.c =================================================================== --- head/lib/libc/stdio/setbuf.c (revision 103011) +++ head/lib/libc/stdio/setbuf.c (revision 103012) @@ -1,50 +1,50 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)setbuf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include "local.h" void -setbuf(FILE *__restrict fp, char *__restrict buf) +setbuf(FILE * __restrict fp, char * __restrict buf) { (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ); } Index: head/lib/libc/stdio/setvbuf.c =================================================================== --- head/lib/libc/stdio/setvbuf.c (revision 103011) +++ head/lib/libc/stdio/setvbuf.c (revision 103012) @@ -1,165 +1,165 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)setvbuf.c 8.2 (Berkeley) 11/16/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include "un-namespace.h" #include "local.h" #include "libc_private.h" /* * Set one of the three kinds of buffering, optionally including * a buffer. */ int -setvbuf(FILE *__restrict fp, char *__restrict buf, int mode, size_t size) +setvbuf(FILE * __restrict fp, char * __restrict buf, int mode, size_t size) { int ret, flags; size_t iosize; int ttyflag; /* * Verify arguments. The `int' limit on `size' is due to this * particular implementation. Note, buf and size are ignored * when setting _IONBF. */ if (mode != _IONBF) if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0) return (EOF); FLOCKFILE(fp); /* * Write current buffer, if any. Discard unread input (including * ungetc data), cancel line buffering, and free old buffer if * malloc()ed. We also clear any eof condition, as if this were * a seek. */ ret = 0; (void)__sflush(fp); if (HASUB(fp)) FREEUB(fp); fp->_r = fp->_lbfsize = 0; flags = fp->_flags; if (flags & __SMBF) free((void *)fp->_bf._base); flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SOFF | __SNPT | __SEOF); /* If setting unbuffered mode, skip all the hard work. */ if (mode == _IONBF) goto nbf; /* * Find optimal I/O size for seek optimization. This also returns * a `tty flag' to suggest that we check isatty(fd), but we do not * care since our caller told us how to buffer. */ flags |= __swhatbuf(fp, &iosize, &ttyflag); if (size == 0) { buf = NULL; /* force local allocation */ size = iosize; } /* Allocate buffer if needed. */ if (buf == NULL) { if ((buf = malloc(size)) == NULL) { /* * Unable to honor user's request. We will return * failure, but try again with file system size. */ ret = EOF; if (size != iosize) { size = iosize; buf = malloc(size); } } if (buf == NULL) { /* No luck; switch to unbuffered I/O. */ nbf: fp->_flags = flags | __SNBF; fp->_w = 0; fp->_bf._base = fp->_p = fp->_nbuf; fp->_bf._size = 1; FUNLOCKFILE(fp); return (ret); } flags |= __SMBF; } /* * Kill any seek optimization if the buffer is not the * right size. * * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)? */ if (size != iosize) flags |= __SNPT; /* * Fix up the FILE fields, and set __cleanup for output flush on * exit (since we are buffered in some way). */ if (mode == _IOLBF) flags |= __SLBF; fp->_flags = flags; fp->_bf._base = fp->_p = (unsigned char *)buf; fp->_bf._size = size; /* fp->_lbfsize is still 0 */ if (flags & __SWR) { /* * Begin or continue writing: see __swsetup(). Note * that __SNBF is impossible (it was handled earlier). */ if (flags & __SLBF) { fp->_w = 0; fp->_lbfsize = -fp->_bf._size; } else fp->_w = size; } else { /* begin/continue reading, or stay in intermediate state */ fp->_w = 0; } __cleanup = _cleanup; FUNLOCKFILE(fp); return (ret); } Index: head/lib/libc/stdio/snprintf.c =================================================================== --- head/lib/libc/stdio/snprintf.c (revision 103011) +++ head/lib/libc/stdio/snprintf.c (revision 103012) @@ -1,75 +1,75 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "local.h" int -snprintf(char *__restrict str, size_t n, char const *__restrict fmt, ...) +snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...) { size_t on; int ret; va_list ap; FILE f; struct __sFILEX ext; on = n; if (n != 0) n--; if (n > INT_MAX) n = INT_MAX; va_start(ap, fmt); f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n; f._extra = &ext; INITEXTRA(&f); ret = __vfprintf(&f, fmt, ap); if (on > 0) *f._p = '\0'; va_end(ap); return (ret); } Index: head/lib/libc/stdio/sprintf.c =================================================================== --- head/lib/libc/stdio/sprintf.c (revision 103011) +++ head/lib/libc/stdio/sprintf.c (revision 103012) @@ -1,67 +1,67 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)sprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "local.h" int -sprintf(char *__restrict str, char const *__restrict fmt, ...) +sprintf(char * __restrict str, char const * __restrict fmt, ...) { int ret; va_list ap; FILE f; struct __sFILEX ext; f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = INT_MAX; f._extra = &ext; INITEXTRA(&f); va_start(ap, fmt); ret = __vfprintf(&f, fmt, ap); va_end(ap); *f._p = 0; return (ret); } Index: head/lib/libc/stdio/vfprintf.c =================================================================== --- head/lib/libc/stdio/vfprintf.c (revision 103011) +++ head/lib/libc/stdio/vfprintf.c (revision 103012) @@ -1,1459 +1,1459 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); /* * Actual printf innards. * * This code is large and complicated... */ #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "fvwrite.h" /* Define FLOATING_POINT to get floating point. */ #define FLOATING_POINT union arg { int intarg; u_int uintarg; long longarg; u_long ulongarg; long long longlongarg; unsigned long long ulonglongarg; ptrdiff_t ptrdiffarg; size_t sizearg; intmax_t intmaxarg; uintmax_t uintmaxarg; void *pvoidarg; char *pchararg; signed char *pschararg; short *pshortarg; int *pintarg; long *plongarg; long long *plonglongarg; ptrdiff_t *pptrdiffarg; size_t *psizearg; intmax_t *pintmaxarg; #ifdef FLOATING_POINT double doublearg; long double longdoublearg; #endif }; /* * Type ids for argument type table. */ enum typeid { T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT, T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG, T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET, T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR, T_DOUBLE, T_LONG_DOUBLE }; static int __sprint(FILE *, struct __suio *); static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0); static char *__ujtoa(uintmax_t, char *, int, int, char *, int, char, const char *); static char *__ultoa(u_long, char *, int, int, char *, int, char, const char *); static void __find_arguments(const char *, va_list, union arg **); static void __grow_type_table(int, enum typeid **, int *); /* * Flush out all the vectors defined by the given uio, * then reset it so that it can be reused. */ static int __sprint(FILE *fp, struct __suio *uio) { int err; if (uio->uio_resid == 0) { uio->uio_iovcnt = 0; return (0); } err = __sfvwrite(fp, uio); uio->uio_resid = 0; uio->uio_iovcnt = 0; return (err); } /* * Helper function for `fprintf to unbuffered unix file': creates a * temporary buffer. We only work on write-only files; this avoids * worries about ungetc buffers and so forth. */ static int __sbprintf(FILE *fp, const char *fmt, va_list ap) { int ret; FILE fake; unsigned char buf[BUFSIZ]; /* copy the important variables */ fake._flags = fp->_flags & ~__SNBF; fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; fake._extra = fp->_extra; /* set up the buffer */ fake._bf._base = fake._p = buf; fake._bf._size = fake._w = sizeof(buf); fake._lbfsize = 0; /* not actually used, but Just In Case */ /* do the work, then copy any error status */ ret = __vfprintf(&fake, fmt, ap); if (ret >= 0 && __fflush(&fake)) ret = EOF; if (fake._flags & __SERR) fp->_flags |= __SERR; return (ret); } /* * Macros for converting digits to letters and vice versa */ #define to_digit(c) ((c) - '0') #define is_digit(c) ((unsigned)to_digit(c) <= 9) #define to_char(n) ((n) + '0') /* * Convert an unsigned long to ASCII for printf purposes, returning * a pointer to the first character of the string representation. * Octal numbers can be forced to have a leading zero; hex numbers * use the given digits. */ static char * __ultoa(u_long val, char *endp, int base, int octzero, char *xdigs, int needgrp, char thousep, const char *grp) { char *cp = endp; long sval; int ndig; /* * Handle the three cases separately, in the hope of getting * better/faster code. */ switch (base) { case 10: if (val < 10) { /* many numbers are 1 digit */ *--cp = to_char(val); return (cp); } ndig = 0; /* * On many machines, unsigned arithmetic is harder than * signed arithmetic, so we do at most one unsigned mod and * divide; this is sufficient to reduce the range of * the incoming value to where signed arithmetic works. */ if (val > LONG_MAX) { *--cp = to_char(val % 10); ndig++; sval = val / 10; } else sval = val; do { *--cp = to_char(sval % 10); ndig++; /* * If (*grp == CHAR_MAX) then no more grouping * should be performed. */ if (needgrp && ndig == *grp && *grp != CHAR_MAX && sval > 9) { *--cp = thousep; ndig = 0; /* * If (*(grp+1) == '\0') then we have to * use *grp character (last grouping rule) * for all next cases */ if (*(grp+1) != '\0') grp++; } sval /= 10; } while (sval != 0); break; case 8: do { *--cp = to_char(val & 7); val >>= 3; } while (val); if (octzero && *cp != '0') *--cp = '0'; break; case 16: do { *--cp = xdigs[val & 15]; val >>= 4; } while (val); break; default: /* oops */ abort(); } return (cp); } /* Identical to __ultoa, but for intmax_t. */ static char * __ujtoa(uintmax_t val, char *endp, int base, int octzero, char *xdigs, int needgrp, char thousep, const char *grp) { char *cp = endp; intmax_t sval; int ndig; /* quick test for small values; __ultoa is typically much faster */ /* (perhaps instead we should run until small, then call __ultoa?) */ if (val <= ULONG_MAX) return (__ultoa((u_long)val, endp, base, octzero, xdigs, needgrp, thousep, grp)); switch (base) { case 10: if (val < 10) { *--cp = to_char(val % 10); return (cp); } ndig = 0; if (val > INTMAX_MAX) { *--cp = to_char(val % 10); ndig++; sval = val / 10; } else sval = val; do { *--cp = to_char(sval % 10); ndig++; /* * If (*grp == CHAR_MAX) then no more grouping * should be performed. */ if (needgrp && *grp != CHAR_MAX && ndig == *grp && sval > 9) { *--cp = thousep; ndig = 0; /* * If (*(grp+1) == '\0') then we have to * use *grp character (last grouping rule) * for all next cases */ if (*(grp+1) != '\0') grp++; } sval /= 10; } while (sval != 0); break; case 8: do { *--cp = to_char(val & 7); val >>= 3; } while (val); if (octzero && *cp != '0') *--cp = '0'; break; case 16: do { *--cp = xdigs[val & 15]; val >>= 4; } while (val); break; default: abort(); } return (cp); } /* * MT-safe version */ int -vfprintf(FILE *__restrict fp, const char *__restrict fmt0, va_list ap) +vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) { int ret; FLOCKFILE(fp); ret = __vfprintf(fp, fmt0, ap); FUNLOCKFILE(fp); return (ret); } #ifdef FLOATING_POINT #include #include "floatio.h" #define BUF ((MAXEXP*2)+MAXFRACT+1) /* + decimal point */ #define DEFPREC 6 static char *cvt(double, int, int, char *, int *, int, int *, char **); static int exponent(char *, int, int); #else /* no FLOATING_POINT */ #define BUF 136 #endif /* FLOATING_POINT */ #define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */ /* * Flags used during conversion. */ #define ALT 0x001 /* alternate form */ #define HEXPREFIX 0x002 /* add 0x or 0X prefix */ #define LADJUST 0x004 /* left adjustment */ #define LONGDBL 0x008 /* long double */ #define LONGINT 0x010 /* long integer */ #define LLONGINT 0x020 /* long long integer */ #define SHORTINT 0x040 /* short integer */ #define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ #define FPT 0x100 /* Floating point number */ #define GROUPING 0x200 /* use grouping ("'" flag) */ /* C99 additional size modifiers: */ #define SIZET 0x400 /* size_t */ #define PTRDIFFT 0x800 /* ptrdiff_t */ #define INTMAXT 0x1000 /* intmax_t */ #define CHARINT 0x2000 /* print char using int format */ /* * Non-MT-safe version */ int __vfprintf(FILE *fp, const char *fmt0, va_list ap) { char *fmt; /* format string */ int ch; /* character from fmt */ int n, n2; /* handy integer (short term usage) */ char *cp; /* handy char pointer (short term usage) */ struct __siov *iovp; /* for PRINT macro */ int flags; /* flags as above */ int ret; /* return value accumulator */ int width; /* width from format (%8d), or 0 */ int prec; /* precision from format (%.3d), or -1 */ char sign; /* sign prefix (' ', '+', '-', or \0) */ char thousands_sep; /* locale specific thousands separator */ const char *grouping; /* locale specific numeric grouping rules */ #ifdef FLOATING_POINT char *decimal_point; /* locale specific decimal point */ char softsign; /* temporary negative sign for floats */ double _double; /* double precision arguments %[eEfgG] */ int expt; /* integer value of exponent */ int expsize; /* character count for expstr */ int ndig; /* actual number of digits returned by cvt */ char expstr[7]; /* buffer for exponent string */ char *dtoaresult; /* buffer allocated by dtoa */ #endif u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ int base; /* base for [diouxX] conversion */ int dprec; /* a copy of prec if [diouxX], 0 otherwise */ int realsz; /* field size expanded by dprec, sign, etc */ int size; /* size of converted field or string */ int prsize; /* max size of printed field */ char *xdigs; /* digits for [xX] conversion */ #define NIOV 8 struct __suio uio; /* output information: summary */ struct __siov iov[NIOV];/* ... and individual io vectors */ char buf[BUF]; /* space for %c, %[diouxX], %[eEfFgG] */ char ox[2]; /* space for 0x hex-prefix */ union arg *argtable; /* args, built due to positional arg */ union arg statargtable [STATIC_ARG_TBL_SIZE]; int nextarg; /* 1-based argument index */ va_list orgap; /* original argument pointer */ /* * Choose PADSIZE to trade efficiency vs. size. If larger printf * fields occur frequently, increase PADSIZE and make the initialisers * below longer. */ #define PADSIZE 16 /* pad chunk size */ static char blanks[PADSIZE] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; static char zeroes[PADSIZE] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; /* * BEWARE, these `goto error' on error, and PAD uses `n'. */ #define PRINT(ptr, len) { \ iovp->iov_base = (ptr); \ iovp->iov_len = (len); \ uio.uio_resid += (len); \ iovp++; \ if (++uio.uio_iovcnt >= NIOV) { \ if (__sprint(fp, &uio)) \ goto error; \ iovp = iov; \ } \ } #define PAD(howmany, with) { \ if ((n = (howmany)) > 0) { \ while (n > PADSIZE) { \ PRINT(with, PADSIZE); \ n -= PADSIZE; \ } \ PRINT(with, n); \ } \ } #define FLUSH() { \ if (uio.uio_resid && __sprint(fp, &uio)) \ goto error; \ uio.uio_iovcnt = 0; \ iovp = iov; \ } /* * Get the argument indexed by nextarg. If the argument table is * built, use it to get the argument. If its not, get the next * argument (and arguments must be gotten sequentially). */ #define GETARG(type) \ ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ (nextarg++, va_arg(ap, type))) /* * To extend shorts properly, we need both signed and unsigned * argument extraction methods. */ #define SARG() \ (flags&LONGINT ? GETARG(long) : \ flags&SHORTINT ? (long)(short)GETARG(int) : \ flags&CHARINT ? (long)(signed char)GETARG(int) : \ (long)GETARG(int)) #define UARG() \ (flags&LONGINT ? GETARG(u_long) : \ flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \ flags&CHARINT ? (u_long)(u_char)GETARG(int) : \ (u_long)GETARG(u_int)) #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) #define SJARG() \ (flags&INTMAXT ? GETARG(intmax_t) : \ flags&SIZET ? (intmax_t)GETARG(size_t) : \ flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ (intmax_t)GETARG(long long)) #define UJARG() \ (flags&INTMAXT ? GETARG(uintmax_t) : \ flags&SIZET ? (uintmax_t)GETARG(size_t) : \ flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \ (uintmax_t)GETARG(unsigned long long)) /* * Get * arguments, including the form *nn$. Preserve the nextarg * that the argument can be gotten once the type is determined. */ #define GETASTER(val) \ n2 = 0; \ cp = fmt; \ while (is_digit(*cp)) { \ n2 = 10 * n2 + to_digit(*cp); \ cp++; \ } \ if (*cp == '$') { \ int hold = nextarg; \ if (argtable == NULL) { \ argtable = statargtable; \ __find_arguments (fmt0, orgap, &argtable); \ } \ nextarg = n2; \ val = GETARG (int); \ nextarg = hold; \ fmt = ++cp; \ } else { \ val = GETARG (int); \ } thousands_sep = '\0'; grouping = NULL; #ifdef FLOATING_POINT dtoaresult = NULL; decimal_point = localeconv()->decimal_point; #endif /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ if (cantwrite(fp)) return (EOF); /* optimise fprintf(stderr) (and other unbuffered Unix files) */ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && fp->_file >= 0) return (__sbprintf(fp, fmt0, ap)); fmt = (char *)fmt0; argtable = NULL; nextarg = 1; orgap = ap; uio.uio_iov = iovp = iov; uio.uio_resid = 0; uio.uio_iovcnt = 0; ret = 0; /* * Scan the format for conversions (`%' character). */ for (;;) { for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) /* void */; if ((n = fmt - cp) != 0) { if ((unsigned)ret + n > INT_MAX) { ret = EOF; goto error; } PRINT(cp, n); ret += n; } if (ch == '\0') goto done; fmt++; /* skip over '%' */ flags = 0; dprec = 0; width = 0; prec = -1; sign = '\0'; rflag: ch = *fmt++; reswitch: switch (ch) { case ' ': /*- * ``If the space and + flags both appear, the space * flag will be ignored.'' * -- ANSI X3J11 */ if (!sign) sign = ' '; goto rflag; case '#': flags |= ALT; goto rflag; case '*': /*- * ``A negative field width argument is taken as a * - flag followed by a positive field width.'' * -- ANSI X3J11 * They don't exclude field widths read from args. */ GETASTER (width); if (width >= 0) goto rflag; width = -width; /* FALLTHROUGH */ case '-': flags |= LADJUST; goto rflag; case '+': sign = '+'; goto rflag; case '\'': flags |= GROUPING; thousands_sep = *(localeconv()->thousands_sep); grouping = localeconv()->grouping; goto rflag; case '.': if ((ch = *fmt++) == '*') { GETASTER (n); prec = n < 0 ? -1 : n; goto rflag; } n = 0; while (is_digit(ch)) { n = 10 * n + to_digit(ch); ch = *fmt++; } prec = n < 0 ? -1 : n; goto reswitch; case '0': /*- * ``Note that 0 is taken as a flag, not as the * beginning of a field width.'' * -- ANSI X3J11 */ flags |= ZEROPAD; goto rflag; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; do { n = 10 * n + to_digit(ch); ch = *fmt++; } while (is_digit(ch)); if (ch == '$') { nextarg = n; if (argtable == NULL) { argtable = statargtable; __find_arguments (fmt0, orgap, &argtable); } goto rflag; } width = n; goto reswitch; #ifdef FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; #endif case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; flags |= CHARINT; } else flags |= SHORTINT; goto rflag; case 'j': flags |= INTMAXT; goto rflag; case 'l': if (flags & LONGINT) { flags &= ~LONGINT; flags |= LLONGINT; } else flags |= LONGINT; goto rflag; case 'q': flags |= LLONGINT; /* not necessarily */ goto rflag; case 't': flags |= PTRDIFFT; goto rflag; case 'z': flags |= SIZET; goto rflag; case 'c': *(cp = buf) = GETARG(int); size = 1; sign = '\0'; break; case 'D': flags |= LONGINT; /*FALLTHROUGH*/ case 'd': case 'i': if (flags & INTMAX_SIZE) { ujval = SJARG(); if ((intmax_t)ujval < 0) { ujval = -ujval; sign = '-'; } } else { ulval = SARG(); if ((long)ulval < 0) { ulval = -ulval; sign = '-'; } } base = 10; goto number; #ifdef FLOATING_POINT #ifdef HEXFLOAT case 'a': case 'A': #endif case 'e': case 'E': /*- * Grouping apply to %i, %d, %u, %f, %F, %g, %G * conversion specifiers only. For other conversions * behavior is undefined. * -- POSIX */ flags &= ~GROUPING; /*FALLTHROUGH*/ case 'f': case 'F': goto fp_begin; case 'g': case 'G': if (prec == 0) prec = 1; fp_begin: if (prec == -1) prec = DEFPREC; if (flags & LONGDBL) /* XXX this loses precision. */ _double = (double)GETARG(long double); else _double = GETARG(double); /* do this before tricky precision changes */ if (isinf(_double)) { if (_double < 0) sign = '-'; if (isupper(ch)) cp = "INF"; else cp = "inf"; size = 3; break; } if (isnan(_double)) { if (isupper(ch)) cp = "NAN"; else cp = "nan"; size = 3; break; } flags |= FPT; if (dtoaresult != NULL) { free(dtoaresult); dtoaresult = NULL; } cp = cvt(_double, prec, flags, &softsign, &expt, ch, &ndig, &dtoaresult); if (ch == 'g' || ch == 'G') { if (expt <= -4 || expt > prec) ch = (ch == 'g') ? 'e' : 'E'; else ch = 'g'; } if (ch == 'e' || ch == 'E') { --expt; expsize = exponent(expstr, expt, ch); size = expsize + ndig; if (ndig > 1 || flags & ALT) ++size; } else if (ch == 'f' || ch == 'F') { if (expt > 0) { size = expt; if (prec || flags & ALT) size += prec + 1; } else /* "0.X" */ size = prec + 2; } else if (expt >= ndig) { /* fixed g fmt */ size = expt; if (flags & ALT) ++size; } else size = ndig + (expt > 0 ? 1 : 2 - expt); if (softsign) sign = '-'; break; #endif /* FLOATING_POINT */ case 'n': /* * Assignment-like behavior is specified if the * value overflows or is otherwise unrepresentable. * C99 says to use `signed char' for %hhn conversions. */ if (flags & LLONGINT) *GETARG(long long *) = ret; else if (flags & SIZET) *GETARG(ssize_t *) = (ssize_t)ret; else if (flags & PTRDIFFT) *GETARG(ptrdiff_t *) = ret; else if (flags & INTMAXT) *GETARG(intmax_t *) = ret; else if (flags & LONGINT) *GETARG(long *) = ret; else if (flags & SHORTINT) *GETARG(short *) = ret; else if (flags & CHARINT) *GETARG(signed char *) = ret; else *GETARG(int *) = ret; continue; /* no output */ case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o': if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 8; goto nosign; case 'p': /*- * ``The argument shall be a pointer to void. The * value of the pointer is converted to a sequence * of printable characters, in an implementation- * defined manner.'' * -- ANSI X3J11 */ ujval = (uintmax_t)(uintptr_t)GETARG(void *); base = 16; xdigs = "0123456789abcdef"; flags = flags | INTMAXT | HEXPREFIX; ch = 'x'; goto nosign; case 's': if ((cp = GETARG(char *)) == NULL) cp = "(null)"; if (prec >= 0) { /* * can't use strlen; can only look for the * NUL in the first `prec' characters, and * strlen() will go further. */ char *p = memchr(cp, 0, (size_t)prec); if (p != NULL) { size = p - cp; if (size > prec) size = prec; } else size = prec; } else size = strlen(cp); sign = '\0'; break; case 'U': flags |= LONGINT; /*FALLTHROUGH*/ case 'u': if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 10; goto nosign; case 'X': xdigs = "0123456789ABCDEF"; goto hex; case 'x': xdigs = "0123456789abcdef"; hex: if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 16; /* leading 0x/X only if non-zero */ if (flags & ALT && (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0)) flags |= HEXPREFIX; flags &= ~GROUPING; /* unsigned conversions */ nosign: sign = '\0'; /*- * ``... diouXx conversions ... if a precision is * specified, the 0 flag will be ignored.'' * -- ANSI X3J11 */ number: if ((dprec = prec) >= 0) flags &= ~ZEROPAD; /*- * ``The result of converting a zero value with an * explicit precision of zero is no characters.'' * -- ANSI X3J11 */ cp = buf + BUF; if (flags & INTMAX_SIZE) { if (ujval != 0 || prec != 0) cp = __ujtoa(ujval, cp, base, flags & ALT, xdigs, flags & GROUPING, thousands_sep, grouping); } else { if (ulval != 0 || prec != 0) cp = __ultoa(ulval, cp, base, flags & ALT, xdigs, flags & GROUPING, thousands_sep, grouping); } size = buf + BUF - cp; break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; /* pretend it was %c with argument ch */ cp = buf; *cp = ch; size = 1; sign = '\0'; break; } /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be * padded out to `width' places. If flags&ZEROPAD, it should * first be prefixed by any sign or other prefix; otherwise, * it should be blank padded before the prefix is emitted. * After any left-hand padding and prefixing, emit zeroes * required by a decimal [diouxX] precision, then print the * string proper, then emit zeroes required by any leftover * floating precision; finally, if LADJUST, pad with blanks. * * Compute actual size, so we know how much to pad. * size excludes decimal prec; realsz includes it. */ realsz = dprec > size ? dprec : size; if (sign) realsz++; else if (flags & HEXPREFIX) realsz += 2; prsize = width > realsz ? width : realsz; if ((unsigned)ret + prsize > INT_MAX) { ret = EOF; goto error; } /* right-adjusting blank padding */ if ((flags & (LADJUST|ZEROPAD)) == 0) PAD(width - realsz, blanks); /* prefix */ if (sign) { PRINT(&sign, 1); } else if (flags & HEXPREFIX) { ox[0] = '0'; ox[1] = ch; PRINT(ox, 2); } /* right-adjusting zero padding */ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) PAD(width - realsz, zeroes); /* leading zeroes from decimal precision */ PAD(dprec - size, zeroes); /* the string or number proper */ #ifdef FLOATING_POINT if ((flags & FPT) == 0) { PRINT(cp, size); } else { /* glue together f_p fragments */ if (ch >= 'f') { /* 'f' or 'g' */ if (_double == 0) { /* kludge for __dtoa irregularity */ PRINT("0", 1); if (expt < ndig || (flags & ALT) != 0) { PRINT(decimal_point, 1); PAD(ndig - 1, zeroes); } } else if (expt <= 0) { PRINT("0", 1); PRINT(decimal_point, 1); PAD(-expt, zeroes); PRINT(cp, ndig); } else if (expt >= ndig) { PRINT(cp, ndig); PAD(expt - ndig, zeroes); if (flags & ALT) PRINT(decimal_point, 1); } else { PRINT(cp, expt); cp += expt; PRINT(decimal_point, 1); PRINT(cp, ndig-expt); } } else { /* 'e' or 'E' */ if (ndig > 1 || flags & ALT) { ox[0] = *cp++; ox[1] = *decimal_point; PRINT(ox, 2); if (_double) { PRINT(cp, ndig-1); } else /* 0.[0..] */ /* __dtoa irregularity */ PAD(ndig - 1, zeroes); } else /* XeYYY */ PRINT(cp, 1); PRINT(expstr, expsize); } } #else PRINT(cp, size); #endif /* left-adjusting padding (always blank) */ if (flags & LADJUST) PAD(width - realsz, blanks); /* finally, adjust ret */ ret += prsize; FLUSH(); /* copy out the I/O vectors */ } done: FLUSH(); error: #ifdef FLOATING_POINT if (dtoaresult != NULL) free(dtoaresult); #endif if (__sferror(fp)) ret = EOF; if ((argtable != NULL) && (argtable != statargtable)) free (argtable); return (ret); /* NOTREACHED */ } /* * Find all arguments when a positional parameter is encountered. Returns a * table, indexed by argument number, of pointers to each arguments. The * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries. * It will be replaces with a malloc-ed one if it overflows. */ static void __find_arguments (const char *fmt0, va_list ap, union arg **argtable) { char *fmt; /* format string */ int ch; /* character from fmt */ int n, n2; /* handy integer (short term usage) */ char *cp; /* handy char pointer (short term usage) */ int flags; /* flags as above */ int width; /* width from format (%8d), or 0 */ enum typeid *typetable; /* table of types */ enum typeid stattypetable [STATIC_ARG_TBL_SIZE]; int tablesize; /* current size of type table */ int tablemax; /* largest used index in table */ int nextarg; /* 1-based argument index */ /* * Add an argument type to the table, expanding if necessary. */ #define ADDTYPE(type) \ ((nextarg >= tablesize) ? \ __grow_type_table(nextarg, &typetable, &tablesize) : 0, \ (nextarg > tablemax) ? tablemax = nextarg : 0, \ typetable[nextarg++] = type) #define ADDSARG() \ ((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \ ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \ ((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT)))))) #define ADDUARG() \ ((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \ ((flags&SIZET) ? ADDTYPE(T_SIZET) : \ ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \ ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \ ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT)))))) /* * Add * arguments to the type array. */ #define ADDASTER() \ n2 = 0; \ cp = fmt; \ while (is_digit(*cp)) { \ n2 = 10 * n2 + to_digit(*cp); \ cp++; \ } \ if (*cp == '$') { \ int hold = nextarg; \ nextarg = n2; \ ADDTYPE (T_INT); \ nextarg = hold; \ fmt = ++cp; \ } else { \ ADDTYPE (T_INT); \ } fmt = (char *)fmt0; typetable = stattypetable; tablesize = STATIC_ARG_TBL_SIZE; tablemax = 0; nextarg = 1; memset (typetable, T_UNUSED, STATIC_ARG_TBL_SIZE); /* * Scan the format for conversions (`%' character). */ for (;;) { for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) /* void */; if (ch == '\0') goto done; fmt++; /* skip over '%' */ flags = 0; width = 0; rflag: ch = *fmt++; reswitch: switch (ch) { case ' ': case '#': goto rflag; case '*': ADDASTER (); goto rflag; case '-': case '+': case '\'': goto rflag; case '.': if ((ch = *fmt++) == '*') { ADDASTER (); goto rflag; } while (is_digit(ch)) { ch = *fmt++; } goto reswitch; case '0': goto rflag; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; do { n = 10 * n + to_digit(ch); ch = *fmt++; } while (is_digit(ch)); if (ch == '$') { nextarg = n; goto rflag; } width = n; goto reswitch; #ifdef FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; #endif case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; flags |= CHARINT; } else flags |= SHORTINT; goto rflag; case 'j': flags |= INTMAXT; goto rflag; case 'l': if (flags & LONGINT) { flags &= ~LONGINT; flags |= LLONGINT; } else flags |= LONGINT; goto rflag; case 'q': flags |= LLONGINT; /* not necessarily */ goto rflag; case 't': flags |= PTRDIFFT; goto rflag; case 'z': flags |= SIZET; goto rflag; case 'c': ADDTYPE(T_INT); break; case 'D': flags |= LONGINT; /*FALLTHROUGH*/ case 'd': case 'i': ADDSARG(); break; #ifdef FLOATING_POINT #ifdef HEXFLOAT case 'a': case 'A': #endif case 'e': case 'E': case 'f': case 'g': case 'G': if (flags & LONGDBL) ADDTYPE(T_LONG_DOUBLE); else ADDTYPE(T_DOUBLE); break; #endif /* FLOATING_POINT */ case 'n': if (flags & INTMAXT) ADDTYPE(TP_INTMAXT); else if (flags & PTRDIFFT) ADDTYPE(TP_PTRDIFFT); else if (flags & SIZET) ADDTYPE(TP_SIZET); else if (flags & LLONGINT) ADDTYPE(TP_LLONG); else if (flags & LONGINT) ADDTYPE(TP_LONG); else if (flags & SHORTINT) ADDTYPE(TP_SHORT); else if (flags & CHARINT) ADDTYPE(TP_SCHAR); else ADDTYPE(TP_INT); continue; /* no output */ case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o': ADDUARG(); break; case 'p': ADDTYPE(TP_VOID); break; case 's': ADDTYPE(TP_CHAR); break; case 'U': flags |= LONGINT; /*FALLTHROUGH*/ case 'u': case 'X': case 'x': ADDUARG(); break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; break; } } done: /* * Build the argument table. */ if (tablemax >= STATIC_ARG_TBL_SIZE) { *argtable = (union arg *) malloc (sizeof (union arg) * (tablemax + 1)); } (*argtable) [0].intarg = 0; for (n = 1; n <= tablemax; n++) { switch (typetable [n]) { case T_UNUSED: /* whoops! */ (*argtable) [n].intarg = va_arg (ap, int); break; case TP_SCHAR: (*argtable) [n].pschararg = va_arg (ap, signed char *); break; case TP_SHORT: (*argtable) [n].pshortarg = va_arg (ap, short *); break; case T_INT: (*argtable) [n].intarg = va_arg (ap, int); break; case T_U_INT: (*argtable) [n].uintarg = va_arg (ap, unsigned int); break; case TP_INT: (*argtable) [n].pintarg = va_arg (ap, int *); break; case T_LONG: (*argtable) [n].longarg = va_arg (ap, long); break; case T_U_LONG: (*argtable) [n].ulongarg = va_arg (ap, unsigned long); break; case TP_LONG: (*argtable) [n].plongarg = va_arg (ap, long *); break; case T_LLONG: (*argtable) [n].longlongarg = va_arg (ap, long long); break; case T_U_LLONG: (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long); break; case TP_LLONG: (*argtable) [n].plonglongarg = va_arg (ap, long long *); break; case T_PTRDIFFT: (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t); break; case TP_PTRDIFFT: (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *); break; case T_SIZET: (*argtable) [n].sizearg = va_arg (ap, size_t); break; case TP_SIZET: (*argtable) [n].psizearg = va_arg (ap, ssize_t *); break; case T_INTMAXT: (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); break; case T_UINTMAXT: (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t); break; case TP_INTMAXT: (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); break; #ifdef FLOATING_POINT case T_DOUBLE: (*argtable) [n].doublearg = va_arg (ap, double); break; case T_LONG_DOUBLE: (*argtable) [n].longdoublearg = va_arg (ap, long double); break; #endif case TP_CHAR: (*argtable) [n].pchararg = va_arg (ap, char *); break; case TP_VOID: (*argtable) [n].pvoidarg = va_arg (ap, void *); break; } } if ((typetable != NULL) && (typetable != stattypetable)) free (typetable); } /* * Increase the size of the type table. */ static void __grow_type_table (int nextarg, enum typeid **typetable, int *tablesize) { enum typeid *const oldtable = *typetable; const int oldsize = *tablesize; enum typeid *newtable; int newsize = oldsize * 2; if (newsize < nextarg + 1) newsize = nextarg + 1; if (oldsize == STATIC_ARG_TBL_SIZE) { if ((newtable = malloc(newsize)) == NULL) abort(); /* XXX handle better */ bcopy(oldtable, newtable, oldsize); } else { if ((newtable = reallocf(oldtable, newsize)) == NULL) abort(); /* XXX handle better */ } memset(&newtable[oldsize], T_UNUSED, newsize - oldsize); *typetable = newtable; *tablesize = newsize; } #ifdef FLOATING_POINT extern char *__dtoa(double, int, int, int *, int *, char **, char **); static char * cvt(double value, int ndigits, int flags, char *sign, int *decpt, int ch, int *length, char **dtoaresultp) { int mode, dsgn; char *digits, *bp, *rve; if (ch == 'f') mode = 3; /* ndigits after the decimal point */ else { /* * To obtain ndigits after the decimal point for the 'e' * and 'E' formats, round to ndigits + 1 significant * figures. */ if (ch == 'e' || ch == 'E') ndigits++; mode = 2; /* ndigits significant digits */ } digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve, dtoaresultp); *sign = dsgn != 0; if ((ch != 'g' && ch != 'G') || flags & ALT) { /* print trailing zeros */ bp = digits + ndigits; if (ch == 'f') { if (*digits == '0' && value) *decpt = -ndigits + 1; bp += *decpt; } if (value == 0) /* kludge for __dtoa irregularity */ rve = bp; while (rve < bp) *rve++ = '0'; } *length = rve - digits; return (digits); } static int exponent(char *p0, int exp, int fmtch) { char *p, *t; char expbuf[MAXEXP]; p = p0; *p++ = fmtch; if (exp < 0) { exp = -exp; *p++ = '-'; } else *p++ = '+'; t = expbuf + MAXEXP; if (exp > 9) { do { *--t = to_char(exp % 10); } while ((exp /= 10) > 9); *--t = to_char(exp); for (; t < expbuf + MAXEXP; *p++ = *t++); } else { *p++ = '0'; *p++ = to_char(exp); } return (p - p0); } #endif /* FLOATING_POINT */ Index: head/lib/libc/stdio/vprintf.c =================================================================== --- head/lib/libc/stdio/vprintf.c (revision 103011) +++ head/lib/libc/stdio/vprintf.c (revision 103012) @@ -1,50 +1,50 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include int -vprintf(const char *__restrict fmt, __va_list ap) +vprintf(const char * __restrict fmt, __va_list ap) { return (vfprintf(stdout, fmt, ap)); } Index: head/lib/libc/stdio/vsnprintf.c =================================================================== --- head/lib/libc/stdio/vsnprintf.c (revision 103011) +++ head/lib/libc/stdio/vsnprintf.c (revision 103012) @@ -1,71 +1,71 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vsnprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include "local.h" int -vsnprintf(char *__restrict str, size_t n, const char *__restrict fmt, +vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt, __va_list ap) { size_t on; int ret; FILE f; struct __sFILEX ext; on = n; if (n != 0) n--; if (n > INT_MAX) n = INT_MAX; f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n; f._extra = &ext; INITEXTRA(&f); ret = __vfprintf(&f, fmt, ap); if (on > 0) *f._p = '\0'; return (ret); } Index: head/lib/libc/stdio/vsprintf.c =================================================================== --- head/lib/libc/stdio/vsprintf.c (revision 103011) +++ head/lib/libc/stdio/vsprintf.c (revision 103012) @@ -1,63 +1,63 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vsprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include "local.h" int -vsprintf(char *__restrict str, const char *__restrict fmt, __va_list ap) +vsprintf(char * __restrict str, const char * __restrict fmt, __va_list ap) { int ret; FILE f; struct __sFILEX ext; f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = INT_MAX; f._extra = &ext; INITEXTRA(&f); ret = __vfprintf(&f, fmt, ap); *f._p = 0; return (ret); } Index: head/lib/libc/stdlib/strtod.3 =================================================================== --- head/lib/libc/stdlib/strtod.3 (revision 103011) +++ head/lib/libc/stdlib/strtod.3 (revision 103012) @@ -1,140 +1,140 @@ .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" the American National Standards Committee X3, on Information .\" Processing Systems. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)strtod.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" .Dd June 4, 1993 .Dt STRTOD 3 .Os .Sh NAME .Nm strtod .Nd convert .Tn ASCII string to double .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdlib.h .Ft double -.Fn strtod "const char *restrict nptr" "char **restrict endptr" +.Fn strtod "const char * restrict nptr" "char ** restrict endptr" .Sh DESCRIPTION The .Fn strtod function converts the initial portion of the string pointed to by .Fa nptr to .Em double representation. .Pp The expected form of the string is an optional plus (``+'') or minus sign (``\-'') followed by a sequence of digits optionally containing a decimal-point character, optionally followed by an exponent. An exponent consists of an ``E'' or ``e'', followed by an optional plus or minus sign, followed by a sequence of digits. .Pp Leading white-space characters in the string (as defined by the .Xr isspace 3 function) are skipped. The decimal point character is defined in the program's locale (category .Dv LC_NUMERIC ) . .Sh RETURN VALUES The .Fn strtod function returns the converted value, if any. .Pp If .Fa endptr is not .Dv NULL , a pointer to the character after the last character used in the conversion is stored in the location referenced by .Fa endptr . .Pp If no conversion is performed, zero is returned and the value of .Fa nptr is stored in the location referenced by .Fa endptr . .Pp If the correct value would cause overflow, plus or minus .Dv HUGE_VAL is returned (according to the sign of the value), and .Er ERANGE is stored in .Va errno . If the correct value would cause underflow, zero is returned and .Er ERANGE is stored in .Va errno . .Sh ERRORS .Bl -tag -width Er .It Bq Er ERANGE Overflow or underflow occurred. .El .Sh SEE ALSO .Xr atof 3 , .Xr atoi 3 , .Xr atol 3 , .Xr strtol 3 , .Xr strtoul 3 .Sh STANDARDS The .Fn strtod function conforms to .St -isoC . .Sh AUTHORS The author of this software is .An David M. Gay . .Pp Copyright (c) 1991 by AT&T. .Pp Permission to use, copy, modify, and distribute this software for any purpose without fee is hereby granted, provided that this entire notice is included in all copies of any software which is or includes a copy or modification of this software and in all copies of the supporting documentation for such software. .Pp THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. .Pp Contact your vendor for a free copy of the source code to .Fn strtod and accompanying functions. Index: head/lib/libc/stdlib/strtod.c =================================================================== --- head/lib/libc/stdlib/strtod.c (revision 103011) +++ head/lib/libc/stdlib/strtod.c (revision 103012) @@ -1,2426 +1,2426 @@ /*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtod.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); /**************************************************************** * * The author of this software is David M. Gay. * * Copyright (c) 1991 by AT&T. * * Permission to use, copy, modify, and distribute this software for any * purpose without fee is hereby granted, provided that this entire notice * is included in all copies of any software which is or includes a copy * or modification of this software and in all copies of the supporting * documentation for such software. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. * ***************************************************************/ /* Please send bug reports to David M. Gay AT&T Bell Laboratories, Room 2C-463 600 Mountain Avenue Murray Hill, NJ 07974-2070 U.S.A. dmg@research.att.com or research!dmg */ /* strtod for IEEE-, VAX-, and IBM-arithmetic machines. * * This strtod returns a nearest machine number to the input decimal * string (or sets errno to ERANGE). With IEEE arithmetic, ties are * broken by the IEEE round-even rule. Otherwise ties are broken by * biased rounding (add half and chop). * * Inspired loosely by William D. Clinger's paper "How to Read Floating * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. * * Modifications: * * 1. We only require IEEE, IBM, or VAX double-precision * arithmetic (not IEEE double-extended). * 2. We get by with floating-point arithmetic in a case that * Clinger missed -- when we're computing d * 10^n * for a small integer d and the integer n is not too * much larger than 22 (the maximum integer k for which * we can represent 10^k exactly), we may be able to * compute (d*10^k) * 10^(e-k) with just one roundoff. * 3. Rather than a bit-at-a-time adjustment of the binary * result in the hard case, we use floating-point * arithmetic to determine the adjustment to within * one bit; only in really hard cases do we need to * compute a second residual. * 4. Because of 3., we don't need a large table of powers of 10 * for ten-to-e (just some small tables, e.g. of 10^k * for 0 <= k <= 22). */ /* * #define Sudden_Underflow for IEEE-format machines without gradual * underflow (i.e., that flush to zero on underflow). * #define IBM for IBM mainframe-style floating-point arithmetic. * #define VAX for VAX-style floating-point arithmetic. * #define Unsigned_Shifts if >> does treats its left operand as unsigned. * #define No_leftright to omit left-right logic in fast floating-point * computation of dtoa. * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines * that use extended-precision instructions to compute rounded * products and quotients) with IBM. * #define ROUND_BIASED for IEEE-format with biased rounding. * #define Inaccurate_Divide for IEEE-format with correctly rounded * products but inaccurate quotients, e.g., for Intel i860. * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision * integer arithmetic. Whether this speeds things up or slows things * down depends on the machine and the number being converted. * #define KR_headers for old-style C function headers. * #define Bad_float_h if your system lacks a float.h or if it does not * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. */ #if defined(__i386__) || defined(__ia64__) || defined(__alpha__) || \ defined(__sparc64__) || defined(__powerpc__) #include #if BYTE_ORDER == BIG_ENDIAN #define IEEE_BIG_ENDIAN #else #define IEEE_LITTLE_ENDIAN #endif #endif /* defined(__i386__) ... */ typedef int32_t Long; typedef u_int32_t ULong; #ifdef DEBUG #include "stdio.h" #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} #endif #include #ifdef __cplusplus #include "malloc.h" #include "memory.h" #else #ifndef KR_headers #include "stdlib.h" #include "string.h" #else #include "malloc.h" #include "memory.h" #endif #endif #include "errno.h" #include #ifdef Bad_float_h #undef __STDC__ #ifdef IEEE_BIG_ENDIAN #define IEEE_ARITHMETIC #endif #ifdef IEEE_LITTLE_ENDIAN #define IEEE_ARITHMETIC #endif #ifdef IEEE_ARITHMETIC #define DBL_DIG 15 #define DBL_MAX_10_EXP 308 #define DBL_MAX_EXP 1024 #define FLT_RADIX 2 #define FLT_ROUNDS 1 #define DBL_MAX 1.7976931348623157e+308 #endif #ifdef IBM #define DBL_DIG 16 #define DBL_MAX_10_EXP 75 #define DBL_MAX_EXP 63 #define FLT_RADIX 16 #define FLT_ROUNDS 0 #define DBL_MAX 7.2370055773322621e+75 #endif #ifdef VAX #define DBL_DIG 16 #define DBL_MAX_10_EXP 38 #define DBL_MAX_EXP 127 #define FLT_RADIX 2 #define FLT_ROUNDS 1 #define DBL_MAX 1.7014118346046923e+38 #endif #ifndef LONG_MAX #define LONG_MAX 2147483647 #endif #else #include "float.h" #endif #ifndef __MATH_H__ #include "math.h" #endif #ifdef __cplusplus extern "C" { #endif #ifndef CONST #ifdef KR_headers #define CONST /* blank */ #else #define CONST const #endif #endif #ifdef Unsigned_Shifts #define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; #else #define Sign_Extend(a,b) /*no-op*/ #endif #if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \ defined(IBM) != 1 Only one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM should be defined. #endif union doubleasulongs { double x; ULong w[2]; }; #ifdef IEEE_LITTLE_ENDIAN #define word0(x) (((union doubleasulongs *)&x)->w)[1] #define word1(x) (((union doubleasulongs *)&x)->w)[0] #else #define word0(x) (((union doubleasulongs *)&x)->w)[0] #define word1(x) (((union doubleasulongs *)&x)->w)[1] #endif /* The following definition of Storeinc is appropriate for MIPS processors. * An alternative that might be better on some machines is * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) */ #if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ ((unsigned short *)a)[0] = (unsigned short)c, a++) #else #define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ ((unsigned short *)a)[1] = (unsigned short)c, a++) #endif /* #define P DBL_MANT_DIG */ /* Ten_pmax = floor(P*log(2)/log(5)) */ /* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ #if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) #define Exp_shift 20 #define Exp_shift1 20 #define Exp_msk1 0x100000 #define Exp_msk11 0x100000 #define Exp_mask 0x7ff00000 #define P 53 #define Bias 1023 #define IEEE_Arith #define Emin (-1022) #define Exp_1 0x3ff00000 #define Exp_11 0x3ff00000 #define Ebits 11 #define Frac_mask 0xfffff #define Frac_mask1 0xfffff #define Ten_pmax 22 #define Bletch 0x10 #define Bndry_mask 0xfffff #define Bndry_mask1 0xfffff #define LSB 1 #define Sign_bit 0x80000000 #define Log2P 1 #define Tiny0 0 #define Tiny1 1 #define Quick_max 14 #define Int_max 14 #define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */ #else #undef Sudden_Underflow #define Sudden_Underflow #ifdef IBM #define Exp_shift 24 #define Exp_shift1 24 #define Exp_msk1 0x1000000 #define Exp_msk11 0x1000000 #define Exp_mask 0x7f000000 #define P 14 #define Bias 65 #define Exp_1 0x41000000 #define Exp_11 0x41000000 #define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ #define Frac_mask 0xffffff #define Frac_mask1 0xffffff #define Bletch 4 #define Ten_pmax 22 #define Bndry_mask 0xefffff #define Bndry_mask1 0xffffff #define LSB 1 #define Sign_bit 0x80000000 #define Log2P 4 #define Tiny0 0x100000 #define Tiny1 0 #define Quick_max 14 #define Int_max 15 #else /* VAX */ #define Exp_shift 23 #define Exp_shift1 7 #define Exp_msk1 0x80 #define Exp_msk11 0x800000 #define Exp_mask 0x7f80 #define P 56 #define Bias 129 #define Exp_1 0x40800000 #define Exp_11 0x4080 #define Ebits 8 #define Frac_mask 0x7fffff #define Frac_mask1 0xffff007f #define Ten_pmax 24 #define Bletch 2 #define Bndry_mask 0xffff007f #define Bndry_mask1 0xffff007f #define LSB 0x10000 #define Sign_bit 0x8000 #define Log2P 1 #define Tiny0 0x80 #define Tiny1 0 #define Quick_max 15 #define Int_max 15 #endif #endif #ifndef IEEE_Arith #define ROUND_BIASED #endif #ifdef RND_PRODQUOT #define rounded_product(a,b) a = rnd_prod(a, b) #define rounded_quotient(a,b) a = rnd_quot(a, b) #ifdef KR_headers extern double rnd_prod(), rnd_quot(); #else extern double rnd_prod(double, double), rnd_quot(double, double); #endif #else #define rounded_product(a,b) a *= b #define rounded_quotient(a,b) a /= b #endif #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) #define Big1 0xffffffff #ifndef Just_16 /* When Pack_32 is not defined, we store 16 bits per 32-bit Long. * This makes some inner loops simpler and sometimes saves work * during multiplications, but it often seems to make things slightly * slower. Hence the default is now to store 32 bits per Long. */ #ifndef Pack_32 #define Pack_32 #endif #endif #define Kmax 15 #ifdef __cplusplus extern "C" double strtod(const char *s00, char **se); extern "C" char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp); #endif struct Bigint { struct Bigint *next; int k, maxwds, sign, wds; ULong x[1]; }; typedef struct Bigint Bigint; static Bigint * Balloc #ifdef KR_headers (k) int k; #else (int k) #endif { int x; Bigint *rv; x = 1 << k; rv = (Bigint *)malloc(sizeof(Bigint) + (x-1)*sizeof(Long)); rv->k = k; rv->maxwds = x; rv->sign = rv->wds = 0; return rv; } static void Bfree #ifdef KR_headers (v) Bigint *v; #else (Bigint *v) #endif { free(v); } #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ y->wds*sizeof(Long) + 2*sizeof(int)) static Bigint * multadd #ifdef KR_headers (b, m, a) Bigint *b; int m, a; #else (Bigint *b, int m, int a) /* multiply by m and add a */ #endif { int i, wds; ULong *x, y; #ifdef Pack_32 ULong xi, z; #endif Bigint *b1; wds = b->wds; x = b->x; i = 0; do { #ifdef Pack_32 xi = *x; y = (xi & 0xffff) * m + a; z = (xi >> 16) * m + (y >> 16); a = (int)(z >> 16); *x++ = (z << 16) + (y & 0xffff); #else y = *x * m + a; a = (int)(y >> 16); *x++ = y & 0xffff; #endif } while (++i < wds); if (a) { if (wds >= b->maxwds) { b1 = Balloc(b->k+1); Bcopy(b1, b); Bfree(b); b = b1; } b->x[wds++] = a; b->wds = wds; } return b; } static Bigint * s2b #ifdef KR_headers (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; #else (CONST char *s, int nd0, int nd, ULong y9) #endif { Bigint *b; int i, k; Long x, y; x = (nd + 8) / 9; for (k = 0, y = 1; x > y; y <<= 1, k++) ; #ifdef Pack_32 b = Balloc(k); b->x[0] = y9; b->wds = 1; #else b = Balloc(k+1); b->x[0] = y9 & 0xffff; b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; #endif i = 9; if (9 < nd0) { s += 9; do b = multadd(b, 10, *s++ - '0'); while (++i < nd0); s++; } else s += 10; for (; i < nd; i++) b = multadd(b, 10, *s++ - '0'); return b; } static int hi0bits #ifdef KR_headers (x) ULong x; #else (ULong x) #endif { int k = 0; if (!(x & 0xffff0000)) { k = 16; x <<= 16; } if (!(x & 0xff000000)) { k += 8; x <<= 8; } if (!(x & 0xf0000000)) { k += 4; x <<= 4; } if (!(x & 0xc0000000)) { k += 2; x <<= 2; } if (!(x & 0x80000000)) { k++; if (!(x & 0x40000000)) return 32; } return k; } static int lo0bits #ifdef KR_headers (y) ULong *y; #else (ULong *y) #endif { int k; ULong x = *y; if (x & 7) { if (x & 1) return 0; if (x & 2) { *y = x >> 1; return 1; } *y = x >> 2; return 2; } k = 0; if (!(x & 0xffff)) { k = 16; x >>= 16; } if (!(x & 0xff)) { k += 8; x >>= 8; } if (!(x & 0xf)) { k += 4; x >>= 4; } if (!(x & 0x3)) { k += 2; x >>= 2; } if (!(x & 1)) { k++; x >>= 1; if (!x & 1) return 32; } *y = x; return k; } static Bigint * i2b #ifdef KR_headers (i) int i; #else (int i) #endif { Bigint *b; b = Balloc(1); b->x[0] = i; b->wds = 1; return b; } static Bigint * mult #ifdef KR_headers (a, b) Bigint *a, *b; #else (Bigint *a, Bigint *b) #endif { Bigint *c; int k, wa, wb, wc; ULong carry, y, z; ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; #ifdef Pack_32 ULong z2; #endif if (a->wds < b->wds) { c = a; a = b; b = c; } k = a->k; wa = a->wds; wb = b->wds; wc = wa + wb; if (wc > a->maxwds) k++; c = Balloc(k); for (x = c->x, xa = x + wc; x < xa; x++) *x = 0; xa = a->x; xae = xa + wa; xb = b->x; xbe = xb + wb; xc0 = c->x; #ifdef Pack_32 for (; xb < xbe; xb++, xc0++) { if ( (y = *xb & 0xffff) ) { x = xa; xc = xc0; carry = 0; do { z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; carry = z >> 16; z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; carry = z2 >> 16; Storeinc(xc, z2, z); } while (x < xae); *xc = carry; } if ( (y = *xb >> 16) ) { x = xa; xc = xc0; carry = 0; z2 = *xc; do { z = (*x & 0xffff) * y + (*xc >> 16) + carry; carry = z >> 16; Storeinc(xc, z, z2); z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; carry = z2 >> 16; } while (x < xae); *xc = z2; } } #else for (; xb < xbe; xc0++) { if (y = *xb++) { x = xa; xc = xc0; carry = 0; do { z = *x++ * y + *xc + carry; carry = z >> 16; *xc++ = z & 0xffff; } while (x < xae); *xc = carry; } } #endif for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; c->wds = wc; return c; } static Bigint *p5s; static Bigint * pow5mult #ifdef KR_headers (b, k) Bigint *b; int k; #else (Bigint *b, int k) #endif { Bigint *b1, *p5, *p51; int i; static int p05[3] = { 5, 25, 125 }; if ( (i = k & 3) ) b = multadd(b, p05[i-1], 0); if (!(k >>= 2)) return b; if (!(p5 = p5s)) { /* first time */ p5 = p5s = i2b(625); p5->next = 0; } for (;;) { if (k & 1) { b1 = mult(b, p5); Bfree(b); b = b1; } if (!(k >>= 1)) break; if (!(p51 = p5->next)) { p51 = p5->next = mult(p5,p5); p51->next = 0; } p5 = p51; } return b; } static Bigint * lshift #ifdef KR_headers (b, k) Bigint *b; int k; #else (Bigint *b, int k) #endif { int i, k1, n, n1; Bigint *b1; ULong *x, *x1, *xe, z; #ifdef Pack_32 n = k >> 5; #else n = k >> 4; #endif k1 = b->k; n1 = n + b->wds + 1; for (i = b->maxwds; n1 > i; i <<= 1) k1++; b1 = Balloc(k1); x1 = b1->x; for (i = 0; i < n; i++) *x1++ = 0; x = b->x; xe = x + b->wds; #ifdef Pack_32 if (k &= 0x1f) { k1 = 32 - k; z = 0; do { *x1++ = *x << k | z; z = *x++ >> k1; } while (x < xe); if ( (*x1 = z) ) ++n1; } #else if (k &= 0xf) { k1 = 16 - k; z = 0; do { *x1++ = *x << k & 0xffff | z; z = *x++ >> k1; } while (x < xe); if (*x1 = z) ++n1; } #endif else do *x1++ = *x++; while (x < xe); b1->wds = n1 - 1; Bfree(b); return b1; } static int cmp #ifdef KR_headers (a, b) Bigint *a, *b; #else (Bigint *a, Bigint *b) #endif { ULong *xa, *xa0, *xb, *xb0; int i, j; i = a->wds; j = b->wds; #ifdef DEBUG if (i > 1 && !a->x[i-1]) Bug("cmp called with a->x[a->wds-1] == 0"); if (j > 1 && !b->x[j-1]) Bug("cmp called with b->x[b->wds-1] == 0"); #endif if (i -= j) return i; xa0 = a->x; xa = xa0 + j; xb0 = b->x; xb = xb0 + j; for (;;) { if (*--xa != *--xb) return *xa < *xb ? -1 : 1; if (xa <= xa0) break; } return 0; } static Bigint * diff #ifdef KR_headers (a, b) Bigint *a, *b; #else (Bigint *a, Bigint *b) #endif { Bigint *c; int i, wa, wb; Long borrow, y; /* We need signed shifts here. */ ULong *xa, *xae, *xb, *xbe, *xc; #ifdef Pack_32 Long z; #endif i = cmp(a,b); if (!i) { c = Balloc(0); c->wds = 1; c->x[0] = 0; return c; } if (i < 0) { c = a; a = b; b = c; i = 1; } else i = 0; c = Balloc(a->k); c->sign = i; wa = a->wds; xa = a->x; xae = xa + wa; wb = b->wds; xb = b->x; xbe = xb + wb; xc = c->x; borrow = 0; #ifdef Pack_32 do { y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; borrow = y >> 16; Sign_Extend(borrow, y); z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; borrow = z >> 16; Sign_Extend(borrow, z); Storeinc(xc, z, y); } while (xb < xbe); while (xa < xae) { y = (*xa & 0xffff) + borrow; borrow = y >> 16; Sign_Extend(borrow, y); z = (*xa++ >> 16) + borrow; borrow = z >> 16; Sign_Extend(borrow, z); Storeinc(xc, z, y); } #else do { y = *xa++ - *xb++ + borrow; borrow = y >> 16; Sign_Extend(borrow, y); *xc++ = y & 0xffff; } while (xb < xbe); while (xa < xae) { y = *xa++ + borrow; borrow = y >> 16; Sign_Extend(borrow, y); *xc++ = y & 0xffff; } #endif while (!*--xc) wa--; c->wds = wa; return c; } static double ulp #ifdef KR_headers (x) double x; #else (double x) #endif { Long L; double a; L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; #ifndef Sudden_Underflow if (L > 0) { #endif #ifdef IBM L |= Exp_msk1 >> 4; #endif word0(a) = L; word1(a) = 0; #ifndef Sudden_Underflow } else { L = -L >> Exp_shift; if (L < Exp_shift) { word0(a) = 0x80000 >> L; word1(a) = 0; } else { word0(a) = 0; L -= Exp_shift; word1(a) = L >= 31 ? 1 : 1 << (31 - L); } } #endif return a; } static double b2d #ifdef KR_headers (a, e) Bigint *a; int *e; #else (Bigint *a, int *e) #endif { ULong *xa, *xa0, w, y, z; int k; double d; #ifdef VAX ULong d0, d1; #else #define d0 word0(d) #define d1 word1(d) #endif xa0 = a->x; xa = xa0 + a->wds; y = *--xa; #ifdef DEBUG if (!y) Bug("zero y in b2d"); #endif k = hi0bits(y); *e = 32 - k; #ifdef Pack_32 if (k < Ebits) { d0 = Exp_1 | (y >> (Ebits - k)); w = xa > xa0 ? *--xa : 0; d1 = (y << ((32-Ebits) + k)) | (w >> (Ebits - k)); goto ret_d; } z = xa > xa0 ? *--xa : 0; if (k -= Ebits) { d0 = Exp_1 | (y << k) | (z >> (32 - k)); y = xa > xa0 ? *--xa : 0; d1 = (z << k) | (y >> (32 - k)); } else { d0 = Exp_1 | y; d1 = z; } #else if (k < Ebits + 16) { z = xa > xa0 ? *--xa : 0; d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; w = xa > xa0 ? *--xa : 0; y = xa > xa0 ? *--xa : 0; d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; goto ret_d; } z = xa > xa0 ? *--xa : 0; w = xa > xa0 ? *--xa : 0; k -= Ebits + 16; d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; y = xa > xa0 ? *--xa : 0; d1 = w << k + 16 | y << k; #endif ret_d: #ifdef VAX word0(d) = d0 >> 16 | d0 << 16; word1(d) = d1 >> 16 | d1 << 16; #else #undef d0 #undef d1 #endif return d; } static Bigint * d2b #ifdef KR_headers (d, e, bits) double d; int *e, *bits; #else (double d, int *e, int *bits) #endif { Bigint *b; int de, i, k; ULong *x, y, z; #ifdef VAX ULong d0, d1; d0 = word0(d) >> 16 | word0(d) << 16; d1 = word1(d) >> 16 | word1(d) << 16; #else #define d0 word0(d) #define d1 word1(d) #endif #ifdef Pack_32 b = Balloc(1); #else b = Balloc(2); #endif x = b->x; z = d0 & Frac_mask; d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ #ifdef Sudden_Underflow de = (int)(d0 >> Exp_shift); #ifndef IBM z |= Exp_msk11; #endif #else if ( (de = (int)(d0 >> Exp_shift)) ) z |= Exp_msk1; #endif #ifdef Pack_32 if ( (y = d1) ) { if ( (k = lo0bits(&y)) ) { x[0] = y | (z << (32 - k)); z >>= k; } else x[0] = y; i = b->wds = (x[1] = z) ? 2 : 1; } else { #ifdef DEBUG if (!z) Bug("Zero passed to d2b"); #endif k = lo0bits(&z); x[0] = z; i = b->wds = 1; k += 32; } #else if (y = d1) { if (k = lo0bits(&y)) if (k >= 16) { x[0] = y | z << 32 - k & 0xffff; x[1] = z >> k - 16 & 0xffff; x[2] = z >> k; i = 2; } else { x[0] = y & 0xffff; x[1] = y >> 16 | z << 16 - k & 0xffff; x[2] = z >> k & 0xffff; x[3] = z >> k+16; i = 3; } else { x[0] = y & 0xffff; x[1] = y >> 16; x[2] = z & 0xffff; x[3] = z >> 16; i = 3; } } else { #ifdef DEBUG if (!z) Bug("Zero passed to d2b"); #endif k = lo0bits(&z); if (k >= 16) { x[0] = z; i = 0; } else { x[0] = z & 0xffff; x[1] = z >> 16; i = 1; } k += 32; } while (!x[i]) --i; b->wds = i + 1; #endif #ifndef Sudden_Underflow if (de) { #endif #ifdef IBM *e = (de - Bias - (P-1) << 2) + k; *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); #else *e = de - Bias - (P-1) + k; *bits = P - k; #endif #ifndef Sudden_Underflow } else { *e = de - Bias - (P-1) + 1 + k; #ifdef Pack_32 *bits = 32*i - hi0bits(x[i-1]); #else *bits = (i+2)*16 - hi0bits(x[i]); #endif } #endif return b; } #undef d0 #undef d1 static double ratio #ifdef KR_headers (a, b) Bigint *a, *b; #else (Bigint *a, Bigint *b) #endif { double da, db; int k, ka, kb; da = b2d(a, &ka); db = b2d(b, &kb); #ifdef Pack_32 k = ka - kb + 32*(a->wds - b->wds); #else k = ka - kb + 16*(a->wds - b->wds); #endif #ifdef IBM if (k > 0) { word0(da) += (k >> 2)*Exp_msk1; if (k &= 3) da *= 1 << k; } else { k = -k; word0(db) += (k >> 2)*Exp_msk1; if (k &= 3) db *= 1 << k; } #else if (k > 0) word0(da) += k*Exp_msk1; else { k = -k; word0(db) += k*Exp_msk1; } #endif return da / db; } static double tens[] = { 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22 #ifdef VAX , 1e23, 1e24 #endif }; static double #ifdef IEEE_Arith bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; static double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; #define n_bigtens 5 #else #ifdef IBM bigtens[] = { 1e16, 1e32, 1e64 }; static double tinytens[] = { 1e-16, 1e-32, 1e-64 }; #define n_bigtens 3 #else bigtens[] = { 1e16, 1e32 }; static double tinytens[] = { 1e-16, 1e-32 }; #define n_bigtens 2 #endif #endif double strtod #ifdef KR_headers - (s00, se) CONST char *__restrict s00; char **__restrict se; + (s00, se) CONST char * __restrict s00; char ** __restrict se; #else - (CONST char *__restrict s00, char **__restrict se) + (CONST char * __restrict s00, char ** __restrict se) #endif { int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; CONST char *s, *s0, *s1; double aadj, aadj1, adj, rv, rv0; Long L; ULong y, z; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; char decimal_point = localeconv()->decimal_point[0]; sign = nz0 = nz = 0; rv = 0.; for (s = s00;;s++) switch(*s) { case '-': sign = 1; /* no break */ case '+': if (*++s) goto break2; /* no break */ case 0: s = s00; goto ret; default: if (isspace((unsigned char)*s)) continue; goto break2; } break2: if (*s == '0') { nz0 = 1; while (*++s == '0') ; if (!*s) goto ret; } s0 = s; y = z = 0; for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) if (nd < 9) y = 10*y + c - '0'; else if (nd < 16) z = 10*z + c - '0'; nd0 = nd; if ((char)c == decimal_point) { c = *++s; if (!nd) { for (; c == '0'; c = *++s) nz++; if (c > '0' && c <= '9') { s0 = s; nf += nz; nz = 0; goto have_dig; } goto dig_done; } for (; c >= '0' && c <= '9'; c = *++s) { have_dig: nz++; if (c - '0' > 0) { nf += nz; for (i = 1; i < nz; i++) if (nd++ < 9) y *= 10; else if (nd <= DBL_DIG + 1) z *= 10; if (nd++ < 9) y = 10*y + c - '0'; else if (nd <= DBL_DIG + 1) z = 10*z + c - '0'; nz = 0; } } } dig_done: e = 0; if (c == 'e' || c == 'E') { if (!nd && !nz && !nz0) { s = s00; goto ret; } s00 = s; esign = 0; switch(c = *++s) { case '-': esign = 1; case '+': c = *++s; } if (c >= '0' && c <= '9') { while (c == '0') c = *++s; if (c > '0' && c <= '9') { L = c - '0'; s1 = s; while ((c = *++s) >= '0' && c <= '9') L = 10*L + c - '0'; if (s - s1 > 8 || L > 19999) /* Avoid confusion from exponents * so large that e might overflow. */ e = 19999; /* safe for 16 bit ints */ else e = (int)L; if (esign) e = -e; } else e = 0; } else s = s00; } if (!nd) { if (!nz && !nz0) s = s00; goto ret; } e1 = e -= nf; /* Now we have nd0 digits, starting at s0, followed by a * decimal point, followed by nd-nd0 digits. The number we're * after is the integer represented by those digits times * 10**e */ if (!nd0) nd0 = nd; k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; rv = y; if (k > 9) rv = tens[k - 9] * rv + z; if (nd <= DBL_DIG #ifndef RND_PRODQUOT && FLT_ROUNDS == 1 #endif ) { if (!e) goto ret; if (e > 0) { if (e <= Ten_pmax) { #ifdef VAX goto vax_ovfl_check; #else /* rv = */ rounded_product(rv, tens[e]); goto ret; #endif } i = DBL_DIG - nd; if (e <= Ten_pmax + i) { /* A fancier test would sometimes let us do * this for larger i values. */ e -= i; rv *= tens[i]; #ifdef VAX /* VAX exponent range is so narrow we must * worry about overflow here... */ vax_ovfl_check: word0(rv) -= P*Exp_msk1; /* rv = */ rounded_product(rv, tens[e]); if ((word0(rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) goto ovfl; word0(rv) += P*Exp_msk1; #else /* rv = */ rounded_product(rv, tens[e]); #endif goto ret; } } #ifndef Inaccurate_Divide else if (e >= -Ten_pmax) { /* rv = */ rounded_quotient(rv, tens[-e]); goto ret; } #endif } e1 += nd - k; /* Get starting approximation = rv * 10**e1 */ if (e1 > 0) { if ( (i = e1 & 15) ) rv *= tens[i]; if ( (e1 &= ~15) ) { if (e1 > DBL_MAX_10_EXP) { ovfl: errno = ERANGE; rv = HUGE_VAL; goto ret; } if (e1 >>= 4) { for (j = 0; e1 > 1; j++, e1 >>= 1) if (e1 & 1) rv *= bigtens[j]; /* The last multiplication could overflow. */ word0(rv) -= P*Exp_msk1; rv *= bigtens[j]; if ((z = word0(rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-P)) goto ovfl; if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { /* set to largest number */ /* (Can't trust DBL_MAX) */ word0(rv) = Big0; word1(rv) = Big1; } else word0(rv) += P*Exp_msk1; } } } else if (e1 < 0) { e1 = -e1; if ( (i = e1 & 15) ) rv /= tens[i]; if ( (e1 &= ~15) ) { e1 >>= 4; for (j = 0; e1 > 1; j++, e1 >>= 1) if (e1 & 1) rv *= tinytens[j]; /* The last multiplication could underflow. */ rv0 = rv; rv *= tinytens[j]; if (!rv) { rv = 2.*rv0; rv *= tinytens[j]; if (!rv) { undfl: rv = 0.; errno = ERANGE; goto ret; } word0(rv) = Tiny0; word1(rv) = Tiny1; /* The refinement below will clean * this approximation up. */ } } } /* Now the hard part -- adjusting rv to the correct value.*/ /* Put digits into bd: true value = bd * 10^e */ bd0 = s2b(s0, nd0, nd, y); for (;;) { bd = Balloc(bd0->k); Bcopy(bd, bd0); bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ bs = i2b(1); if (e >= 0) { bb2 = bb5 = 0; bd2 = bd5 = e; } else { bb2 = bb5 = -e; bd2 = bd5 = 0; } if (bbe >= 0) bb2 += bbe; else bd2 -= bbe; bs2 = bb2; #ifdef Sudden_Underflow #ifdef IBM j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); #else j = P + 1 - bbbits; #endif #else i = bbe + bbbits - 1; /* logb(rv) */ if (i < Emin) /* denormal */ j = bbe + (P-Emin); else j = P + 1 - bbbits; #endif bb2 += j; bd2 += j; i = bb2 < bd2 ? bb2 : bd2; if (i > bs2) i = bs2; if (i > 0) { bb2 -= i; bd2 -= i; bs2 -= i; } if (bb5 > 0) { bs = pow5mult(bs, bb5); bb1 = mult(bs, bb); Bfree(bb); bb = bb1; } if (bb2 > 0) bb = lshift(bb, bb2); if (bd5 > 0) bd = pow5mult(bd, bd5); if (bd2 > 0) bd = lshift(bd, bd2); if (bs2 > 0) bs = lshift(bs, bs2); delta = diff(bb, bd); dsign = delta->sign; delta->sign = 0; i = cmp(delta, bs); if (i < 0) { /* Error is less than half an ulp -- check for * special case of mantissa a power of two. */ if (dsign || word1(rv) || word0(rv) & Bndry_mask) break; delta = lshift(delta,Log2P); if (cmp(delta, bs) > 0) goto drop_down; break; } if (i == 0) { /* exactly half-way between */ if (dsign) { if ((word0(rv) & Bndry_mask1) == Bndry_mask1 && word1(rv) == 0xffffffff) { /*boundary case -- increment exponent*/ word0(rv) = (word0(rv) & Exp_mask) + Exp_msk1 #ifdef IBM | Exp_msk1 >> 4 #endif ; word1(rv) = 0; break; } } else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { drop_down: /* boundary case -- decrement exponent */ #ifdef Sudden_Underflow L = word0(rv) & Exp_mask; #ifdef IBM if (L < Exp_msk1) #else if (L <= Exp_msk1) #endif goto undfl; L -= Exp_msk1; #else L = (word0(rv) & Exp_mask) - Exp_msk1; #endif word0(rv) = L | Bndry_mask1; word1(rv) = 0xffffffff; #ifdef IBM goto cont; #else break; #endif } #ifndef ROUND_BIASED if (!(word1(rv) & LSB)) break; #endif if (dsign) rv += ulp(rv); #ifndef ROUND_BIASED else { rv -= ulp(rv); #ifndef Sudden_Underflow if (!rv) goto undfl; #endif } #endif break; } if ((aadj = ratio(delta, bs)) <= 2.) { if (dsign) aadj = aadj1 = 1.; else if (word1(rv) || word0(rv) & Bndry_mask) { #ifndef Sudden_Underflow if (word1(rv) == Tiny1 && !word0(rv)) goto undfl; #endif aadj = 1.; aadj1 = -1.; } else { /* special case -- power of FLT_RADIX to be */ /* rounded down... */ if (aadj < 2./FLT_RADIX) aadj = 1./FLT_RADIX; else aadj *= 0.5; aadj1 = -aadj; } } else { aadj *= 0.5; aadj1 = dsign ? aadj : -aadj; #ifdef Check_FLT_ROUNDS switch(FLT_ROUNDS) { case 2: /* towards +infinity */ aadj1 -= 0.5; break; case 0: /* towards 0 */ case 3: /* towards -infinity */ aadj1 += 0.5; } #else if (FLT_ROUNDS == 0) aadj1 += 0.5; #endif } y = word0(rv) & Exp_mask; /* Check for overflow */ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { rv0 = rv; word0(rv) -= P*Exp_msk1; adj = aadj1 * ulp(rv); rv += adj; if ((word0(rv) & Exp_mask) >= Exp_msk1*(DBL_MAX_EXP+Bias-P)) { if (word0(rv0) == Big0 && word1(rv0) == Big1) goto ovfl; word0(rv) = Big0; word1(rv) = Big1; goto cont; } else word0(rv) += P*Exp_msk1; } else { #ifdef Sudden_Underflow if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { rv0 = rv; word0(rv) += P*Exp_msk1; adj = aadj1 * ulp(rv); rv += adj; #ifdef IBM if ((word0(rv) & Exp_mask) < P*Exp_msk1) #else if ((word0(rv) & Exp_mask) <= P*Exp_msk1) #endif { if (word0(rv0) == Tiny0 && word1(rv0) == Tiny1) goto undfl; word0(rv) = Tiny0; word1(rv) = Tiny1; goto cont; } else word0(rv) -= P*Exp_msk1; } else { adj = aadj1 * ulp(rv); rv += adj; } #else /* Compute adj so that the IEEE rounding rules will * correctly round rv + adj in some half-way cases. * If rv * ulp(rv) is denormalized (i.e., * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid * trouble from bits lost to denormalization; * example: 1.2e-307 . */ if (y <= (P-1)*Exp_msk1 && aadj >= 1.) { aadj1 = (double)(int)(aadj + 0.5); if (!dsign) aadj1 = -aadj1; } adj = aadj1 * ulp(rv); rv += adj; #endif } z = word0(rv) & Exp_mask; if (y == z) { /* Can we stop now? */ L = aadj; aadj -= L; /* The tolerances below are conservative. */ if (dsign || word1(rv) || word0(rv) & Bndry_mask) { if (aadj < .4999999 || aadj > .5000001) break; } else if (aadj < .4999999/FLT_RADIX) break; } cont: Bfree(bb); Bfree(bd); Bfree(bs); Bfree(delta); } Bfree(bb); Bfree(bd); Bfree(bs); Bfree(bd0); Bfree(delta); ret: if (se) *se = (char *)s; return sign ? -rv : rv; } static int quorem #ifdef KR_headers (b, S) Bigint *b, *S; #else (Bigint *b, Bigint *S) #endif { int n; Long borrow, y; ULong carry, q, ys; ULong *bx, *bxe, *sx, *sxe; #ifdef Pack_32 Long z; ULong si, zs; #endif n = S->wds; #ifdef DEBUG /*debug*/ if (b->wds > n) /*debug*/ Bug("oversize b in quorem"); #endif if (b->wds < n) return 0; sx = S->x; sxe = sx + --n; bx = b->x; bxe = bx + n; q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ #ifdef DEBUG /*debug*/ if (q > 9) /*debug*/ Bug("oversized quotient in quorem"); #endif if (q) { borrow = 0; carry = 0; do { #ifdef Pack_32 si = *sx++; ys = (si & 0xffff) * q + carry; zs = (si >> 16) * q + (ys >> 16); carry = zs >> 16; y = (*bx & 0xffff) - (ys & 0xffff) + borrow; borrow = y >> 16; Sign_Extend(borrow, y); z = (*bx >> 16) - (zs & 0xffff) + borrow; borrow = z >> 16; Sign_Extend(borrow, z); Storeinc(bx, z, y); #else ys = *sx++ * q + carry; carry = ys >> 16; y = *bx - (ys & 0xffff) + borrow; borrow = y >> 16; Sign_Extend(borrow, y); *bx++ = y & 0xffff; #endif } while (sx <= sxe); if (!*bxe) { bx = b->x; while (--bxe > bx && !*bxe) --n; b->wds = n; } } if (cmp(b, S) >= 0) { q++; borrow = 0; carry = 0; bx = b->x; sx = S->x; do { #ifdef Pack_32 si = *sx++; ys = (si & 0xffff) + carry; zs = (si >> 16) + (ys >> 16); carry = zs >> 16; y = (*bx & 0xffff) - (ys & 0xffff) + borrow; borrow = y >> 16; Sign_Extend(borrow, y); z = (*bx >> 16) - (zs & 0xffff) + borrow; borrow = z >> 16; Sign_Extend(borrow, z); Storeinc(bx, z, y); #else ys = *sx++ + carry; carry = ys >> 16; y = *bx - (ys & 0xffff) + borrow; borrow = y >> 16; Sign_Extend(borrow, y); *bx++ = y & 0xffff; #endif } while (sx <= sxe); bx = b->x; bxe = bx + n; if (!*bxe) { while (--bxe > bx && !*bxe) --n; b->wds = n; } } return q; } /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. * * Inspired by "How to Print Floating-Point Numbers Accurately" by * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. * * Modifications: * 1. Rather than iterating, we use a simple numeric overestimate * to determine k = floor(log10(d)). We scale relevant * quantities using O(log2(k)) rather than O(k) multiplications. * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't * try to generate digits strictly left to right. Instead, we * compute with fewer bits and propagate the carry if necessary * when rounding the final digit up. This is often faster. * 3. Under the assumption that input will be rounded nearest, * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. * That is, we allow equality in stopping tests when the * round-nearest rule will give the same floating-point value * as would satisfaction of the stopping test with strict * inequality. * 4. We remove common factors of powers of 2 from relevant * quantities. * 5. When converting floating-point integers less than 1e16, * we use floating-point arithmetic rather than resorting * to multiple-precision integers. * 6. When asked to produce fewer than 15 digits, we first try * to get by with floating-point arithmetic; we resort to * multiple-precision integer arithmetic only if we cannot * guarantee that the floating-point calculation has given * the correctly rounded result. For k requested digits and * "uniformly" distributed input, the probability is * something like 10^(k-15) that we must resort to the Long * calculation. */ char * __dtoa #ifdef KR_headers (d, mode, ndigits, decpt, sign, rve, resultp) double d; int mode, ndigits, *decpt, *sign; char **rve, **resultp; #else (double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp) #endif { /* Arguments ndigits, decpt, sign are similar to those of ecvt and fcvt; trailing zeros are suppressed from the returned string. If not null, *rve is set to point to the end of the return value. If d is +-Infinity or NaN, then *decpt is set to 9999. mode: 0 ==> shortest string that yields d when read in and rounded to nearest. 1 ==> like 0, but with Steele & White stopping rule; e.g. with IEEE P754 arithmetic , mode 0 gives 1e23 whereas mode 1 gives 9.999999999999999e22. 2 ==> max(1,ndigits) significant digits. This gives a return value similar to that of ecvt, except that trailing zeros are suppressed. 3 ==> through ndigits past the decimal point. This gives a return value similar to that from fcvt, except that trailing zeros are suppressed, and ndigits can be negative. 4-9 should give the same return values as 2-3, i.e., 4 <= mode <= 9 ==> same return as mode 2 + (mode & 1). These modes are mainly for debugging; often they run slower but sometimes faster than modes 2-3. 4,5,8,9 ==> left-to-right digit generation. 6-9 ==> don't try fast floating-point estimate (if applicable). Values of mode other than 0-9 are treated as mode 0. Sufficient space is allocated to the return value to hold the suppressed trailing zeros. */ int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, spec_case, try_quick; Long L; #ifndef Sudden_Underflow int denorm; ULong x; #endif Bigint *b, *b1, *delta, *mlo, *mhi, *S; double d2, ds, eps; char *s, *s0; if (word0(d) & Sign_bit) { /* set sign for everything, including 0's and NaNs */ *sign = 1; word0(d) &= ~Sign_bit; /* clear sign bit */ } else *sign = 0; #if defined(IEEE_Arith) + defined(VAX) #ifdef IEEE_Arith if ((word0(d) & Exp_mask) == Exp_mask) #else if (word0(d) == 0x8000) #endif { /* Infinity or NaN */ *decpt = 9999; s = #ifdef IEEE_Arith !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : #endif "NaN"; if (rve) *rve = #ifdef IEEE_Arith s[3] ? s + 8 : #endif s + 3; return s; } #endif #ifdef IBM d += 0; /* normalize */ #endif if (!d) { *decpt = 1; s = "0"; if (rve) *rve = s + 1; return s; } b = d2b(d, &be, &bbits); #ifdef Sudden_Underflow i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); #else if ( (i = (int)((word0(d) >> Exp_shift1) & (Exp_mask>>Exp_shift1))) ) { #endif d2 = d; word0(d2) &= Frac_mask1; word0(d2) |= Exp_11; #ifdef IBM if ( (j = 11 - hi0bits(word0(d2) & Frac_mask)) ) d2 /= 1 << j; #endif /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 * log10(x) = log(x) / log(10) * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) * * This suggests computing an approximation k to log10(d) by * * k = (i - Bias)*0.301029995663981 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); * * We want k to be too large rather than too small. * The error in the first-order Taylor series approximation * is in our favor, so we just round up the constant enough * to compensate for any error in the multiplication of * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, * adding 1e-13 to the constant term more than suffices. * Hence we adjust the constant term to 0.1760912590558. * (We could get a more accurate k by invoking log10, * but this is probably not worthwhile.) */ i -= Bias; #ifdef IBM i <<= 2; i += j; #endif #ifndef Sudden_Underflow denorm = 0; } else { /* d is denormalized */ i = bbits + be + (Bias + (P-1) - 1); x = i > 32 ? ((word0(d) << (64 - i)) | (word1(d) >> (i - 32))) : (word1(d) << (32 - i)); d2 = x; word0(d2) -= 31*Exp_msk1; /* adjust exponent */ i -= (Bias + (P-1) - 1) + 1; denorm = 1; } #endif ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; k = (int)ds; if (ds < 0. && ds != k) k--; /* want k = floor(ds) */ k_check = 1; if (k >= 0 && k <= Ten_pmax) { if (d < tens[k]) k--; k_check = 0; } j = bbits - i - 1; if (j >= 0) { b2 = 0; s2 = j; } else { b2 = -j; s2 = 0; } if (k >= 0) { b5 = 0; s5 = k; s2 += k; } else { b2 -= k; b5 = -k; s5 = 0; } if (mode < 0 || mode > 9) mode = 0; try_quick = 1; if (mode > 5) { mode -= 4; try_quick = 0; } leftright = 1; switch(mode) { case 0: case 1: ilim = ilim1 = -1; i = 18; ndigits = 0; break; case 2: leftright = 0; /* no break */ case 4: if (ndigits <= 0) ndigits = 1; ilim = ilim1 = i = ndigits; break; case 3: leftright = 0; /* no break */ case 5: i = ndigits + k + 1; ilim = i; ilim1 = i - 1; if (i <= 0) i = 1; } *resultp = (char *) malloc(i + 1); s = s0 = *resultp; if (ilim >= 0 && ilim <= Quick_max && try_quick) { /* Try to get by with floating-point arithmetic. */ i = 0; d2 = d; k0 = k; ilim0 = ilim; ieps = 2; /* conservative */ if (k > 0) { ds = tens[k&0xf]; j = k >> 4; if (j & Bletch) { /* prevent overflows */ j &= Bletch - 1; d /= bigtens[n_bigtens-1]; ieps++; } for (; j; j >>= 1, i++) if (j & 1) { ieps++; ds *= bigtens[i]; } d /= ds; } else if ( (j1 = -k) ) { d *= tens[j1 & 0xf]; for (j = j1 >> 4; j; j >>= 1, i++) if (j & 1) { ieps++; d *= bigtens[i]; } } if (k_check && d < 1. && ilim > 0) { if (ilim1 <= 0) goto fast_failed; ilim = ilim1; k--; d *= 10.; ieps++; } eps = ieps*d + 7.; word0(eps) -= (P-1)*Exp_msk1; if (ilim == 0) { S = mhi = 0; d -= 5.; if (d > eps) goto one_digit; if (d < -eps) goto no_digits; goto fast_failed; } #ifndef No_leftright if (leftright) { /* Use Steele & White method of only * generating digits needed. */ eps = 0.5/tens[ilim-1] - eps; for (i = 0;;) { L = d; d -= L; *s++ = '0' + (int)L; if (d < eps) goto ret1; if (1. - d < eps) goto bump_up; if (++i >= ilim) break; eps *= 10.; d *= 10.; } } else { #endif /* Generate ilim digits, then fix them up. */ eps *= tens[ilim-1]; for (i = 1;; i++, d *= 10.) { L = d; d -= L; *s++ = '0' + (int)L; if (i == ilim) { if (d > 0.5 + eps) goto bump_up; else if (d < 0.5 - eps) { while (*--s == '0'); s++; goto ret1; } break; } } #ifndef No_leftright } #endif fast_failed: s = s0; d = d2; k = k0; ilim = ilim0; } /* Do we have a "small" integer? */ if (be >= 0 && k <= Int_max) { /* Yes. */ ds = tens[k]; if (ndigits < 0 && ilim <= 0) { S = mhi = 0; if (ilim < 0 || d <= 5*ds) goto no_digits; goto one_digit; } for (i = 1;; i++) { L = d / ds; d -= L*ds; #ifdef Check_FLT_ROUNDS /* If FLT_ROUNDS == 2, L will usually be high by 1 */ if (d < 0) { L--; d += ds; } #endif *s++ = '0' + (int)L; if (i == ilim) { d += d; if (d > ds || (d == ds && L & 1)) { bump_up: while (*--s == '9') if (s == s0) { k++; *s = '0'; break; } ++*s++; } break; } if (!(d *= 10.)) break; } goto ret1; } m2 = b2; m5 = b5; mhi = mlo = 0; if (leftright) { if (mode < 2) { i = #ifndef Sudden_Underflow denorm ? be + (Bias + (P-1) - 1 + 1) : #endif #ifdef IBM 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); #else 1 + P - bbits; #endif } else { j = ilim - 1; if (m5 >= j) m5 -= j; else { s5 += j -= m5; b5 += j; m5 = 0; } if ((i = ilim) < 0) { m2 -= i; i = 0; } } b2 += i; s2 += i; mhi = i2b(1); } if (m2 > 0 && s2 > 0) { i = m2 < s2 ? m2 : s2; b2 -= i; m2 -= i; s2 -= i; } if (b5 > 0) { if (leftright) { if (m5 > 0) { mhi = pow5mult(mhi, m5); b1 = mult(mhi, b); Bfree(b); b = b1; } if ( (j = b5 - m5) ) b = pow5mult(b, j); } else b = pow5mult(b, b5); } S = i2b(1); if (s5 > 0) S = pow5mult(S, s5); /* Check for special case that d is a normalized power of 2. */ if (mode < 2) { if (!word1(d) && !(word0(d) & Bndry_mask) #ifndef Sudden_Underflow && word0(d) & Exp_mask #endif ) { /* The special case */ b2 += Log2P; s2 += Log2P; spec_case = 1; } else spec_case = 0; } /* Arrange for convenient computation of quotients: * shift left if necessary so divisor has 4 leading 0 bits. * * Perhaps we should just compute leading 28 bits of S once * and for all and pass them and a shift to quorem, so it * can do shifts and ors to compute the numerator for q. */ #ifdef Pack_32 if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) ) i = 32 - i; #else if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) ) i = 16 - i; #endif if (i > 4) { i -= 4; b2 += i; m2 += i; s2 += i; } else if (i < 4) { i += 28; b2 += i; m2 += i; s2 += i; } if (b2 > 0) b = lshift(b, b2); if (s2 > 0) S = lshift(S, s2); if (k_check) { if (cmp(b,S) < 0) { k--; b = multadd(b, 10, 0); /* we botched the k estimate */ if (leftright) mhi = multadd(mhi, 10, 0); ilim = ilim1; } } if (ilim <= 0 && mode > 2) { if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { /* no digits, fcvt style */ no_digits: k = -1 - ndigits; goto ret; } one_digit: *s++ = '1'; k++; goto ret; } if (leftright) { if (m2 > 0) mhi = lshift(mhi, m2); /* Compute mlo -- check for special case * that d is a normalized power of 2. */ mlo = mhi; if (spec_case) { mhi = Balloc(mhi->k); Bcopy(mhi, mlo); mhi = lshift(mhi, Log2P); } for (i = 1;;i++) { dig = quorem(b,S) + '0'; /* Do we yet have the shortest decimal string * that will round to d? */ j = cmp(b, mlo); delta = diff(S, mhi); j1 = delta->sign ? 1 : cmp(b, delta); Bfree(delta); #ifndef ROUND_BIASED if (j1 == 0 && !mode && !(word1(d) & 1)) { if (dig == '9') goto round_9_up; if (j > 0) dig++; *s++ = dig; goto ret; } #endif if (j < 0 || (j == 0 && !mode #ifndef ROUND_BIASED && !(word1(d) & 1) #endif )) { if (j1 > 0) { b = lshift(b, 1); j1 = cmp(b, S); if ((j1 > 0 || (j1 == 0 && dig & 1)) && dig++ == '9') goto round_9_up; } *s++ = dig; goto ret; } if (j1 > 0) { if (dig == '9') { /* possible if i == 1 */ round_9_up: *s++ = '9'; goto roundoff; } *s++ = dig + 1; goto ret; } *s++ = dig; if (i == ilim) break; b = multadd(b, 10, 0); if (mlo == mhi) mlo = mhi = multadd(mhi, 10, 0); else { mlo = multadd(mlo, 10, 0); mhi = multadd(mhi, 10, 0); } } } else for (i = 1;; i++) { *s++ = dig = quorem(b,S) + '0'; if (i >= ilim) break; b = multadd(b, 10, 0); } /* Round off last digit */ b = lshift(b, 1); j = cmp(b, S); if (j > 0 || (j == 0 && dig & 1)) { roundoff: while (*--s == '9') if (s == s0) { k++; *s++ = '1'; goto ret; } ++*s++; } else { while (*--s == '0'); s++; } ret: Bfree(S); if (mhi) { if (mlo && mlo != mhi) Bfree(mlo); Bfree(mhi); } ret1: Bfree(b); if (s == s0) { /* don't return empty string */ *s++ = '0'; k = 0; } *s = 0; *decpt = k + 1; if (rve) *rve = s; return s0; } #ifdef __cplusplus } #endif Index: head/lib/libc/stdlib/strtoimax.c =================================================================== --- head/lib/libc/stdlib/strtoimax.c (revision 103011) +++ head/lib/libc/stdlib/strtoimax.c (revision 103012) @@ -1,141 +1,141 @@ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "from @(#)strtol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include #include /* * Convert a string to a intmax_t integer. * * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ intmax_t -strtoimax(const char *__restrict nptr, char **__restrict endptr, int base) +strtoimax(const char * __restrict nptr, char ** __restrict endptr, int base) { const char *s; uintmax_t acc; char c; uintmax_t cutoff; int neg, any, cutlim; /* * Skip white space and pick up leading +/- sign if any. * If base is 0, allow 0x for hex and 0 for octal, else * assume decimal; if base is already 16, allow 0x. */ s = nptr; do { c = *s++; } while (isspace((unsigned char)c)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; /* * Compute the cutoff value between legal numbers and illegal * numbers. That is the largest legal value, divided by the * base. An input number that is greater than this value, if * followed by a legal input character, is too big. One that * is equal to this value may be valid or not; the limit * between valid and invalid numbers is then based on the last * digit. For instance, if the range for intmax_t is * [-9223372036854775808..9223372036854775807] and the input base * is 10, cutoff will be set to 922337203685477580 and cutlim to * either 7 (neg==0) or 8 (neg==1), meaning that if we have * accumulated a value > 922337203685477580, or equal but the * next digit is > 7 (or 8), the number is too big, and we will * return a range error. * * Set 'any' if any `digits' consumed; make it negative to indicate * overflow. */ cutoff = neg ? (uintmax_t)-(INTMAX_MIN + INTMAX_MAX) + INTMAX_MAX : INTMAX_MAX; cutlim = cutoff % base; cutoff /= base; for ( ; ; c = *s++) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = neg ? INTMAX_MIN : INTMAX_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } Index: head/lib/libc/stdlib/strtol.3 =================================================================== --- head/lib/libc/stdlib/strtol.3 (revision 103011) +++ head/lib/libc/stdlib/strtol.3 (revision 103012) @@ -1,222 +1,222 @@ .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Chris Torek and the American National Standards Committee X3, .\" on Information Processing Systems. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)strtol.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" .Dd November 28, 2001 .Dt STRTOL 3 .Os .Sh NAME .Nm strtol , strtoll , strtoimax , strtoq .Nd "convert a string value to a" .Vt long , "long long" , intmax_t or .Vt quad_t integer .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdlib.h .In limits.h .Ft long -.Fn strtol "const char *restrict nptr" "char **restrict endptr" "int base" +.Fn strtol "const char * restrict nptr" "char ** restrict endptr" "int base" .Ft long long -.Fn strtoll "const char *restrict nptr" "char **restrict endptr" "int base" +.Fn strtoll "const char * restrict nptr" "char ** restrict endptr" "int base" .In inttypes.h .Ft intmax_t -.Fn strtoimax "const char *restrict nptr" "char **restrict endptr" "int base" +.Fn strtoimax "const char * restrict nptr" "char ** restrict endptr" "int base" .In sys/types.h .In stdlib.h .In limits.h .Ft quad_t .Fn strtoq "const char *nptr" "char **endptr" "int base" .Sh DESCRIPTION The .Fn strtol function converts the string in .Fa nptr to a .Vt long value. The .Fn strtoll function converts the string in .Fa nptr to a .Vt "long long" value. The .Fn strtoimax function converts the string in .Fa nptr to an .Vt intmax_t value. The .Fn strtoq function converts the string in .Fa nptr to a .Vt quad_t value. The conversion is done according to the given .Fa base , which must be between 2 and 36 inclusive, or be the special value 0. .Pp The string may begin with an arbitrary amount of white space (as determined by .Xr isspace 3 ) followed by a single optional .Ql + or .Ql - sign. If .Fa base is zero or 16, the string may then include a .Dq Li 0x prefix, and the number will be read in base 16; otherwise, a zero .Fa base is taken as 10 (decimal) unless the next character is .Ql 0 , in which case it is taken as 8 (octal). .Pp The remainder of the string is converted to a .Vt long , "long long" , intmax_t or .Vt quad_t value in the obvious manner, stopping at the first character which is not a valid digit in the given base. (In bases above 10, the letter .Ql A in either upper or lower case represents 10, .Ql B represents 11, and so forth, with .Ql Z representing 35.) .Pp If .Fa endptr is not .Dv NULL , .Fn strtol stores the address of the first invalid character in .Fa *endptr . If there were no digits at all, however, .Fn strtol stores the original value of .Fa nptr in .Fa *endptr . (Thus, if .Fa *nptr is not .Ql \e0 but .Fa **endptr is .Ql \e0 on return, the entire string was valid.) .Sh RETURN VALUES The .Fn strtol , .Fn strtoll , .Fn strtoimax and .Fn strtoq functions return the result of the conversion, unless the value would underflow or overflow. If no conversion could be performed, 0 is returned and the global variable .Va errno is set to .Er EINVAL . If an overflow or underflow occurs, .Va errno is set to .Er ERANGE and the function return value is clamped according to the following table. .Bl -column -offset indent ".Fn strtoimax" ".Sy overflow" ".Sy underflow" .It Sy Function Ta Sy overflow Ta Sy underflow .It Fn strtol Ta Dv LONG_MIN Ta Dv LONG_MAX .It Fn strtoll Ta Dv LLONG_MIN Ta Dv LLONG_MAX .It Fn strtoimax Ta Dv INTMAX_MIN Ta Dv INTMAX_MAX .It Fn strtoq Ta Dv LLONG_MIN Ta Dv LLONG_MAX .El .Sh ERRORS .Bl -tag -width Er .It Bq Er EINVAL The value of .Fa base is not supported or no conversion could be performed. .It Bq Er ERANGE The given string was out of range; the value converted has been clamped. .El .Sh SEE ALSO .Xr atof 3 , .Xr atoi 3 , .Xr atol 3 , .Xr strtod 3 , .Xr strtoul 3 .Sh STANDARDS The .Fn strtol function conforms to .St -isoC . The .Fn strtoll and .Fn strtoimax functions conform to .St -isoC-99 . The .Bx .Fn strtoq function is deprecated. Index: head/lib/libc/stdlib/strtol.c =================================================================== --- head/lib/libc/stdlib/strtol.c (revision 103011) +++ head/lib/libc/stdlib/strtol.c (revision 103012) @@ -1,141 +1,141 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include #include /* * Convert a string to a long integer. * * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ long -strtol(const char *__restrict nptr, char **__restrict endptr, int base) +strtol(const char * __restrict nptr, char ** __restrict endptr, int base) { const char *s; unsigned long acc; char c; unsigned long cutoff; int neg, any, cutlim; /* * Skip white space and pick up leading +/- sign if any. * If base is 0, allow 0x for hex and 0 for octal, else * assume decimal; if base is already 16, allow 0x. */ s = nptr; do { c = *s++; } while (isspace((unsigned char)c)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; /* * Compute the cutoff value between legal numbers and illegal * numbers. That is the largest legal value, divided by the * base. An input number that is greater than this value, if * followed by a legal input character, is too big. One that * is equal to this value may be valid or not; the limit * between valid and invalid numbers is then based on the last * digit. For instance, if the range for longs is * [-2147483648..2147483647] and the input base is 10, * cutoff will be set to 214748364 and cutlim to either * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated * a value > 214748364, or equal but the next digit is > 7 (or 8), * the number is too big, and we will return a range error. * * Set 'any' if any `digits' consumed; make it negative to indicate * overflow. */ cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX; cutlim = cutoff % base; cutoff /= base; for ( ; ; c = *s++) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = neg ? LONG_MIN : LONG_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } Index: head/lib/libc/stdlib/strtoll.c =================================================================== --- head/lib/libc/stdlib/strtoll.c (revision 103011) +++ head/lib/libc/stdlib/strtoll.c (revision 103012) @@ -1,141 +1,141 @@ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include #include /* * Convert a string to a long long integer. * * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ long long -strtoll(const char *__restrict nptr, char **__restrict endptr, int base) +strtoll(const char * __restrict nptr, char ** __restrict endptr, int base) { const char *s; unsigned long long acc; char c; unsigned long long cutoff; int neg, any, cutlim; /* * Skip white space and pick up leading +/- sign if any. * If base is 0, allow 0x for hex and 0 for octal, else * assume decimal; if base is already 16, allow 0x. */ s = nptr; do { c = *s++; } while (isspace((unsigned char)c)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; /* * Compute the cutoff value between legal numbers and illegal * numbers. That is the largest legal value, divided by the * base. An input number that is greater than this value, if * followed by a legal input character, is too big. One that * is equal to this value may be valid or not; the limit * between valid and invalid numbers is then based on the last * digit. For instance, if the range for quads is * [-9223372036854775808..9223372036854775807] and the input base * is 10, cutoff will be set to 922337203685477580 and cutlim to * either 7 (neg==0) or 8 (neg==1), meaning that if we have * accumulated a value > 922337203685477580, or equal but the * next digit is > 7 (or 8), the number is too big, and we will * return a range error. * * Set 'any' if any `digits' consumed; make it negative to indicate * overflow. */ cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX : LLONG_MAX; cutlim = cutoff % base; cutoff /= base; for ( ; ; c = *s++) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = neg ? LLONG_MIN : LLONG_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } Index: head/lib/libc/stdlib/strtoul.3 =================================================================== --- head/lib/libc/stdlib/strtoul.3 (revision 103011) +++ head/lib/libc/stdlib/strtoul.3 (revision 103012) @@ -1,224 +1,224 @@ .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Chris Torek and the American National Standards Committee X3, .\" on Information Processing Systems. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)strtoul.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" .Dd November 28, 2001 .Dt STRTOUL 3 .Os .Sh NAME .Nm strtoul , strtoull , strtoumax , strtouq .Nd "convert a string to an" .Vt "unsigned long" , "unsigned long long" , uintmax_t , or .Vt u_quad_t integer .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In stdlib.h .In limits.h .Ft "unsigned long" -.Fn strtoul "const char *restrict nptr" "char **restrict endptr" "int base" +.Fn strtoul "const char * restrict nptr" "char ** restrict endptr" "int base" .Ft "unsigned long long" -.Fn strtoull "const char *restrict nptr" "char **restrict endptr" "int base" +.Fn strtoull "const char * restrict nptr" "char ** restrict endptr" "int base" .In inttypes.h .Ft uintmax_t -.Fn strtoumax "const char *restrict nptr" "char **restrict endptr" "int base" +.Fn strtoumax "const char * restrict nptr" "char ** restrict endptr" "int base" .In sys/types.h .In stdlib.h .In limits.h .Ft u_quad_t .Fn strtouq "const char *nptr" "char **endptr" "int base" .Sh DESCRIPTION The .Fn strtoul function converts the string in .Fa nptr to an .Vt "unsigned long" value. The .Fn strtoull function converts the string in .Fa nptr to an .Vt "unsigned long long" value. The .Fn strtoumax function converts the string in .Fa nptr to an .Vt uintmax_t value. The .Fn strtouq function converts the string in .Fa nptr to a .Vt u_quad_t value. The conversion is done according to the given .Fa base , which must be between 2 and 36 inclusive, or be the special value 0. .Pp The string may begin with an arbitrary amount of white space (as determined by .Xr isspace 3 ) followed by a single optional .Ql + or .Ql - sign. If .Fa base is zero or 16, the string may then include a .Dq Li 0x prefix, and the number will be read in base 16; otherwise, a zero .Fa base is taken as 10 (decimal) unless the next character is .Ql 0 , in which case it is taken as 8 (octal). .Pp The remainder of the string is converted to an .Vt "unsigned long" value in the obvious manner, stopping at the end of the string or at the first character that does not produce a valid digit in the given base. (In bases above 10, the letter .Ql A in either upper or lower case represents 10, .Ql B represents 11, and so forth, with .Ql Z representing 35.) .Pp If .Fa endptr is not .Dv NULL , .Fn strtoul stores the address of the first invalid character in .Fa *endptr . If there were no digits at all, however, .Fn strtoul stores the original value of .Fa nptr in .Fa *endptr . (Thus, if .Fa *nptr is not .Ql \e0 but .Fa **endptr is .Ql \e0 on return, the entire string was valid.) .Sh RETURN VALUES The .Fn strtoul , .Fn strtoull , .Fn strtoumax and .Fn strtouq functions return either the result of the conversion or, if there was a leading minus sign, the negation of the result of the conversion, unless the original (non-negated) value would overflow; in the latter case, .Fn strtoul returns .Dv ULONG_MAX , .Fn strtoull returns .Dv ULLONG_MAX , .Fn strtoumax returns .Dv UINTMAX_MAX , and .Fn strtouq returns .Dv ULLONG_MAX . In all cases, .Va errno is set to .Er ERANGE . If no conversion could be performed, 0 is returned and the global variable .Va errno is set to .Er EINVAL . .Sh ERRORS .Bl -tag -width Er .It Bq Er EINVAL The value of .Fa base is not supported or no conversion could be performed. .It Bq Er ERANGE The given string was out of range; the value converted has been clamped. .El .Sh SEE ALSO .Xr strtol 3 .Sh STANDARDS The .Fn strtoul function conforms to .St -isoC . The .Fn strtoull and .Fn strtoumax functions conform to .St -isoC-99 . The .Bx .Fn strtouq function is deprecated. Index: head/lib/libc/stdlib/strtoul.c =================================================================== --- head/lib/libc/stdlib/strtoul.c (revision 103011) +++ head/lib/libc/stdlib/strtoul.c (revision 103012) @@ -1,119 +1,119 @@ /* * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include #include /* * Convert a string to an unsigned long integer. * * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ unsigned long -strtoul(const char *__restrict nptr, char **__restrict endptr, int base) +strtoul(const char * __restrict nptr, char ** __restrict endptr, int base) { const char *s; unsigned long acc; char c; unsigned long cutoff; int neg, any, cutlim; /* * See strtol for comments as to the logic used. */ s = nptr; do { c = *s++; } while (isspace((unsigned char)c)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; cutoff = ULONG_MAX / base; cutlim = ULONG_MAX % base; for ( ; ; c = *s++) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = ULONG_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } Index: head/lib/libc/stdlib/strtoull.c =================================================================== --- head/lib/libc/stdlib/strtoull.c (revision 103011) +++ head/lib/libc/stdlib/strtoull.c (revision 103012) @@ -1,119 +1,119 @@ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include #include /* * Convert a string to an unsigned long long integer. * * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ unsigned long long -strtoull(const char *__restrict nptr, char **__restrict endptr, int base) +strtoull(const char * __restrict nptr, char ** __restrict endptr, int base) { const char *s; unsigned long long acc; char c; unsigned long long cutoff; int neg, any, cutlim; /* * See strtoq for comments as to the logic used. */ s = nptr; do { c = *s++; } while (isspace((unsigned char)c)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; cutoff = ULLONG_MAX / base; cutlim = ULLONG_MAX % base; for ( ; ; c = *s++) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = ULLONG_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } Index: head/lib/libc/stdlib/strtoumax.c =================================================================== --- head/lib/libc/stdlib/strtoumax.c (revision 103011) +++ head/lib/libc/stdlib/strtoumax.c (revision 103012) @@ -1,119 +1,119 @@ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "from @(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include #include /* * Convert a string to a uintmax_t integer. * * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ uintmax_t -strtoumax(const char *__restrict nptr, char **__restrict endptr, int base) +strtoumax(const char * __restrict nptr, char ** __restrict endptr, int base) { const char *s; uintmax_t acc; char c; uintmax_t cutoff; int neg, any, cutlim; /* * See strtoimax for comments as to the logic used. */ s = nptr; do { c = *s++; } while (isspace((unsigned char)c)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; cutoff = UINTMAX_MAX / base; cutlim = UINTMAX_MAX % base; for ( ; ; c = *s++) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = UINTMAX_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } Index: head/lib/libc/stdlib/tdelete.c =================================================================== --- head/lib/libc/stdlib/tdelete.c (revision 103011) +++ head/lib/libc/stdlib/tdelete.c (revision 103012) @@ -1,72 +1,72 @@ /* $NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $ */ /* * Tree search generalized from Knuth (6.2.2) Algorithm T just like * the AT&T man page says. * * The node_t structure is for internal use only, lint doesn't grok it. * * Written by reading the System V Interface Definition, not the code. * * Totally public domain. */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) __RCSID("$NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $"); #endif /* LIBC_SCCS and not lint */ #endif __FBSDID("$FreeBSD$"); #include #define _SEARCH_PRIVATE #include #include /* * delete node with given key * * vkey: key to be deleted * vrootp: address of the root of the tree * compar: function to carry out node comparisons */ void * -tdelete(const void *__restrict vkey, void **__restrict vrootp, +tdelete(const void * __restrict vkey, void ** __restrict vrootp, int (*compar)(const void *, const void *)) { node_t **rootp = (node_t **)vrootp; node_t *p, *q, *r; int cmp; if (rootp == NULL || (p = *rootp) == NULL) return NULL; while ((cmp = (*compar)(vkey, (*rootp)->key)) != 0) { p = *rootp; rootp = (cmp < 0) ? &(*rootp)->llink : /* follow llink branch */ &(*rootp)->rlink; /* follow rlink branch */ if (*rootp == NULL) return NULL; /* key not found */ } r = (*rootp)->rlink; /* D1: */ if ((q = (*rootp)->llink) == NULL) /* Left NULL? */ q = r; else if (r != NULL) { /* Right link is NULL? */ if (r->llink == NULL) { /* D2: Find successor */ r->llink = q; q = r; } else { /* D3: Find NULL link */ for (q = r->llink; q->llink != NULL; q = r->llink) r = q; r->llink = q->rlink; q->llink = (*rootp)->llink; q->rlink = (*rootp)->rlink; } } free(*rootp); /* D4: Free node */ *rootp = q; /* link parent to new node */ return p; } Index: head/lib/libc/stdlib/tsearch.3 =================================================================== --- head/lib/libc/stdlib/tsearch.3 (revision 103011) +++ head/lib/libc/stdlib/tsearch.3 (revision 103012) @@ -1,118 +1,118 @@ .\" $NetBSD$ .\" Copyright (c) 1997 Todd C. Miller .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. The name of the author may not be used to endorse or promote products .\" derived from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, .\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL .\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, .\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, .\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; .\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, .\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" OpenBSD: tsearch.3,v 1.2 1998/06/21 22:13:49 millert Exp .\" $FreeBSD$ .\" .Dd June 15, 1997 .Dt TSEARCH 3 .Os .Sh NAME .Nm tsearch , tfind , tdelete , twalk .Nd manipulate binary search trees .Sh SYNOPSIS .In search.h .Ft void * -.Fn tdelete "const void *restrict key" "void **restrict rootp" "int (*compar) (const void *, const void *)" +.Fn tdelete "const void * restrict key" "void ** restrict rootp" "int (*compar) (const void *, const void *)" .Ft void * .Fn tfind "const void *key" "void **rootp" "int (*compar) (const void *, const void *)" .Ft void * .Fn tsearch "const void *key" "void **rootp" "int (*compar) (const void *, const void *)" .Ft void .Fn twalk "const void *root" "void (*compar) (const void *, VISIT, int)" .Sh DESCRIPTION The .Fn tdelete , .Fn tfind , .Fn tsearch , and .Fn twalk functions manage binary search trees based on algorithms T and D from Knuth (6.2.2). The comparison function passed in by the user has the same style of return values as .Xr strcmp 3 . .Pp .Fn Tfind searches for the datum matched by the argument .Fa key in the binary tree rooted at .Fa rootp , returning a pointer to the datum if it is found and NULL if it is not. .Pp .Fn Tsearch is identical to .Fn tfind except that if no match is found, .Fa key is inserted into the tree and a pointer to it is returned. If .Fa rootp points to a NULL value a new binary search tree is created. .Pp .Fn Tdelete deletes a node from the specified binary search tree and returns a pointer to the parent of the node to be deleted. It takes the same arguments as .Fn tfind and .Fn tsearch . If the node to be deleted is the root of the binary search tree, .Fa rootp will be adjusted. .Pp .Fn Twalk walks the binary search tree rooted in .Fa root and calls the function .Fa action on each node. .Fa Action is called with three arguments: a pointer to the current node, a value from the enum .Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;" specifying the traversal type, and a node level (where level zero is the root of the tree). .Sh SEE ALSO .Xr bsearch 3 , .Xr hsearch 3 , .Xr lsearch 3 .Sh RETURN VALUES The .Fn tsearch function returns NULL if allocation of a new node fails (usually due to a lack of free memory). .Pp .Fn Tfind , .Fn tsearch , and .Fn tdelete return NULL if .Fa rootp is NULL or the datum cannot be found. .Pp The .Fn twalk function returns no value. Index: head/lib/libc/stdtime/strftime.3 =================================================================== --- head/lib/libc/stdtime/strftime.3 (revision 103011) +++ head/lib/libc/stdtime/strftime.3 (revision 103012) @@ -1,263 +1,263 @@ .\" Copyright (c) 1989, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" the American National Standards Committee X3, on Information .\" Processing Systems. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)strftime.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" .Dd October 4, 1997 .Dt STRFTIME 3 .Os .Sh NAME .Nm strftime .Nd format date and time .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In time.h .Ft size_t .Fo strftime -.Fa "char *restrict buf" +.Fa "char * restrict buf" .Fa "size_t maxsize" -.Fa "const char *restrict format" -.Fa "const struct tm *restrict timeptr" +.Fa "const char * restrict format" +.Fa "const struct tm * restrict timeptr" .Fc .Sh DESCRIPTION The .Fn strftime function formats the information from .Fa timeptr into the buffer .Fa buf according to the string pointed to by .Fa format . .Pp The .Fa format string consists of zero or more conversion specifications and ordinary characters. All ordinary characters are copied directly into the buffer. A conversion specification consists of a percent sign .Dq Ql % and one other character. .Pp No more than .Fa maxsize characters will be placed into the array. If the total number of resulting characters, including the terminating NUL character, is not more than .Fa maxsize , .Fn strftime returns the number of characters in the array, not counting the terminating NUL. Otherwise, zero is returned and the buffer contents are indeterminate. .Pp The conversion specifications are copied to the buffer after expansion as follows:- .Bl -tag -width "xxxx" .It Cm \&%A is replaced by national representation of the full weekday name. .It Cm %a is replaced by national representation of the abbreviated weekday name. .It Cm \&%B is replaced by national representation of the full month name. .It Cm %b is replaced by national representation of the abbreviated month name. .It Cm \&%C is replaced by (year / 100) as decimal number; single digits are preceded by a zero. .It Cm %c is replaced by national representation of time and date. .It Cm \&%D is equivalent to .Dq Li %m/%d/%y . .It Cm %d is replaced by the day of the month as a decimal number (01-31). .It Cm \&%E* Cm \&%O* POSIX locale extensions. The sequences %Ec %EC %Ex %EX %Ey %EY %Od %Oe %OH %OI %Om %OM %OS %Ou %OU %OV %Ow %OW %Oy are supposed to provide alternate representations. .Pp Additionly %OB implemented to represent alternative months names (used standalone, without day mentioned). .It Cm %e is replaced by the day of month as a decimal number (1-31); single digits are preceded by a blank. .It Cm \&%F is equivalent to .Dq Li %Y-%m-%d . .It Cm \&%G is replaced by a year as a decimal number with century. This year is the one that contains the greater part of the week (Monday as the first day of the week). .It Cm %g is replaced by the same year as in .Dq Li %G , but as a decimal number without century (00-99). .It Cm \&%H is replaced by the hour (24-hour clock) as a decimal number (00-23). .It Cm %h the same as %b. .It Cm \&%I is replaced by the hour (12-hour clock) as a decimal number (01-12). .It Cm %j is replaced by the day of the year as a decimal number (001-366). .It Cm %k is replaced by the hour (24-hour clock) as a decimal number (0-23); single digits are preceded by a blank. .It Cm %l is replaced by the hour (12-hour clock) as a decimal number (1-12); single digits are preceded by a blank. .It Cm \&%M is replaced by the minute as a decimal number (00-59). .It Cm %m is replaced by the month as a decimal number (01-12). .It Cm %n is replaced by a newline. .It Cm \&%O* the same as %E*. .It Cm %p is replaced by national representation of either "ante meridiem" or "post meridiem" as appropriate. .It Cm \&%R is equivalent to .Dq Li %H:%M . .It Cm %r is equivalent to .Dq Li %I:%M:%S %p . .It Cm \&%S is replaced by the second as a decimal number (00-60). .It Cm %s is replaced by the number of seconds since the Epoch, UTC (see .Xr mktime 3 ) . .It Cm \&%T is equivalent to .Dq Li %H:%M:%S . .It Cm %t is replaced by a tab. .It Cm \&%U is replaced by the week number of the year (Sunday as the first day of the week) as a decimal number (00-53). .It Cm %u is replaced by the weekday (Monday as the first day of the week) as a decimal number (1-7). .It Cm \&%V is replaced by the week number of the year (Monday as the first day of the week) as a decimal number (01-53). If the week containing January 1 has four or more days in the new year, then it is week 1; otherwise it is the last week of the previous year, and the next week is week 1. .It Cm %v is equivalent to .Dq Li %e-%b-%Y . .It Cm \&%W is replaced by the week number of the year (Monday as the first day of the week) as a decimal number (00-53). .It Cm %w is replaced by the weekday (Sunday as the first day of the week) as a decimal number (0-6). .It Cm \&%X is replaced by national representation of the time. .It Cm %x is replaced by national representation of the date. .It Cm \&%Y is replaced by the year with century as a decimal number. .It Cm %y is replaced by the year without century as a decimal number (00-99). .It Cm \&%Z is replaced by the time zone name. .It Cm \&%z is replaced by the time zone offset from UTC; a leading plus sign stands for east of UTC, a minus sign for west of UTC, hours and minutes follow with two digits each and no delimiter between them (common form for RFC 822 date headers). .It Cm %+ is replaced by national representation of the date and time (the format is similar to that produced by .Xr date 1 ) . .It Cm %% is replaced by .Ql % . .El .Sh SEE ALSO .Xr date 1 , .Xr printf 1 , .Xr ctime 3 , .Xr printf 3 , .Xr strptime 3 .Sh STANDARDS The .Fn strftime function conforms to .St -isoC with a lot of extensions including .Ql %C , .Ql \&%D , .Ql %E* , .Ql %e , .Ql %G , .Ql %g , .Ql %h , .Ql %k , .Ql %l , .Ql %n , .Ql %O* , .Ql \&%R , .Ql %r , .Ql %s , .Ql \&%T , .Ql %t , .Ql %u , .Ql \&%V , .Ql %z , .Ql %+ . .Pp The peculiar week number and year in the replacements of .Ql %G , .Ql %g and .Ql \&%V are defined in ISO 8601: 1988. .Sh BUGS There is no conversion specification for the phase of the moon. Index: head/lib/libc/stdtime/strftime.c =================================================================== --- head/lib/libc/stdtime/strftime.c (revision 103011) +++ head/lib/libc/stdtime/strftime.c (revision 103012) @@ -1,447 +1,447 @@ /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint #ifndef NOID static const char elsieid[] = "@(#)strftime.c 7.38"; /* ** Based on the UCB version with the ID appearing below. ** This is ANSIish only when "multibyte character == plain character". */ #endif /* !defined NOID */ #endif /* !defined lint */ #include "namespace.h" #include "private.h" #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "tzfile.h" #include #include #include "un-namespace.h" #include "timelocal.h" static char * _add(const char *, char *, const char *); static char * _conv(int, const char *, char *, const char *); static char * _fmt(const char *, const struct tm *, char *, const char *); -size_t strftime(char *__restrict, size_t, const char *__restrict, - const struct tm *__restrict); +size_t strftime(char * __restrict, size_t, const char * __restrict, + const struct tm * __restrict); extern char * tzname[]; size_t -strftime(char *__restrict s, size_t maxsize, const char *__restrict format, - const struct tm *__restrict t) +strftime(char * __restrict s, size_t maxsize, const char * __restrict format, + const struct tm * __restrict t) { char *p; tzset(); p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize); if (p == s + maxsize) return 0; *p = '\0'; return p - s; } static char * _fmt(format, t, pt, ptlim) const char *format; const struct tm *const t; char *pt; const char *const ptlim; { int Ealternative, Oalternative; struct lc_time_T *tptr = __get_current_time_locale(); for ( ; *format; ++format) { if (*format == '%') { Ealternative = 0; Oalternative = 0; label: switch (*++format) { case '\0': --format; break; case 'A': pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ? "?" : tptr->weekday[t->tm_wday], pt, ptlim); continue; case 'a': pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ? "?" : tptr->wday[t->tm_wday], pt, ptlim); continue; case 'B': pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ? "?" : (Oalternative ? tptr->alt_month : tptr->month)[t->tm_mon], pt, ptlim); continue; case 'b': case 'h': pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ? "?" : tptr->mon[t->tm_mon], pt, ptlim); continue; case 'C': /* ** %C used to do a... ** _fmt("%a %b %e %X %Y", t); ** ...whereas now POSIX 1003.2 calls for ** something completely different. ** (ado, 5/24/93) */ pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, "%02d", pt, ptlim); continue; case 'c': pt = _fmt(tptr->c_fmt, t, pt, ptlim); continue; case 'D': pt = _fmt("%m/%d/%y", t, pt, ptlim); continue; case 'd': pt = _conv(t->tm_mday, "%02d", pt, ptlim); continue; case 'E': if (Ealternative || Oalternative) break; Ealternative++; goto label; case 'O': /* ** POSIX locale extensions, a la ** Arnold Robbins' strftime version 3.0. ** The sequences ** %Ec %EC %Ex %EX %Ey %EY ** %Od %oe %OH %OI %Om %OM ** %OS %Ou %OU %OV %Ow %OW %Oy ** are supposed to provide alternate ** representations. ** (ado, 5/24/93) ** ** FreeBSD extensions ** %OB %Ef %EF */ if (Ealternative || Oalternative) break; Oalternative++; goto label; case 'e': pt = _conv(t->tm_mday, "%2d", pt, ptlim); continue; case 'F': pt = _fmt("%Y-%m-%d", t, pt, ptlim); continue; case 'H': pt = _conv(t->tm_hour, "%02d", pt, ptlim); continue; case 'I': pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, "%02d", pt, ptlim); continue; case 'j': pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim); continue; case 'k': /* ** This used to be... ** _conv(t->tm_hour % 12 ? ** t->tm_hour % 12 : 12, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbins' ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 5/24/93) */ pt = _conv(t->tm_hour, "%2d", pt, ptlim); continue; #ifdef KITCHEN_SINK case 'K': /* ** After all this time, still unclaimed! */ pt = _add("kitchen sink", pt, ptlim); continue; #endif /* defined KITCHEN_SINK */ case 'l': /* ** This used to be... ** _conv(t->tm_hour, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbin's ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 5/24/93) */ pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, "%2d", pt, ptlim); continue; case 'M': pt = _conv(t->tm_min, "%02d", pt, ptlim); continue; case 'm': pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim); continue; case 'n': pt = _add("\n", pt, ptlim); continue; case 'p': pt = _add((t->tm_hour >= 12) ? tptr->pm : tptr->am, pt, ptlim); continue; case 'R': pt = _fmt("%H:%M", t, pt, ptlim); continue; case 'r': pt = _fmt(tptr->ampm_fmt, t, pt, ptlim); continue; case 'S': pt = _conv(t->tm_sec, "%02d", pt, ptlim); continue; case 's': { struct tm tm; char buf[INT_STRLEN_MAXIMUM( time_t) + 1]; time_t mkt; tm = *t; mkt = mktime(&tm); if (TYPE_SIGNED(time_t)) (void) sprintf(buf, "%ld", (long) mkt); else (void) sprintf(buf, "%lu", (unsigned long) mkt); pt = _add(buf, pt, ptlim); } continue; case 'T': pt = _fmt("%H:%M:%S", t, pt, ptlim); continue; case 't': pt = _add("\t", pt, ptlim); continue; case 'U': pt = _conv((t->tm_yday + 7 - t->tm_wday) / 7, "%02d", pt, ptlim); continue; case 'u': /* ** From Arnold Robbins' strftime version 3.0: ** "ISO 8601: Weekday as a decimal number ** [1 (Monday) - 7]" ** (ado, 5/24/93) */ pt = _conv((t->tm_wday == 0) ? 7 : t->tm_wday, "%d", pt, ptlim); continue; case 'V': /* ISO 8601 week number */ case 'G': /* ISO 8601 year (four digits) */ case 'g': /* ISO 8601 year (two digits) */ /* ** From Arnold Robbins' strftime version 3.0: "the week number of the ** year (the first Monday as the first day of week 1) as a decimal number ** (01-53)." ** (ado, 1993-05-24) ** ** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn: ** "Week 01 of a year is per definition the first week which has the ** Thursday in this year, which is equivalent to the week which contains ** the fourth day of January. In other words, the first week of a new year ** is the week which has the majority of its days in the new year. Week 01 ** might also contain days from the previous year and the week before week ** 01 of a year is the last week (52 or 53) of the previous year even if ** it contains days from the new year. A week starts with Monday (day 1) ** and ends with Sunday (day 7). For example, the first week of the year ** 1997 lasts from 1996-12-30 to 1997-01-05..." ** (ado, 1996-01-02) */ { int year; int yday; int wday; int w; year = t->tm_year + TM_YEAR_BASE; yday = t->tm_yday; wday = t->tm_wday; for ( ; ; ) { int len; int bot; int top; len = isleap(year) ? DAYSPERLYEAR : DAYSPERNYEAR; /* ** What yday (-3 ... 3) does ** the ISO year begin on? */ bot = ((yday + 11 - wday) % DAYSPERWEEK) - 3; /* ** What yday does the NEXT ** ISO year begin on? */ top = bot - (len % DAYSPERWEEK); if (top < -3) top += DAYSPERWEEK; top += len; if (yday >= top) { ++year; w = 1; break; } if (yday >= bot) { w = 1 + ((yday - bot) / DAYSPERWEEK); break; } --year; yday += isleap(year) ? DAYSPERLYEAR : DAYSPERNYEAR; } #ifdef XPG4_1994_04_09 if ((w == 52 && t->tm_mon == TM_JANUARY) || (w == 1 && t->tm_mon == TM_DECEMBER)) w = 53; #endif /* defined XPG4_1994_04_09 */ if (*format == 'V') pt = _conv(w, "%02d", pt, ptlim); else if (*format == 'g') { pt = _conv(year % 100, "%02d", pt, ptlim); } else pt = _conv(year, "%04d", pt, ptlim); } continue; case 'v': /* ** From Arnold Robbins' strftime version 3.0: ** "date as dd-bbb-YYYY" ** (ado, 5/24/93) */ pt = _fmt("%e-%b-%Y", t, pt, ptlim); continue; case 'W': pt = _conv((t->tm_yday + 7 - (t->tm_wday ? (t->tm_wday - 1) : 6)) / 7, "%02d", pt, ptlim); continue; case 'w': pt = _conv(t->tm_wday, "%d", pt, ptlim); continue; case 'X': pt = _fmt(tptr->X_fmt, t, pt, ptlim); continue; case 'x': pt = _fmt(tptr->x_fmt, t, pt, ptlim); continue; case 'y': pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, "%02d", pt, ptlim); continue; case 'Y': pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d", pt, ptlim); continue; case 'Z': if (t->tm_zone != NULL) pt = _add(t->tm_zone, pt, ptlim); else if (t->tm_isdst == 0 || t->tm_isdst == 1) { pt = _add(tzname[t->tm_isdst], pt, ptlim); } else pt = _add("?", pt, ptlim); continue; case 'z': { long absoff; if (t->tm_gmtoff >= 0) { absoff = t->tm_gmtoff; pt = _add("+", pt, ptlim); } else { absoff = -t->tm_gmtoff; pt = _add("-", pt, ptlim); } pt = _conv(absoff / 3600, "%02d", pt, ptlim); pt = _conv((absoff % 3600) / 60, "%02d", pt, ptlim); }; continue; case '+': pt = _fmt(tptr->date_fmt, t, pt, ptlim); continue; case '%': /* * X311J/88-090 (4.12.3.5): if conversion char is * undefined, behavior is undefined. Print out the * character itself as printf(3) also does. */ default: break; } } if (pt == ptlim) break; *pt++ = *format; } return pt; } static char * _conv(n, format, pt, ptlim) const int n; const char *const format; char *const pt; const char *const ptlim; { char buf[INT_STRLEN_MAXIMUM(int) + 1]; (void) sprintf(buf, format, n); return _add(buf, pt, ptlim); } static char * _add(str, pt, ptlim) const char *str; char *pt; const char *const ptlim; { while (pt < ptlim && (*pt = *str++) != '\0') ++pt; return pt; } Index: head/lib/libc/stdtime/strptime.3 =================================================================== --- head/lib/libc/stdtime/strptime.3 (revision 103011) +++ head/lib/libc/stdtime/strptime.3 (revision 103012) @@ -1,143 +1,143 @@ .\" .\" Copyright (c) 1997 Joerg Wunsch .\" .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" $FreeBSD$ .\" " .Dd May 8, 1997 .Dt STRPTIME 3 .Os .Sh NAME .Nm strptime .Nd parse date and time string .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In time.h .Ft char * .Fo strptime -.Fa "const char *restrict buf" -.Fa "const char *restrict format" -.Fa "struct tm *restrict timeptr" +.Fa "const char * restrict buf" +.Fa "const char * restrict format" +.Fa "struct tm * restrict timeptr" .Fc .Sh DESCRIPTION The .Fn strptime function parses the string in the buffer .Fa buf according to the string pointed to by .Fa format , and fills in the elements of the structure pointed to by .Fa timeptr . The resulting values will be relative to the local time zone. Thus, it can be considered the reverse operation of .Xr strftime 3 . .Pp The .Fa format string consists of zero or more conversion specifications and ordinary characters. All ordinary characters are matched exactly with the buffer, where white space in the format string will match any amount of white space in the buffer. All conversion specifications are identical to those described in .Xr strftime 3 . .Pp Two-digit year values, including formats .Fa %y and .Fa \&%D , are now interpreted as beginning at 1969 per POSIX requirements. Years 69-00 are interpreted in the 20th century (1969-2000), years 01-68 in the 21st century (2001-2068). .Sh RETURN VALUES Upon successful completion, .Fn strptime returns the pointer to the first character in .Fa buf that has not been required to satisfy the specified conversions in .Fa format . It returns .Dv NULL if one of the conversions failed. .Sh SEE ALSO .Xr date 1 , .Xr scanf 3 , .Xr strftime 3 .Sh AUTHORS The .Fn strptime function has been contributed by Powerdog Industries. .Pp This man page was written by .An J\(:org Wunsch . .Sh HISTORY The .Fn strptime function appeared in .Fx 3.0 . .Sh BUGS Both the .Fa %e and .Fa %l format specifiers may incorrectly scan one too many digits if the intended values comprise only a single digit and that digit is followed immediately by another digit. Both specifiers accept zero-padded values, even though they are both defined as taking unpadded values. .Pp The .Fa %p format specifier has no effect unless it is parsed .Em after hour-related specifiers. Specifying .Fa %l without .Fa %p will produce undefined results. Note that 12AM (ante meridiem) is taken as midnight and 12PM (post meridiem) is taken as noon. .Pp The .Fa %U and .Fa %W format specifiers accept any value within the range 00 to 53 without validating against other values supplied (like month or day of the year, for example). .Pp The .Fa %Z format specifier only accepts time zone abbreviations of the local time zone, or the value "GMT". This limitation is because of ambiguity due to of the over loading of time zone abbreviations. One such example is .Fa EST which is both Eastern Standard Time and Eastern Australia Summer Time. Index: head/lib/libc/stdtime/strptime.c =================================================================== --- head/lib/libc/stdtime/strptime.c (revision 103011) +++ head/lib/libc/stdtime/strptime.c (revision 103012) @@ -1,540 +1,540 @@ /* * Powerdog Industries kindly requests feedback from anyone modifying * this function: * * Date: Thu, 05 Jun 1997 23:17:17 -0400 * From: Kevin Ruddy * To: James FitzGibbon * Subject: Re: Use of your strptime(3) code (fwd) * * The reason for the "no mod" clause was so that modifications would * come back and we could integrate them and reissue so that a wider * audience could use it (thereby spreading the wealth). This has * made it possible to get strptime to work on many operating systems. * I'm not sure why that's "plain unacceptable" to the FreeBSD team. * * Anyway, you can change it to "with or without modification" as * you see fit. Enjoy. * * Kevin Ruddy * Powerdog Industries, Inc. */ /* * Copyright (c) 1994 Powerdog Industries. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgement: * This product includes software developed by Powerdog Industries. * 4. The name of Powerdog Industries may not be used to endorse or * promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE POWERDOG INDUSTRIES BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef lint #ifndef NOID static char copyright[] = "@(#) Copyright (c) 1994 Powerdog Industries. All rights reserved."; static char sccsid[] = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; #endif /* !defined NOID */ #endif /* not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "timelocal.h" static char * _strptime(const char *, const char *, struct tm *); static pthread_mutex_t gotgmt_mutex = PTHREAD_MUTEX_INITIALIZER; static int got_GMT; #define asizeof(a) (sizeof (a) / sizeof ((a)[0])) static char * _strptime(const char *buf, const char *fmt, struct tm *tm) { char c; const char *ptr; int i, len; int Ealternative, Oalternative; struct lc_time_T *tptr = __get_current_time_locale(); ptr = fmt; while (*ptr != 0) { if (*buf == 0) break; c = *ptr++; if (c != '%') { if (isspace((unsigned char)c)) while (*buf != 0 && isspace((unsigned char)*buf)) buf++; else if (c != *buf++) return 0; continue; } Ealternative = 0; Oalternative = 0; label: c = *ptr++; switch (c) { case 0: case '%': if (*buf++ != '%') return 0; break; case '+': buf = _strptime(buf, tptr->date_fmt, tm); if (buf == 0) return 0; break; case 'C': if (!isdigit((unsigned char)*buf)) return 0; /* XXX This will break for 3-digit centuries. */ len = 2; for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; len--; } if (i < 19) return 0; tm->tm_year = i * 100 - 1900; break; case 'c': buf = _strptime(buf, tptr->c_fmt, tm); if (buf == 0) return 0; break; case 'D': buf = _strptime(buf, "%m/%d/%y", tm); if (buf == 0) return 0; break; case 'E': if (Ealternative || Oalternative) break; Ealternative++; goto label; case 'O': if (Ealternative || Oalternative) break; Oalternative++; goto label; case 'F': buf = _strptime(buf, "%Y-%m-%d", tm); if (buf == 0) return 0; break; case 'R': buf = _strptime(buf, "%H:%M", tm); if (buf == 0) return 0; break; case 'r': buf = _strptime(buf, tptr->ampm_fmt, tm); if (buf == 0) return 0; break; case 'T': buf = _strptime(buf, "%H:%M:%S", tm); if (buf == 0) return 0; break; case 'X': buf = _strptime(buf, tptr->X_fmt, tm); if (buf == 0) return 0; break; case 'x': buf = _strptime(buf, tptr->x_fmt, tm); if (buf == 0) return 0; break; case 'j': if (!isdigit((unsigned char)*buf)) return 0; len = 3; for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; len--; } if (i < 1 || i > 366) return 0; tm->tm_yday = i - 1; break; case 'M': case 'S': if (*buf == 0 || isspace((unsigned char)*buf)) break; if (!isdigit((unsigned char)*buf)) return 0; len = 2; for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; len--; } if (c == 'M') { if (i > 59) return 0; tm->tm_min = i; } else { if (i > 60) return 0; tm->tm_sec = i; } if (*buf != 0 && isspace((unsigned char)*buf)) while (*ptr != 0 && !isspace((unsigned char)*ptr)) ptr++; break; case 'H': case 'I': case 'k': case 'l': /* * Of these, %l is the only specifier explicitly * documented as not being zero-padded. However, * there is no harm in allowing zero-padding. * * XXX The %l specifier may gobble one too many * digits if used incorrectly. */ if (!isdigit((unsigned char)*buf)) return 0; len = 2; for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; len--; } if (c == 'H' || c == 'k') { if (i > 23) return 0; } else if (i > 12) return 0; tm->tm_hour = i; if (*buf != 0 && isspace((unsigned char)*buf)) while (*ptr != 0 && !isspace((unsigned char)*ptr)) ptr++; break; case 'p': /* * XXX This is bogus if parsed before hour-related * specifiers. */ len = strlen(tptr->am); if (strncasecmp(buf, tptr->am, len) == 0) { if (tm->tm_hour > 12) return 0; if (tm->tm_hour == 12) tm->tm_hour = 0; buf += len; break; } len = strlen(tptr->pm); if (strncasecmp(buf, tptr->pm, len) == 0) { if (tm->tm_hour > 12) return 0; if (tm->tm_hour != 12) tm->tm_hour += 12; buf += len; break; } return 0; case 'A': case 'a': for (i = 0; i < asizeof(tptr->weekday); i++) { len = strlen(tptr->weekday[i]); if (strncasecmp(buf, tptr->weekday[i], len) == 0) break; len = strlen(tptr->wday[i]); if (strncasecmp(buf, tptr->wday[i], len) == 0) break; } if (i == asizeof(tptr->weekday)) return 0; tm->tm_wday = i; buf += len; break; case 'U': case 'W': /* * XXX This is bogus, as we can not assume any valid * information present in the tm structure at this * point to calculate a real value, so just check the * range for now. */ if (!isdigit((unsigned char)*buf)) return 0; len = 2; for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; len--; } if (i > 53) return 0; if (*buf != 0 && isspace((unsigned char)*buf)) while (*ptr != 0 && !isspace((unsigned char)*ptr)) ptr++; break; case 'w': if (!isdigit((unsigned char)*buf)) return 0; i = *buf - '0'; if (i > 6) return 0; tm->tm_wday = i; if (*buf != 0 && isspace((unsigned char)*buf)) while (*ptr != 0 && !isspace((unsigned char)*ptr)) ptr++; break; case 'd': case 'e': /* * The %e specifier is explicitly documented as not * being zero-padded but there is no harm in allowing * such padding. * * XXX The %e specifier may gobble one too many * digits if used incorrectly. */ if (!isdigit((unsigned char)*buf)) return 0; len = 2; for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; len--; } if (i > 31) return 0; tm->tm_mday = i; if (*buf != 0 && isspace((unsigned char)*buf)) while (*ptr != 0 && !isspace((unsigned char)*ptr)) ptr++; break; case 'B': case 'b': case 'h': for (i = 0; i < asizeof(tptr->month); i++) { if (Oalternative) { if (c == 'B') { len = strlen(tptr->alt_month[i]); if (strncasecmp(buf, tptr->alt_month[i], len) == 0) break; } } else { len = strlen(tptr->month[i]); if (strncasecmp(buf, tptr->month[i], len) == 0) break; len = strlen(tptr->mon[i]); if (strncasecmp(buf, tptr->mon[i], len) == 0) break; } } if (i == asizeof(tptr->month)) return 0; tm->tm_mon = i; buf += len; break; case 'm': if (!isdigit((unsigned char)*buf)) return 0; len = 2; for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; len--; } if (i < 1 || i > 12) return 0; tm->tm_mon = i - 1; if (*buf != 0 && isspace((unsigned char)*buf)) while (*ptr != 0 && !isspace((unsigned char)*ptr)) ptr++; break; case 's': { char *cp; time_t t; t = strtol(buf, &cp, 10); if (t == LONG_MAX) return 0; buf = cp; gmtime_r(&t, tm); got_GMT = 1; } break; case 'Y': case 'y': if (*buf == 0 || isspace((unsigned char)*buf)) break; if (!isdigit((unsigned char)*buf)) return 0; len = (c == 'Y') ? 4 : 2; for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; len--; } if (c == 'Y') i -= 1900; if (c == 'y' && i < 69) i += 100; if (i < 0) return 0; tm->tm_year = i; if (*buf != 0 && isspace((unsigned char)*buf)) while (*ptr != 0 && !isspace((unsigned char)*ptr)) ptr++; break; case 'Z': { const char *cp; char *zonestr; for (cp = buf; *cp && isupper((unsigned char)*cp); ++cp) {/*empty*/} if (cp - buf) { zonestr = alloca(cp - buf + 1); strncpy(zonestr, buf, cp - buf); zonestr[cp - buf] = '\0'; tzset(); if (0 == strcmp(zonestr, "GMT")) { got_GMT = 1; } else if (0 == strcmp(zonestr, tzname[0])) { tm->tm_isdst = 0; } else if (0 == strcmp(zonestr, tzname[1])) { tm->tm_isdst = 1; } else { return 0; } buf += cp - buf; } } break; } } return (char *)buf; } char * -strptime(const char *__restrict buf, const char *__restrict fmt, - struct tm *__restrict tm) +strptime(const char * __restrict buf, const char * __restrict fmt, + struct tm * __restrict tm) { char *ret; if (__isthreaded) _pthread_mutex_lock(&gotgmt_mutex); got_GMT = 0; ret = _strptime(buf, fmt, tm); if (ret && got_GMT) { time_t t = timegm(tm); localtime_r(&t, tm); got_GMT = 0; } if (__isthreaded) _pthread_mutex_unlock(&gotgmt_mutex); return ret; } Index: head/lib/libc/string/strcat.3 =================================================================== --- head/lib/libc/string/strcat.3 (revision 103011) +++ head/lib/libc/string/strcat.3 (revision 103012) @@ -1,164 +1,164 @@ .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Chris Torek and the American National Standards Committee X3, .\" on Information Processing Systems. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)strcat.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" .Dd June 4, 1993 .Dt STRCAT 3 .Os .Sh NAME .Nm strcat .Nd concatenate strings .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In string.h .Ft char * -.Fn strcat "char *restrict s" "const char *restrict append" +.Fn strcat "char * restrict s" "const char * restrict append" .Ft char * -.Fn strncat "char *restrict s" "const char *restrict append" "size_t count" +.Fn strncat "char * restrict s" "const char * restrict append" "size_t count" .Sh DESCRIPTION The .Fn strcat and .Fn strncat functions append a copy of the null-terminated string .Fa append to the end of the null-terminated string .Fa s , then add a terminating .Ql \e0 . The string .Fa s must have sufficient space to hold the result. .Pp The .Fn strncat function appends not more than .Fa count characters from .Fa append , and then adds a terminating .Ql \e0 . .Sh RETURN VALUES The .Fn strcat and .Fn strncat functions return the pointer .Fa s . .Sh SECURITY CONSIDERATIONS The .Fn strcat function is easily misused in a manner which enables malicious users to arbitrarily change a running program's functionality through a buffer overflow attack. (See the FSA.) .Pp Avoid using .Fn strcat . Instead, use .Fn strncat or .Fn strlcat and ensure that no more characters are copied to the destination buffer than it can hold. .Pp Note that .Fn strncat can also be problematic. It may be a security concern for a string to be truncated at all. Since the truncated string will not be as long as the original, it may refer to a completely different resource and usage of the truncated resource could result in very incorrect behavior. Example: .Bd -literal void foo(const char *arbitrary_string) { char onstack[8]; #if defined(BAD) /* * This first strcat is bad behavior. Do not use strcat! */ (void)strcat(onstack, arbitrary_string); /* BAD! */ #elif defined(BETTER) /* * The following two lines demonstrate better use of * strncat(). */ (void)strncat(onstack, arbitrary_string, sizeof(onstack) - strlen(onstack) - 1); #elif defined(BEST) /* * These lines are even more robust due to testing for * truncation. */ if (strlen(arbitrary_string) + 1 > sizeof(onstack) - strlen(onstack)) err(1, "onstack would be truncated"); (void)strncat(onstack, arbitrary_string, sizeof(onstack) - strlen(onstack) - 1); #endif } .Ed .Sh SEE ALSO .Xr bcopy 3 , .Xr memccpy 3 , .Xr memcpy 3 , .Xr memmove 3 , .Xr strcpy 3 , .Xr strlcat 3 , .Xr strlcpy 3 .Rs .%T "The FreeBSD Security Architecture" .Re (See .Pa "/usr/share/doc/{to be decided}" . ) .Sh STANDARDS The .Fn strcat and .Fn strncat functions conform to .St -isoC . Index: head/lib/libc/string/strcat.c =================================================================== --- head/lib/libc/string/strcat.c (revision 103011) +++ head/lib/libc/string/strcat.c (revision 103012) @@ -1,50 +1,50 @@ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strcat.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include char * -strcat(char *__restrict s, const char *__restrict append) +strcat(char * __restrict s, const char * __restrict append) { char *save = s; for (; *s; ++s); while ((*s++ = *append++)); return(save); } Index: head/lib/libc/string/strcpy.3 =================================================================== --- head/lib/libc/string/strcpy.3 (revision 103011) +++ head/lib/libc/string/strcpy.3 (revision 103012) @@ -1,180 +1,180 @@ .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Chris Torek and the American National Standards Committee X3, .\" on Information Processing Systems. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)strcpy.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" .Dd August 9, 2001 .Dt STRCPY 3 .Os .Sh NAME .Nm strcpy , strncpy .Nd copy strings .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In string.h .Ft char * -.Fn strcpy "char *restrict dst" "const char *restrict src" +.Fn strcpy "char * restrict dst" "const char * restrict src" .Ft char * -.Fn strncpy "char *restrict dst" "const char *restrict src" "size_t len" +.Fn strncpy "char * restrict dst" "const char * restrict src" "size_t len" .Sh DESCRIPTION The .Fn strcpy function copies the string .Fa src to .Fa dst (including the terminating .Ql \e0 character). .Pp The .Fn strncpy function copies not more than .Fa len characters from .Fa src into .Fa dst , appending .Ql \e0 characters if .Fa src is less than .Fa len characters long, and .Em not terminating .Fa dst otherwise. .Sh RETURN VALUES The .Fn strcpy and .Fn strncpy functions return .Fa dst . .Sh EXAMPLES The following sets .Va chararray to .Dq Li abc\e0\e0\e0 : .Bd -literal -offset indent char chararray[6]; (void)strncpy(chararray, "abc", sizeof(chararray)); .Ed .Pp The following sets .Va chararray to .Dq Li abcdef : .Bd -literal -offset indent char chararray[6]; (void)strncpy(chararray, "abcdefgh", sizeof(chararray)); .Ed .Pp Note that it does .Em not .Tn NUL terminate .Va chararray because the length of the source string is greater than or equal to the length parameter. .Pp The following copies as many characters from .Va input to .Va buf as will fit and .Tn NUL terminates the result. Because .Fn strncpy does .Em not guarantee to .Tn NUL terminate the string itself, this must be done explicitly. .Bd -literal -offset indent char buf[1024]; (void)strncpy(buf, input, sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\e0'; .Ed .Pp This could be better achieved using .Xr strlcpy 3 , as shown in the following example: .Pp .Dl "(void)strlcpy(buf, input, sizeof(buf));" .Pp Note that because .Xr strlcpy 3 is not defined in any standards, it should only be used when portability is not a concern. .Sh SECURITY CONSIDERATIONS The .Fn strcpy function is easily misused in a manner which enables malicious users to arbitrarily change a running program's functionality through a buffer overflow attack. (See the FSA and .Sx EXAMPLES . ) .Sh SEE ALSO .Xr bcopy 3 , .Xr memccpy 3 , .Xr memcpy 3 , .Xr memmove 3 , .Xr strlcpy 3 .Rs .%T "The FreeBSD Security Architecture" .Re (See .Pa "/usr/share/doc/{to be decided}" . ) .Sh STANDARDS The .Fn strcpy and .Fn strncpy functions conform to .St -isoC . Index: head/lib/libc/string/strcpy.c =================================================================== --- head/lib/libc/string/strcpy.c (revision 103011) +++ head/lib/libc/string/strcpy.c (revision 103012) @@ -1,49 +1,49 @@ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strcpy.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include char * -strcpy(char *__restrict to, const char *__restrict from) +strcpy(char * __restrict to, const char * __restrict from) { char *save = to; for (; (*to = *from); ++from, ++to); return(save); } Index: head/lib/libc/string/strncat.c =================================================================== --- head/lib/libc/string/strncat.c (revision 103011) +++ head/lib/libc/string/strncat.c (revision 103012) @@ -1,66 +1,66 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strncat.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include /* * Concatenate src on the end of dst. At most strlen(dst)+n+1 bytes * are written at dst (at most n+1 bytes being appended). Return dst. */ char * -strncat(char *__restrict dst, const char *__restrict src, size_t n) +strncat(char * __restrict dst, const char * __restrict src, size_t n) { if (n != 0) { char *d = dst; const char *s = src; while (*d != 0) d++; do { if ((*d = *s++) == 0) break; d++; } while (--n != 0); *d = 0; } return (dst); } Index: head/lib/libc/string/strncpy.c =================================================================== --- head/lib/libc/string/strncpy.c (revision 103011) +++ head/lib/libc/string/strncpy.c (revision 103012) @@ -1,66 +1,66 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strncpy.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include /* * Copy src to dst, truncating or null-padding to always copy n bytes. * Return dst. */ char * -strncpy(char *__restrict dst, const char *__restrict src, size_t n) +strncpy(char * __restrict dst, const char * __restrict src, size_t n) { if (n != 0) { char *d = dst; const char *s = src; do { if ((*d++ = *s++) == 0) { /* NUL pad the remaining n-1 bytes */ while (--n != 0) *d++ = 0; break; } } while (--n != 0); } return (dst); } Index: head/lib/libc/string/strxfrm.3 =================================================================== --- head/lib/libc/string/strxfrm.3 (revision 103011) +++ head/lib/libc/string/strxfrm.3 (revision 103012) @@ -1,99 +1,99 @@ .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Chris Torek and the American National Standards Committee X3, .\" on Information Processing Systems. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)strxfrm.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" .Dd June 4, 1993 .Dt STRXFRM 3 .Os .Sh NAME .Nm strxfrm .Nd transform a string under locale .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In string.h .Ft size_t -.Fn strxfrm "char *restrict dst" "const char *restrict src" "size_t n" +.Fn strxfrm "char * restrict dst" "const char * restrict src" "size_t n" .Sh DESCRIPTION The .Fn strxfrm function transforms a null-terminated string pointed to by .Fa src according to the current locale collation if any, then copies the transformed string into .Fa dst . Not more than .Fa n characters are copied into .Fa dst , including the terminating null character added. If .Fa n is set to 0 (it helps to determine an actual size needed for transformation), .Fa dst is permitted to be a NULL pointer. .Pp Comparing two strings using .Fn strcmp after .Fn strxfrm is equal to comparing two original strings with .Fn strcoll . .Sh RETURN VALUES Upon successful completion, .Fn strxfrm returns the length of the transformed string not including the terminating null character. If this value is .Fa n or more, the contents of .Fa dst are indeterminate. .Sh SEE ALSO .Xr setlocale 3 , .Xr strcmp 3 , .Xr strcoll 3 .Sh STANDARDS The .Fn strxfrm function conforms to .St -isoC . Index: head/lib/libc/string/strxfrm.c =================================================================== --- head/lib/libc/string/strxfrm.c (revision 103011) +++ head/lib/libc/string/strxfrm.c (revision 103012) @@ -1,83 +1,83 @@ /*- * Copyright (c) 1995 Alex Tatmanjants * at Electronni Visti IA, Kiev, Ukraine. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include "collate.h" size_t -strxfrm(char *__restrict dest, const char *__restrict src, size_t len) +strxfrm(char * __restrict dest, const char * __restrict src, size_t len) { int prim, sec, l; size_t slen; char *s, *ss; if (!*src) { if (len > 0) *dest = '\0'; return 0; } if (__collate_load_error) { slen = strlen(src); if (len > 0) { if (slen < len) strcpy(dest, src); else { strncpy(dest, src, len - 1); dest[len - 1] = '\0'; } } return slen; } slen = 0; prim = sec = 0; ss = s = __collate_substitute(src); while (*s) { while (*s && !prim) { __collate_lookup(s, &l, &prim, &sec); s += l; } if (prim) { if (len > 1) { *dest++ = (char)prim; len--; } slen++; prim = 0; } } free(ss); if (len > 0) *dest = '\0'; return slen; }