summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2006-03-14 16:57:30 +0000
committerandre <andre@FreeBSD.org>2006-03-14 16:57:30 +0000
commit9ec6603878b44d4ee5c0205e99fa9788e8717b96 (patch)
treeda218425feae6ba491bf6dcbb51422c211cce3a1 /lib/libc
parentaaa33da2edd23682521bc1bbbfa6ec1f33e6a9b6 (diff)
downloadFreeBSD-src-9ec6603878b44d4ee5c0205e99fa9788e8717b96.zip
FreeBSD-src-9ec6603878b44d4ee5c0205e99fa9788e8717b96.tar.gz
Import of OpenBSD's strtonum(3) which is a nicer version of strtoll(3)
providing proper error checking and other improvements. Obtained from: OpenBSD Requested by: flz (to port Open[BGP|OSPF]D) MFC after: 3 days
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/stdlib/Makefile.inc7
-rw-r--r--lib/libc/stdlib/Symbol.map1
-rw-r--r--lib/libc/stdlib/strtonum.3154
-rw-r--r--lib/libc/stdlib/strtonum.c68
4 files changed, 227 insertions, 3 deletions
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index 29bd492..27eee7d 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -10,8 +10,8 @@ MISRCS+=_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c malloc.c \
merge.c putenv.c qsort.c qsort_r.c radixsort.c rand.c random.c \
reallocf.c realpath.c remque.c setenv.c strfmon.c strtoimax.c \
- strtol.c strtoll.c strtoq.c strtoul.c strtoull.c strtoumax.c strtouq.c \
- system.c tdelete.c tfind.c tsearch.c twalk.c
+ strtol.c strtoll.c strtoq.c strtoul.c strtonum.c strtoull.c strtoumax.c \
+ strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c
SYM_MAPS+= ${.CURDIR}/stdlib/Symbol.map
@@ -25,7 +25,8 @@ MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
lsearch.3 malloc.3 memory.3 posix_memalign.3 qsort.3 radixsort.3 \
rand.3 random.3 \
- realpath.3 strfmon.3 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3
+ realpath.3 strfmon.3 strtod.3 strtol.3 strtonum.3 strtoul.3 system.3 \
+ tsearch.3
MLINKS+=a64l.3 l64a.3 a64l.3 l64a_r.3
MLINKS+=atol.3 atoll.3
diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map
index 2fd2582..2459fe2 100644
--- a/lib/libc/stdlib/Symbol.map
+++ b/lib/libc/stdlib/Symbol.map
@@ -77,6 +77,7 @@ FBSD_1.0 {
strtoimax;
strtol;
strtoll;
+ strtonum;
strtoq;
strtoul;
strtoull;
diff --git a/lib/libc/stdlib/strtonum.3 b/lib/libc/stdlib/strtonum.3
new file mode 100644
index 0000000..73af822
--- /dev/null
+++ b/lib/libc/stdlib/strtonum.3
@@ -0,0 +1,154 @@
+.\" Copyright (c) 2004 Ted Unangst
+.\"
+.\" 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
+.\"
+.\" $OpenBSD: strtonum.3,v 1.12 2005/10/26 11:37:58 jmc Exp $
+.\" $FreeBSD$
+.\"
+.Dd April 29, 2004
+.Dt STRTONUM 3
+.Os
+.Sh NAME
+.Nm strtonum
+.Nd "reliably convert string value to an integer"
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Fd #include <limits.h>
+.Ft long long
+.Fo strtonum
+.Fa "const char *nptr"
+.Fa "long long minval"
+.Fa "long long maxval"
+.Fa "const char **errstr"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn strtonum
+function converts the string in
+.Fa nptr
+to a
+.Li long long
+value.
+The
+.Fn strtonum
+function was designed to facilitate safe, robust programming
+and overcome the shortcomings of the
+.Xr atoi 3
+and
+.Xr strtol 3
+family of interfaces.
+.Pp
+The string may begin with an arbitrary amount of whitespace
+(as determined by
+.Xr isspace 3 )
+followed by a single optional
+.Ql +
+or
+.Ql -
+sign.
+.Pp
+The remainder of the string is converted to a
+.Li long long
+value according to base 10.
+.Pp
+The value obtained is then checked against the provided
+.Fa minval
+and
+.Fa maxval
+bounds.
+If
+.Fa errstr
+is non-null,
+.Fn strtonum
+stores an error string in
+.Fa *errstr
+indicating the failure.
+.Sh RETURN VALUES
+The
+.Fn strtonum
+function returns the result of the conversion,
+unless the value would exceed the provided bounds or is invalid.
+On error, 0 is returned,
+.Va errno
+is set, and
+.Fa errstr
+will point to an error message.
+.Fa *errstr
+will be set to
+.Dv NULL
+on success;
+this fact can be used to differentiate
+a successful return of 0 from an error.
+.Sh EXAMPLES
+Using
+.Fn strtonum
+correctly is meant to be simpler than the alternative functions.
+.Bd -literal -offset indent
+int iterations;
+const char *errstr;
+
+iterations = strtonum(optarg, 1, 64, &errstr);
+if (errstr)
+ errx(1, "number of iterations is %s: %s", errstr, optarg);
+.Ed
+.Pp
+The above example will guarantee that the value of iterations is between
+1 and 64 (inclusive).
+.Sh ERRORS
+.Bl -tag -width Er
+.It Bq Er ERANGE
+The given string was out of range.
+.It Bq Er EINVAL
+The given string did not consist solely of digit characters.
+.It Bq Er EINVAL
+.Ar minval
+was larger than
+.Ar maxval .
+.El
+.Pp
+If an error occurs,
+.Fa errstr
+will be set to one of the following strings:
+.Pp
+.Bl -tag -width "too largeXX" -compact
+.It too large
+The result was larger than the provided maximum value.
+.It too small
+The result was smaller than the provided minimum value.
+.It invalid
+The string did not consist solely of digit characters.
+.El
+.Sh SEE ALSO
+.Xr atof 3 ,
+.Xr atoi 3 ,
+.Xr atol 3 ,
+.Xr atoll 3 ,
+.Xr sscanf 3 ,
+.Xr strtod 3 ,
+.Xr strtol 3 ,
+.Xr strtoul 3
+.Sh STANDARDS
+.Fn strtonum
+is an
+.Ox
+extension.
+The existing alternatives, such as
+.Xr atoi 3
+and
+.Xr strtol 3 ,
+are either impossible or difficult to use safely.
+.Sh HISTORY
+The
+.Fn strtonum
+function first appeared in
+.Ox 3.6 .
diff --git a/lib/libc/stdlib/strtonum.c b/lib/libc/stdlib/strtonum.c
new file mode 100644
index 0000000..0bf29c3
--- /dev/null
+++ b/lib/libc/stdlib/strtonum.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2004 Ted Unangst and Todd Miller
+ * All rights reserved.
+ *
+ * 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
+ *
+ * $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#define INVALID 1
+#define TOOSMALL 2
+#define TOOLARGE 3
+
+long long
+strtonum(const char *numstr, long long minval, long long maxval,
+ const char **errstrp)
+{
+ long long ll = 0;
+ char *ep;
+ int error = 0;
+ struct errval {
+ const char *errstr;
+ int err;
+ } ev[4] = {
+ { NULL, 0 },
+ { "invalid", EINVAL },
+ { "too small", ERANGE },
+ { "too large", ERANGE },
+ };
+
+ ev[0].err = errno;
+ errno = 0;
+ if (minval > maxval)
+ error = INVALID;
+ else {
+ ll = strtoll(numstr, &ep, 10);
+ if (numstr == ep || *ep != '\0')
+ error = INVALID;
+ else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
+ error = TOOSMALL;
+ else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
+ error = TOOLARGE;
+ }
+ if (errstrp != NULL)
+ *errstrp = ev[error].errstr;
+ errno = ev[error].err;
+ if (error)
+ ll = 0;
+
+ return (ll);
+}
OpenPOWER on IntegriCloud