diff options
| author | Peter Wemm <peter@FreeBSD.org> | 1996-05-27 10:49:43 +0000 | 
|---|---|---|
| committer | Peter Wemm <peter@FreeBSD.org> | 1996-05-27 10:49:43 +0000 | 
| commit | 15aa00d597010009c3fb718ded37438aa3f601ab (patch) | |
| tree | 46b469e307f5817e3d72000c1cb25e1b95261d2d /lib/libc/stdio | |
| parent | c12a60de93e437e6d2da41797fbd9bb4c0ec3041 (diff) | |
Notes
Diffstat (limited to 'lib/libc/stdio')
| -rw-r--r-- | lib/libc/stdio/Makefile.inc | 10 | ||||
| -rw-r--r-- | lib/libc/stdio/asprintf.c | 59 | ||||
| -rw-r--r-- | lib/libc/stdio/printf.3 | 80 | ||||
| -rw-r--r-- | lib/libc/stdio/vasprintf.c | 108 | 
4 files changed, 219 insertions, 38 deletions
| diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc index 5ca501621a49..b9c02a41f40c 100644 --- a/lib/libc/stdio/Makefile.inc +++ b/lib/libc/stdio/Makefile.inc @@ -3,16 +3,16 @@  # stdio sources  .PATH: ${.CURDIR}/stdio -SRCS+=	clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \ -	fgetln.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \ +SRCS+=	asprintf.c clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c \ +	fgetc.c fgetln.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \  	fprintf.c fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \  	fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \  	getc.c getchar.c gets.c getw.c makebuf.c mktemp.c perror.c \  	printf.c putc.c putchar.c puts.c putw.c refill.c remove.c rewind.c \  	rget.c scanf.c setbuf.c setbuffer.c setvbuf.c snprintf.c sprintf.c \ -	sscanf.c stdio.c tempnam.c tmpfile.c tmpnam.c ungetc.c vfprintf.c \ -	vfscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c \ -	wbuf.c wsetup.c +	sscanf.c stdio.c tempnam.c tmpfile.c tmpnam.c ungetc.c vasprintf.c \ +	vfprintf.c vfscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c \ +	vsscanf.c wbuf.c wsetup.c  MAN3+=	stdio/fclose.3 stdio/ferror.3 stdio/fflush.3 stdio/fgetln.3 \  	stdio/fgets.3 stdio/fopen.3 stdio/fputs.3 stdio/fread.3 stdio/fseek.3 \ diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c new file mode 100644 index 000000000000..9b4d05b4397b --- /dev/null +++ b/lib/libc/stdio/asprintf.c @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 1996  Peter Wemm <peter@freebsd.org> + * + * 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. + */ + +#if defined(LIBC_RCS) && !defined(lint) +static char rcsid[] = "$Id$"; +#endif /* LIBC_RCS and not lint */ + +#include <stdio.h> +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +#if __STDC__ +int +asprintf(char **str, char const *fmt, ...) +#else +int +asprintf(str, fmt, va_alist) +	char **str; +	char *fmt; +	va_dcl +#endif +{ +	int ret; +	va_list ap; + +#if __STDC__ +	va_start(ap, fmt); +#else +	va_start(ap); +#endif +	ret = vasprintf(str, fmt, ap); +	va_end(ap); +	return (ret); +} diff --git a/lib/libc/stdio/printf.3 b/lib/libc/stdio/printf.3 index 4238a90a889e..e675b3eda99b 100644 --- a/lib/libc/stdio/printf.3 +++ b/lib/libc/stdio/printf.3 @@ -43,10 +43,12 @@  .Nm fprintf ,  .Nm sprintf ,  .Nm snprintf , +.Nm asprintf ,  .Nm vprintf ,  .Nm vfprintf,  .Nm vsprintf , -.Nm vsnprintf +.Nm vsnprintf , +.Nm vasprintf  .Nd formatted output conversion  .Sh SYNOPSIS  .Fd #include <stdio.h> @@ -58,8 +60,8 @@  .Fn sprintf "char *str" "const char *format" ...  .Ft int  .Fn snprintf "char *str" "size_t size" "const char *format" ... -.\" .Ft int -.\" .Fn smprintf "const char *format" ... +.Ft int +.Fn asprintf "char **ret" "const char *format" ...  .Fd #include <stdarg.h>  .Ft int  .Fn vprintf "const char *format" "va_list ap" @@ -69,8 +71,8 @@  .Fn vsprintf "char *str" "char *format" "va_list ap"  .Ft int  .Fn vsnprintf "char *str" "size_t size" "const char *format" "va_list ap" -.\" .Ft int -.\" .Fn vsmprintf "const char *format" "va_list ap" +.Ft int +.Fn vasprintf "char **ret" "const char *format" "va_list ap"  .Sh DESCRIPTION  The  .Fn printf @@ -94,45 +96,47 @@ write output to the given output  and  .Fn vsnprintf  write to the character string -.Fa str . -.\" .IR str ; -.\" and -.\" .I smprintf -.\" and -.\" .I vsmprintf -.\" dynamically allocate a new string with -.\" .IR malloc . +.Fa str ; +and +.Fn asprintf +and +.Fn vasprintf +dynamically allocate a new string with +.Xr malloc 3 +/ +.Xr realloc 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. -.\" Except for -.\" .I smprintf -.\" and -.\" .IR vsmprintf , -.\" all of these functions return +.Pp  These functions return  the number of characters printed  (not including the trailing  .Ql \e0  used to end output to strings). -.\" .I Smprintf -.\" and -.\" .I vsmprintf -.\" return a pointer to a string of an appropriate length; -.\" this pointer should be passed to -.\" .I free -.\" to release the associated storage -.\" when it is no longer needed. -.\" If sufficient space is not avaliable, -.\" .I smprintf -.\" and -.\" .I vsmprintf -.\" will return -.\" .SM -.\" .BR +.Pp +.Fn Asprintf +and +.Fn vasprintf +return a pointer to a buffer sufficiently large to hold the +string in the +.Fa ret +argument; +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 NULL pointer. +.Pp  .Fn Snprintf  and  .Fn vsnprintf @@ -147,6 +151,7 @@ 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. +.Pp  .Fn Sprintf  and  .Fn vsprintf @@ -600,6 +605,15 @@ The functions  and  .Fn vsnprintf  are new to this release. +.Pp +The functions +.Fn asprintf +and +.Fn vasprintf +first appeared in the GNU C library.  This implementation is thought +to be compatable but is not derived from the GNU code.  This implementation +was written by Peter Wemm <peter@FreeBSD.org> and first appeared in +FreeBSD-2.2.  .Sh BUGS  The conversion formats  .Cm \&%D , diff --git a/lib/libc/stdio/vasprintf.c b/lib/libc/stdio/vasprintf.c new file mode 100644 index 000000000000..bec579a7a9de --- /dev/null +++ b/lib/libc/stdio/vasprintf.c @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 1996  Peter Wemm <peter@freebsd.org> + * + * 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. + */ + +#if defined(LIBC_RCS) && !defined(lint) +static char rcsid[] = "$Id$"; +#endif /* LIBC_RCS and not lint */ + +#include <stdio.h> +#include <stdlib.h> + +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +#define CHUNK_SPARE 128 /* how much spare to allocate to avoid realloc calls */ + +struct bufcookie { +	char	*base;	/* start of buffer */ +	int	size; +	int	left; +}; + +static int +writehook(cookie, buf, len) +	void *cookie; +	char *buf; +	int   len; +{ +	struct bufcookie *h = (struct bufcookie *)cookie; + +	if (len == 0) +		return 0; + +	if (len > h->left) { +		/* grow malloc region */ +		h->left = h->left + len + CHUNK_SPARE; +		h->size = h->size + len + CHUNK_SPARE; +		h->base = realloc(h->base, h->size); +		if (h->base == NULL) +			return (-1); +	} +	/* "write" it */ +	(void)memcpy(h->base + h->size - h->left, buf, len); +	h->left -= len; +	return (0); +} + + +int +vasprintf(str, fmt, ap) +	char **str; +	const char *fmt; +	va_list ap; +{ +	int ret; +	FILE *f; +	struct bufcookie h; + +	h.base = malloc(CHUNK_SPARE); +	if (h.base == NULL) +		return (-1); +	h.size = CHUNK_SPARE; +	h.left = CHUNK_SPARE; + +	f = funopen(&h, NULL, writehook, NULL, NULL); +	if (f == NULL) { +		free(h.base); +		return (-1); +	} +	ret = vfprintf(f, fmt, ap); +	fclose(f); +	if (ret < 0) { +		free(h.base); +		return (-1); +	} +	if (h.base == NULL)	/* failed to realloc in writehook */ +		return (-1); + +	h.base[h.size - h.left] = '\0'; +	*str = realloc(h.base, h.size - h.left + 1); +	if (*str == NULL)	/* failed to realloc it to actual size */ +		return -1; +	return (ret); +} | 
