summaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1997-11-29 19:54:53 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1997-11-29 19:54:53 +0000
commit024ba423ea0a307412d5003ef9850338156bf5a5 (patch)
tree1b9e345cdff1afda03d93ef840f966cc98ecfc09 /lib/libc
parent34231e94bf05e703994e7617faff53abdf1c9e72 (diff)
Implement asprintf(3) and vasprintf(3) functions similar to the
ones in the glibc. Some man pages changes from FreeBSD (asprintf.c/vasprintf.c are not based on GNU or FreeBSD code).
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/shlib_version2
-rw-r--r--lib/libc/stdio/asprintf.c83
-rw-r--r--lib/libc/stdio/fvwrite.c18
-rw-r--r--lib/libc/stdio/printf.3107
-rw-r--r--lib/libc/stdio/vasprintf.c67
5 files changed, 233 insertions, 44 deletions
diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version
index 51c2640f411..16555489150 100644
--- a/lib/libc/shlib_version
+++ b/lib/libc/shlib_version
@@ -1,2 +1,2 @@
major=17
-minor=4
+minor=5
diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c
new file mode 100644
index 00000000000..1e5f00fa1ab
--- /dev/null
+++ b/lib/libc/stdio/asprintf.c
@@ -0,0 +1,83 @@
+/* $OpenBSD: asprintf.c,v 1.1 1997/11/29 19:54:48 millert Exp $ */
+
+/*
+ * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+ * 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 Todd C. Miller.
+ * 4. 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: asprintf.c,v 1.1 1997/11/29 19:54:48 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+#if __STDC__
+asprintf(char **str, char const *fmt, ...)
+#else
+asprintf(str, fmt, va_alist)
+ char **str;
+ const char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+ FILE f;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ f._flags = __SWR | __SSTR | __SALC;
+ f._bf._base = f._p = (unsigned char *)malloc(128);
+ if (f._bf._base == NULL) {
+ *str = NULL;
+ errno = ENOMEM;
+ return (-1);
+ }
+ f._bf._size = f._w = 127; /* Leave room for the NULL */
+ ret = vfprintf(&f, fmt, ap);
+ *f._p = '\0';
+ va_end(ap);
+ f._bf._base = realloc(f._bf._base, f._bf._size + 1);
+ if (f._bf._base == NULL) {
+ errno = ENOMEM;
+ ret = -1;
+ }
+ *str = f._bf._base;
+ return (ret);
+}
diff --git a/lib/libc/stdio/fvwrite.c b/lib/libc/stdio/fvwrite.c
index 259152be86f..c01968b72f8 100644
--- a/lib/libc/stdio/fvwrite.c
+++ b/lib/libc/stdio/fvwrite.c
@@ -35,10 +35,11 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: fvwrite.c,v 1.4 1996/10/26 08:16:07 tholo Exp $";
+static char rcsid[] = "$OpenBSD: fvwrite.c,v 1.5 1997/11/29 19:54:48 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "local.h"
@@ -109,6 +110,21 @@ __sfvwrite(fp, uio)
*/
do {
GETIOV(;);
+ if ((fp->_flags & (__SALC | __SSTR)) ==
+ (__SALC | __SSTR) && fp->_w < len) {
+ size_t blen = fp->_p - fp->_bf._base;
+
+ /*
+ * Alloc an extra 128 bytes (+ 1 for NULL)
+ * so we don't call realloc(3) so often.
+ */
+ fp->_w = len + 128;
+ fp->_bf._size = blen + len + 128;
+ /* XXX - check return val */
+ fp->_bf._base =
+ realloc(fp->_bf._base, fp->_bf._size + 1);
+ fp->_p = fp->_bf._base + blen;
+ }
w = fp->_w;
if (fp->_flags & __SSTR) {
if (len < w)
diff --git a/lib/libc/stdio/printf.3 b/lib/libc/stdio/printf.3
index 7786746a339..f43672a901e 100644
--- a/lib/libc/stdio/printf.3
+++ b/lib/libc/stdio/printf.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: printf.3,v 1.4 1997/06/30 03:22:08 millert Exp $
+.\" $OpenBSD: printf.3,v 1.5 1997/11/29 19:54:49 millert Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -35,6 +35,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" @(#)printf.3 8.1 (Berkeley) 6/4/93
+.\"
.Dd June 4, 1993
.Dt PRINTF 3
.Os
@@ -43,10 +45,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,19 +62,19 @@
.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"
.Ft int
.Fn vfprintf "FILE *stream" "const char *format" "va_list ap"
.Ft int
-.Fn vsprintf "char *str" "char *format" "va_list ap"
+.Fn vsprintf "char *str" "const 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 +98,50 @@ 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 ;
+.Fn asprintf
+and
+.Fn vasprintf
+write to a dynamically allocated string that is stored in
+.Fa ret .
+.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
+.Fn Snprintf
+and
+.Fn vsnprintf
+will return -1 if the
+.Fa size
+parameter is 0.
+.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 +156,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
@@ -180,7 +190,6 @@ 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 -hyphen
@@ -189,7 +198,7 @@ A
.Cm #
character
specifying that the value should be converted to an ``alternate form''.
-For
+For
.Cm c ,
.Cm d ,
.Cm i ,
@@ -199,7 +208,7 @@ For
and
.Cm u ,
conversions, this option has no effect.
-For
+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
@@ -239,7 +248,7 @@ 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
-.Pf ( Mc d ,
+.Pf ( Cm d ,
.Cm i ,
.Cm o ,
.Cm u ,
@@ -615,6 +624,14 @@ 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 first appeared in
+.Bx Open
+2.3.
.Sh BUGS
The conversion formats
.Cm \&%D ,
@@ -649,6 +666,12 @@ callers must be careful not to overflow the actual space;
this is often impossible to assure.
For safety, programmers should use the
.Fn snprintf
-interface instead.
-Unfortunately, this interface is not available on older
-systems.
+and
+.Fn vasprintf
+family of interfaces instead.
+Unfortunately, the
+.Fn snprintf
+interface is not available on older
+systems and the
+.Fn vasprintf
+interface is not portable.
diff --git a/lib/libc/stdio/vasprintf.c b/lib/libc/stdio/vasprintf.c
new file mode 100644
index 00000000000..e11f33b7dff
--- /dev/null
+++ b/lib/libc/stdio/vasprintf.c
@@ -0,0 +1,67 @@
+/* $OpenBSD: vasprintf.c,v 1.1 1997/11/29 19:54:47 millert Exp $ */
+
+/*
+ * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+ * 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 Todd C. Miller.
+ * 4. 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: vasprintf.c,v 1.1 1997/11/29 19:54:47 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+int
+vasprintf(str, fmt, ap)
+ char **str;
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ int ret;
+ FILE f;
+
+ f._flags = __SWR | __SSTR | __SALC;
+ f._bf._base = f._p = (unsigned char *)malloc(128);
+ if (f._bf._base == NULL) {
+ *str = NULL;
+ errno = ENOMEM;
+ return (-1);
+ }
+ f._bf._size = f._w = 127; /* Leave room for the NULL */
+ ret = vfprintf(&f, fmt, ap);
+ *f._p = '\0';
+ f._bf._base = realloc(f._bf._base, f._bf._size + 1);
+ if (f._bf._base == NULL) {
+ errno = ENOMEM;
+ ret = -1;
+ }
+ *str = f._bf._base;
+ return (ret);
+}