From e13b1a337a608c3301ccb9ea344b6f97279a818f Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Mon, 21 May 2018 00:20:49 +0200 Subject: [PATCH] Import strtoi() and strtou() functions from NetBSD --- COPYING | 6 +- include/Makefile.am | 1 + include/bsd/inttypes.h | 49 +++++++++ man/Makefile.am | 2 + man/libbsd.7 | 3 + man/strtoi.3bsd | 238 +++++++++++++++++++++++++++++++++++++++++ man/strtou.3bsd | 238 +++++++++++++++++++++++++++++++++++++++++ src/Makefile.am | 2 + src/libbsd.map | 3 + src/strtoi.c | 97 +++++++++++++++++ src/strtou.c | 97 +++++++++++++++++ 11 files changed, 735 insertions(+), 1 deletion(-) create mode 100644 include/bsd/inttypes.h create mode 100644 man/strtoi.3bsd create mode 100644 man/strtou.3bsd create mode 100644 src/strtoi.c create mode 100644 src/strtou.c diff --git a/COPYING b/COPYING index 4377959..10fb229 100644 --- a/COPYING +++ b/COPYING @@ -3,7 +3,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Files: * Copyright: - Copyright © 2004-2006, 2008-2017 Guillem Jover + Copyright © 2004-2006, 2008-2018 Guillem Jover License: BSD-3-clause Files: @@ -110,6 +110,8 @@ Files: man/setmode.3bsd man/strmode.3bsd man/strnstr.3bsd + man/strtoi.3bsd + man/strtou.3bsd man/unvis.3bsd man/vis.3bsd man/wcslcpy.3bsd @@ -121,6 +123,8 @@ Files: src/setmode.c src/strmode.c src/strnstr.c + src/strtoi.c + src/strtou.c src/unvis.c Copyright: Copyright © 1980, 1982, 1986, 1989-1994 diff --git a/include/Makefile.am b/include/Makefile.am index 6c74b44..ce3f058 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -13,6 +13,7 @@ nobase_include_HEADERS = \ bsd/bsd.h \ bsd/err.h \ bsd/getopt.h \ + bsd/inttypes.h \ bsd/libutil.h \ bsd/md5.h \ bsd/nlist.h \ diff --git a/include/bsd/inttypes.h b/include/bsd/inttypes.h new file mode 100644 index 0000000..a2b89f7 --- /dev/null +++ b/include/bsd/inttypes.h @@ -0,0 +1,49 @@ +/* + * Copyright © 2018 Guillem Jover + * + * 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. 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. + */ + +#ifdef LIBBSD_OVERLAY +#include_next +#else +#include +#endif + +#ifndef LIBBSD_INTTYPES_H +#define LIBBSD_INTTYPES_H + +#ifdef LIBBSD_OVERLAY +#include +#else +#include +#endif + +__BEGIN_DECLS +intmax_t strtoi(const char *__restrict nptr, char **__restrict endptr, + int base, intmax_t lo, intmax_t hi, int *rstatus); +uintmax_t strtou(const char *__restrict nptr, char **__restrict endptr, + int base, uintmax_t lo, uintmax_t hi, int *rstatus); +__END_DECLS + +#endif diff --git a/man/Makefile.am b/man/Makefile.am index 28192c0..26e893a 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -212,7 +212,9 @@ dist_man_MANS = \ strnstr.3bsd \ strnunvis.3bsd \ strnvis.3bsd \ + strtoi.3bsd \ strtonum.3bsd \ + strtou.3bsd \ strunvis.3bsd \ strvis.3bsd \ strvisx.3bsd \ diff --git a/man/libbsd.7 b/man/libbsd.7 index ea2d281..0521f93 100644 --- a/man/libbsd.7 +++ b/man/libbsd.7 @@ -94,6 +94,7 @@ be prefixed with .It In bitstring.h .It In err.h .It In getopt.h +.It In inttypes.h .It In libutil.h .It In md5.h .It In netinet/ip_icmp.h @@ -214,7 +215,9 @@ This function is provided by .Xr strlcpy 3bsd , .Xr strmode 3bsd , .Xr strnstr 3bsd , +.Xr strtoi 3bsd , .Xr strtonum 3bsd , +.Xr strtou 3bsd , .Xr timeradd 3bsd , .Xr timeval 3bsd , .Xr tree 3bsd , diff --git a/man/strtoi.3bsd b/man/strtoi.3bsd new file mode 100644 index 0000000..273d336 --- /dev/null +++ b/man/strtoi.3bsd @@ -0,0 +1,238 @@ +.\" $NetBSD: strtoi.3,v 1.7 2017/07/03 21:32:50 wiz Exp $ +.\" +.\" Copyright (c) 1990, 1991, 1993 +.\" 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. +.\" +.\" from: @(#)strtol.3 8.1 (Berkeley) 6/4/93 +.\" +.\" Created by Kamil Rytarowski, based on ID: +.\" NetBSD: strtol.3,v 1.31 2015/03/11 09:57:35 wiz Exp +.\" +.Dd November 13, 2015 +.Dt STRTOI 3bsd +.Os +.Sh NAME +.Nm strtoi +.Nd convert string value to an intmax_t integer +.Sh LIBRARY +.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd) +.Lb libbsd +.Sh SYNOPSIS +.In inttypes.h +(See +.Xr libbsd 7 +for include usage.) +.Ft intmax_t +.Fo strtoi +.Fa "const char * restrict nptr" +.Fa "char ** restrict endptr" +.Fa "int base" +.Fa "intmax_t lo" +.Fa "intmax_t hi" +.Fa "int *rstatus" +.Fc +.Sh DESCRIPTION +The +.Fn strtoi +function +converts the string in +.Fa nptr +to an +.Ft intmax_t +value. +The +.Fn strtoi +function uses internally +.Xr strtoimax 3 +and ensures that the result is always in the range [ +.Fa lo .. +.Fa hi +]. +In adddition it always places +.Dv 0 +on success or a conversion status in the +.Fa rstatus +argument, avoiding the +.Dv errno +gymnastics the other functions require. +The +.Fa rstatus +argument can be +.Dv NULL +if conversion status is to be ignored. +.Pp +The string may begin with an arbitrary amount of white space +(as determined by +.Xr isspace 3 ) +followed by a single optional +.Ql + +or +.Ql - +sign. +If +.Fa base +is zero or 16, +the string may then include a +.Ql 0x +or +.Ql 0X +prefix, +and the number will be read in base 16; otherwise, +.\" if the +.\" .Fa base +.\" is zero or 2, +.\" the string may then include a +.\" .Ql 0b +.\" or +.\" .Ql 0B +.\" prefix, +.\" and the number will be read in base 2; otherwise, +a zero +.Fa base +is taken as 10 (decimal) unless the next character is +.Ql 0 , +in which case it is taken as 8 (octal). +.Pp +The remainder of the string is converted to a +.Em intmax_t +value in the obvious manner, +stopping at the first character which is not a valid digit +in the given base. +(In bases above 10, the letter +.Ql A +in either upper or lower case +represents 10, +.Ql B +represents 11, and so forth, with +.Ql Z +representing 35.) +.Pp +If +.Fa endptr +is non-nil, +.Fn strtoi +stores the address of the first invalid character in +.Fa *endptr . +If there were no digits at all, however, +.Fn strtoi +stores the original value of +.Fa nptr +in +.Fa *endptr . +(Thus, if +.Fa *nptr +is not +.Ql \e0 +but +.Fa **endptr +is +.Ql \e0 +on return, the entire string was valid.) +.Sh RETURN VALUES +The +.Fn strtoi +function +always returns the closest value in the range specified by +the +.Fa lo +and +.Fa hi +arguments. +.Pp +The +.Va errno +value is guaranteed to be left unchanged. +.Pp +Errors are stored as the conversion status in the +.Fa rstatus +argument. +.Sh EXAMPLES +The following example will always return a number in +.Dv [1..99] +range no matter what the input is, and warn if the conversion failed. +.Bd -literal -offset indent +int e; +intmax_t lval = strtoi(buf, NULL, 0, 1, 99, &e); +if (e) + warnc(e, "conversion of `%s' to a number failed, using %jd", + buf, lval); +.Ed +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er ECANCELED +The string did not contain any characters that were converted. +.It Bq Er EINVAL +The +.Ar base +is not between 2 and 36 and does not contain the special value 0. +.It Bq Er ENOTSUP +The string contained non-numeric characters that did not get converted. +In this case, +.Fa endptr +points to the first unconverted character. +.It Bq Er ERANGE +The given string was out of range; the value converted has been clamped; +or the range given was invalid, i.e. +.Fa lo +> +.Fa hi . +.El +.Sh SEE ALSO +.Xr atof 3 , +.Xr atoi 3 , +.Xr atol 3 , +.Xr atoll 3 , +.Xr strtod 3 , +.Xr strtoimax 3 , +.Xr strtol 3 , +.Xr strtoll 3 , +.Xr strtou 3bsd , +.Xr strtoul 3 , +.Xr strtoull 3 , +.Xr strtoumax 3 +.Sh STANDARDS +The +.Fn strtoi +function is a +.Nx +extension. +.Sh HISTORY +The +.Fn strtoi +function first appeared in +.Nx 7 . +.Ox +introduced the +.Fn strtonum 3bsd +function for the same purpose, but the interface makes it impossible to +properly differentiate illegal returns. +.Sh BUGS +Ignores the current locale. diff --git a/man/strtou.3bsd b/man/strtou.3bsd new file mode 100644 index 0000000..fc0f901 --- /dev/null +++ b/man/strtou.3bsd @@ -0,0 +1,238 @@ +.\" $NetBSD: strtou.3,v 1.7 2017/07/03 21:32:50 wiz Exp $ +.\" +.\" Copyright (c) 1990, 1991, 1993 +.\" 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. +.\" +.\" from: @(#)strtoul.3 8.1 (Berkeley) 6/4/93 +.\" +.\" Created by Kamil Rytarowski, based on ID: +.\" NetBSD: strtoul.3,v 1.29 2015/03/10 13:00:58 christos Exp +.\" +.Dd November 13, 2015 +.Dt STRTOU 3bsd +.Os +.Sh NAME +.Nm strtou +.Nd convert a string to an uintmax_t integer +.Sh LIBRARY +.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd) +.Lb libbsd +.Sh SYNOPSIS +.In inttypes.h +(See +.Xr libbsd 7 +for include usage.) +.Ft uintmax_t +.Fo strtou +.Fa "const char * restrict nptr" +.Fa "char ** restrict endptr" +.Fa "int base" +.Fa "uintmax_t lo" +.Fa "uintmax_t hi" +.Fa "int *rstatus" +.Fc +.Sh DESCRIPTION +The +.Fn strtou +function converts the string in +.Fa nptr +to an +.Ft uintmax_t +value. +The +.Fn strtou +function uses internally +.Xr strtoumax 3 +and ensures that the result is always in the range [ +.Fa lo .. +.Fa hi +]. +In adddition it always places +.Dv 0 +on success or a conversion status in the +.Fa rstatus +argument, avoiding the +.Dv errno +gymnastics the other functions require. +The +.Fa rstatus +argument can be +.Dv NULL +if conversion status is to be ignored. +.Pp +The string may begin with an arbitrary amount of white space +(as determined by +.Xr isspace 3 ) +followed by a single optional +.Ql + +or +.Ql - +sign. +If +.Fa base +is zero or 16, +the string may then include a +.Ql 0x +or +.Ql 0X +prefix, +and the number will be read in base 16; otherwise, +.\" if the +.\" .Fa base +.\" is zero or 2, +.\" the string may then include a +.\" .Ql 0b +.\" or +.\" .Ql 0B +.\" prefix, +.\" and the number will be read in base 2; otherwise, +a zero +.Fa base +is taken as 10 (decimal) unless the next character is +.Ql 0 , +in which case it is taken as 8 (octal). +.Pp +The remainder of the string is converted to an +.Em uintmax_t +value in the obvious manner, +stopping at the end of the string +or at the first character that does not produce a valid digit +in the given base. +(In bases above 10, the letter +.Ql A +in either upper or lower case +represents 10, +.Ql B +represents 11, and so forth, with +.Ql Z +representing 35.) +.Pp +If +.Fa endptr +is non-nil, +.Fn strtou +stores the address of the first invalid character in +.Fa *endptr . +If there were no digits at all, however, +.Fn strtou +stores the original value of +.Fa nptr +in +.Fa *endptr . +(Thus, if +.Fa *nptr +is not +.Ql \e0 +but +.Fa **endptr +is +.Ql \e0 +on return, the entire string was valid.) +.Sh RETURN VALUES +The +.Fn strtou +function +always returns the closest value in the range specified by +the +.Fa lo +and +.Fa hi +arguments. +.Pp +The +.Va errno +value is guaranteed to be left unchanged. +.Pp +Errors are stored as the conversion status in the +.Fa rstatus +argument. +.Sh EXAMPLES +The following example will always return a number in +.Dv [1..99] +range no matter what the input is, and warn if the conversion failed. +.Bd -literal -offset indent +int e; +uintmax_t lval = strtou(buf, NULL, 0, 1, 99, &e); +if (e) + warnc(e, "conversion of `%s' to a number failed, using %ju", + buf, lval); +.Ed +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er ECANCELED +The string did not contain any characters that were converted. +.It Bq Er EINVAL +The +.Ar base +is not between 2 and 36 and does not contain the special value 0. +.It Bq Er ENOTSUP +The string contained non-numeric characters that did not get converted. +In this case, +.Fa endptr +points to the first unconverted character. +.It Bq Er ERANGE +The given string was out of range; the value converted has been clamped; or +the range given was invalid, i.e. +.Fa lo +> +.Fa hi . +.El +.Sh SEE ALSO +.Xr atof 3 , +.Xr atoi 3 , +.Xr atol 3 , +.Xr atoll 3 , +.Xr strtod 3 , +.Xr strtoi 3bsd , +.Xr strtoimax 3 , +.Xr strtol 3 , +.Xr strtoll 3 , +.Xr strtoul 3 , +.Xr strtoull 3 , +.Xr strtoumax 3 +.Sh STANDARDS +The +.Fn strtou +function is a +.Nx +extension. +.Sh HISTORY +The +.Fn strtou +function first appeared in +.Nx 7 . +.Ox +introduced the +.Fn strtonum 3bsd +function for the same purpose, but the interface makes it impossible to +properly differentiate illegal returns. +.Sh BUGS +Ignores the current locale. diff --git a/src/Makefile.am b/src/Makefile.am index d72802e..d85dc69 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -104,7 +104,9 @@ libbsd_la_SOURCES = \ stringlist.c \ strmode.c \ strnstr.c \ + strtoi.c \ strtonum.c \ + strtou.c \ timeconv.c \ unvis.c \ vis.c \ diff --git a/src/libbsd.map b/src/libbsd.map index a91d522..98b95ce 100644 --- a/src/libbsd.map +++ b/src/libbsd.map @@ -145,6 +145,9 @@ LIBBSD_0.9 { pidfile_fileno; + strtoi; + strtou; + nvis; snvis; stravis; diff --git a/src/strtoi.c b/src/strtoi.c new file mode 100644 index 0000000..9e3771d --- /dev/null +++ b/src/strtoi.c @@ -0,0 +1,97 @@ +/* $NetBSD: _strtoi.h,v 1.2 2015/01/18 17:55:22 christos Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. 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. + * + * Original version ID: + * NetBSD: src/lib/libc/locale/_wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp + * + * Created by Kamil Rytarowski, based on ID: + * NetBSD: src/common/lib/libc/stdlib/_strtoul.h,v 1.7 2013/05/17 12:55:56 joe… + */ + +#include + +#include +#include +#include +#include + +#define _DIAGASSERT(t) + +intmax_t +strtoi(const char *__restrict nptr, + char **__restrict endptr, int base, + intmax_t lo, intmax_t hi, int *rstatus) +{ + int serrno; + intmax_t im; + char *ep; + int rep; + + _DIAGASSERT(hi >= lo); + + _DIAGASSERT(nptr != NULL); + /* endptr may be NULL */ + + if (endptr == NULL) + endptr = &ep; + + if (rstatus == NULL) + rstatus = &rep; + + serrno = errno; + errno = 0; + + im = strtoimax(nptr, endptr, base); + + *rstatus = errno; + errno = serrno; + + if (*rstatus == 0) { + /* No digits were found */ + if (nptr == *endptr) + *rstatus = ECANCELED; + /* There are further characters after number */ + else if (**endptr != '\0') + *rstatus = ENOTSUP; + } + + if (im < lo) { + if (*rstatus == 0) + *rstatus = ERANGE; + return lo; + } + if (im > hi) { + if (*rstatus == 0) + *rstatus = ERANGE; + return hi; + } + + return im; +} diff --git a/src/strtou.c b/src/strtou.c new file mode 100644 index 0000000..0e22a88 --- /dev/null +++ b/src/strtou.c @@ -0,0 +1,97 @@ +/* $NetBSD: _strtoi.h,v 1.2 2015/01/18 17:55:22 christos Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. 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. + * + * Original version ID: + * NetBSD: src/lib/libc/locale/_wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp + * + * Created by Kamil Rytarowski, based on ID: + * NetBSD: src/common/lib/libc/stdlib/_strtoul.h,v 1.7 2013/05/17 12:55:56 joe… + */ + +#include + +#include +#include +#include +#include + +#define _DIAGASSERT(t) + +uintmax_t +strtou(const char *__restrict nptr, + char **__restrict endptr, int base, + uintmax_t lo, uintmax_t hi, int *rstatus) +{ + int serrno; + uintmax_t im; + char *ep; + int rep; + + _DIAGASSERT(hi >= lo); + + _DIAGASSERT(nptr != NULL); + /* endptr may be NULL */ + + if (endptr == NULL) + endptr = &ep; + + if (rstatus == NULL) + rstatus = &rep; + + serrno = errno; + errno = 0; + + im = strtoumax(nptr, endptr, base); + + *rstatus = errno; + errno = serrno; + + if (*rstatus == 0) { + /* No digits were found */ + if (nptr == *endptr) + *rstatus = ECANCELED; + /* There are further characters after number */ + else if (**endptr != '\0') + *rstatus = ENOTSUP; + } + + if (im < lo) { + if (*rstatus == 0) + *rstatus = ERANGE; + return lo; + } + if (im > hi) { + if (*rstatus == 0) + *rstatus = ERANGE; + return hi; + } + + return im; +}