]> git.ipfire.org Git - thirdparty/libbsd.git/commitdiff
Add strtonum function
authorGuillem Jover <guillem@hadrons.org>
Sun, 11 Oct 2009 19:07:53 +0000 (21:07 +0200)
committerGuillem Jover <guillem@hadrons.org>
Fri, 23 Oct 2009 23:11:23 +0000 (01:11 +0200)
Taken from FreeBSD.

Makefile
Versions
include/bsd/stdlib.h
man/strtonum.3 [new file with mode: 0644]
src/strtonum.c [new file with mode: 0644]

index 72849414908cfb765036103d398796a1ec91d0b5..46fd0c1d578bcc95b89020ab06c93ce8e9f00110 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -31,6 +31,7 @@ LIB_SRCS := \
        hash/md5.c hash/md5hl.c \
        setmode.c \
        strmode.c \
+       strtonum.c \
        strlcat.c strlcpy.c \
        fmtcheck.c \
        nlist.c \
@@ -62,6 +63,7 @@ LIB_MANS := \
        arc4random.3 \
        arc4random_addrandom.3 \
        arc4random_stir.3 \
+       strtonum.3 \
        strlcpy.3 \
        strlcat.3 \
        fgetln.3 \
index 76d81631bdbb2f288c722a17280557aa9d0192c4..271839d1042a02540071f1c2e2f13ae66af8b9e6 100644 (file)
--- a/Versions
+++ b/Versions
@@ -42,3 +42,7 @@ LIBBSD_0.1 {
     nlist;
 } LIBBSD_0.0;
 
+LIBBSD_0.2 {
+    strtonum;
+} LIBBSD_0.1;
+
index 75f994ad7700d65879a3c7c2daea5bd829220c38..3e1fe83333e3fd6519a9effc72b4d25e2c85cf90 100644 (file)
@@ -47,6 +47,9 @@ int heapsort (void *, size_t, size_t, int (*)(const void *, const void *));
 
 mode_t getmode(const void *set, mode_t mode);
 void *setmode(const char *mode_str);
+
+long long strtonum(const char *nptr, long long minval, long long maxval,
+                   const char **errstr);
 __END_DECLS
 
 #endif
diff --git a/man/strtonum.3 b/man/strtonum.3
new file mode 100644 (file)
index 0000000..90f0b57
--- /dev/null
@@ -0,0 +1,156 @@
+.\" 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
+.In stdlib.h
+.In 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
+.Vt "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
+.Vt "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.
+On success,
+.Fa *errstr
+will be set to
+.Dv NULL ;
+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
+The supplied
+.Fa minval
+was larger than
+.Fa maxval .
+.El
+.Pp
+If an error occurs,
+.Fa errstr
+will be set to one of the following strings:
+.Pp
+.Bl -tag -width ".Li too large" -compact
+.It Li "too large"
+The result was larger than the provided maximum value.
+.It Li "too small"
+The result was smaller than the provided minimum value.
+.It Li 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
+The
+.Fn strtonum
+function is a
+.Bx
+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/src/strtonum.c b/src/strtonum.c
new file mode 100644 (file)
index 0000000..6dccd97
--- /dev/null
@@ -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 (errno == EINVAL || 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);
+}