summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2004-05-03 17:09:25 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2004-05-03 17:09:25 +0000
commite90d8f0d9ca5b4228bd1097be477b5d3129fb270 (patch)
tree6f7f95dbe353504810539475d2723127fd34084d
parent5b3c3b153b81205ce727cb14eaf63da746a7b450 (diff)
strtonum, a nicer version of strtoll, by millert and myself.
ok deraadt@ millert@
-rw-r--r--lib/libc/stdlib/Makefile.inc5
-rw-r--r--lib/libc/stdlib/strtonum.3114
-rw-r--r--lib/libc/stdlib/strtonum.c74
3 files changed, 191 insertions, 2 deletions
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index 74f8ff5e7a5..e24eb8d4a5b 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -7,7 +7,8 @@ SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \
calloc.c cfree.c exit.c ecvt.c gcvt.c getenv.c getopt_long.c \
getsubopt.c heapsort.c l64a.c llabs.c lsearch.c malloc.c merge.c \
multibyte.c putenv.c qsort.c radixsort.c rand.c random.c realpath.c \
- setenv.c strtod.c strtol.c strtoll.c strtoul.c strtoull.c system.c \
+ setenv.c strtod.c strtol.c strtoll.c strtonum.c strtoul.c strtoull.c \
+ system.c \
tfind.c tsearch.c _rand48.c drand48.c erand48.c jrand48.c lcong48.c \
lrand48.c mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c
@@ -42,7 +43,7 @@ MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 atoll.3 \
bsearch.3 div.3 ecvt.3 exit.3 getenv.3 getopt.3 getopt_long.3 \
getsubopt.3 insque.3 labs.3 ldiv.3 lsearch.3 malloc.3 qabs.3 \
qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 random.3 realpath.3 \
- strtod.3 strtol.3 strtoul.3 system.3 tsearch.3
+ strtod.3 strtonum.3 strtol.3 strtoul.3 system.3 tsearch.3
MLINKS+=ecvt.3 fcvt.3 ecvt.3 gcvt.3
MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3
diff --git a/lib/libc/stdlib/strtonum.3 b/lib/libc/stdlib/strtonum.3
new file mode 100644
index 00000000000..31aae9075bd
--- /dev/null
+++ b/lib/libc/stdlib/strtonum.3
@@ -0,0 +1,114 @@
+.\" Copyright (c) 1990, 1991 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. 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.
+.\"
+.\" $OpenBSD: strtonum.3,v 1.1 2004/05/03 17:09:24 tedu Exp $
+.\"
+.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 unsigned long long
+.Fo strtonum
+.Fa "const char *nptr"
+.Fa "long long minval"
+.Fa "unsigned long long maxval"
+.Fa "const char **errstr"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn strtonum
+function converts the string in
+.Fa nptr
+to an
+.Li unsigned long long
+value.
+The conversion is done according to base 10.
+Negative values may be obtained by casting the result.
+.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 an
+.Li unsigned long long
+value in the obvious manner,
+stopping at the first character which is not a valid digit
+in the given base.
+.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 *endptr
+indicating the failure.
+.Sh RETURN VALUES
+The
+.Fn strtol
+function returns the result of the conversion,
+unless the value would underflow or overflow.
+On error, 0 is returned.
+.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 a valid number.
+.El
+.Sh SEE ALSO
+.Xr atof 3 ,
+.Xr atoi 3 ,
+.Xr atol 3 ,
+.Xr atoll 3 ,
+.Xr sscanf 3 ,
+.Xr strtol 3 ,
+.Xr strtod 3 ,
+.Xr strtoul 3
+.Sh STANDARDS
+.Fn strtonum
+is an
+.Ox
+extension.
diff --git a/lib/libc/stdlib/strtonum.c b/lib/libc/stdlib/strtonum.c
new file mode 100644
index 00000000000..9ac0d34ee00
--- /dev/null
+++ b/lib/libc/stdlib/strtonum.c
@@ -0,0 +1,74 @@
+/* $OpenBSD: strtonum.c,v 1.1 2004/05/03 17:09:24 tedu Exp $ */
+/*
+ * 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.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#define INVALID 1
+#define TOOSMALL 2
+#define TOOLARGE 3
+
+unsigned long long
+strtonum(const char *numstr, long long minval, unsigned long long maxval,
+ const char **errstrp)
+{
+ unsigned long long ull;
+ char *ep;
+ int error;
+ struct errval {
+ const char *errstr;
+ int errno;
+ } ev[4] = {
+ { NULL, 0 },
+ { "invalid", EINVAL },
+ { "too small", ERANGE },
+ { "too large", ERANGE },
+ };
+
+ ev[0].errno = errno;
+ errno = 0;
+ error = 0;
+ ull = 0;
+ if (minval > maxval || maxval < minval ||
+ (minval < 0 && maxval > LLONG_MAX))
+ error = INVALID;
+ else if (minval >= 0) {
+ ull = strtoull(numstr, &ep, 10);
+ if (numstr == ep || *ep != '\0')
+ error = INVALID;
+ else if ((ull == ULLONG_MAX && errno == ERANGE) || ull > maxval)
+ error = TOOLARGE;
+ } else {
+ long long 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;
+ ull = (unsigned long long)ll;
+ }
+ if (errstrp != NULL)
+ *errstrp = ev[error].errstr;
+ errno = ev[error].errno;
+ if (error)
+ ull = 0;
+
+ return (ull);
+}