From b1eca6d665fc82eead745c49be9c7ccb27719483 Mon Sep 17 00:00:00 2001 From: Aditya Upadhyay Date: Wed, 14 Jun 2017 00:26:39 +0530 Subject: [PATCH] Porting the methods declared inside inttypes.h from freebsd. --- newlib/libc/Makefile.am | 4 +- newlib/libc/inttypes/Makefile.am | 24 +++++++ newlib/libc/inttypes/imaxabs.c | 44 ++++++++++++ newlib/libc/inttypes/imaxdiv.c | 53 ++++++++++++++ newlib/libc/inttypes/strtoimax.c | 144 +++++++++++++++++++++++++++++++++++++ newlib/libc/inttypes/strtoumax.c | 135 ++++++++++++++++++++++++++++++++++ newlib/libc/inttypes/wcstoimax.c | 151 +++++++++++++++++++++++++++++++++++++++ newlib/libc/inttypes/wcstoumax.c | 144 +++++++++++++++++++++++++++++++++++++ 8 files changed, 698 insertions(+), 1 deletion(-) create mode 100644 newlib/libc/inttypes/Makefile.am create mode 100644 newlib/libc/inttypes/imaxabs.c create mode 100644 newlib/libc/inttypes/imaxdiv.c create mode 100644 newlib/libc/inttypes/strtoimax.c create mode 100644 newlib/libc/inttypes/strtoumax.c create mode 100644 newlib/libc/inttypes/wcstoimax.c create mode 100644 newlib/libc/inttypes/wcstoumax.c diff --git a/newlib/libc/Makefile.am b/newlib/libc/Makefile.am index 6e97bca..640c95e 100644 --- a/newlib/libc/Makefile.am +++ b/newlib/libc/Makefile.am @@ -41,7 +41,7 @@ endif # The order of SUBDIRS is important for the integrated documentation. # Do not change the order without considering the doc impact. SUBDIRS = argz stdlib ctype search $(STDIO_SUBDIR) $(STDIO64_SUBDIR) string $(SIGNAL_SUBDIR) time locale sys reent \ - $(extra_dir) errno misc machine $(UNIX_SUBDIR) $(POSIX_SUBDIR) $(SYSCALLS_SUBDIR) $(NEWLIB_ICONV_DIRS) \ + $(extra_dir) errno misc inttypes machine $(UNIX_SUBDIR) $(POSIX_SUBDIR) $(SYSCALLS_SUBDIR) $(NEWLIB_ICONV_DIRS) \ $(XDR_SUBDIR) . noinst_DATA = $(CRT0) @@ -64,6 +64,7 @@ SUBLIBS = \ $(LIBC_EXTRA_LIB) \ errno/liberrno.$(aext) \ misc/libmisc.$(aext) \ + inttypes/libinttypes.$(aext)\ $(LIBC_UNIX_LIB) \ $(LIBC_POSIX_LIB) \ $(LIBC_SYSCALL_LIB) \ @@ -87,6 +88,7 @@ SUBLIBS = \ $(LIBC_EXTRA_LIB) \ errno/lib.$(aext) \ misc/lib.$(aext) \ + inttypes/lib.$(aext)\ $(LIBC_UNIX_LIB) \ $(LIBC_POSIX_LIB) \ $(LIBC_SYSCALL_LIB) \ diff --git a/newlib/libc/inttypes/Makefile.am b/newlib/libc/inttypes/Makefile.am new file mode 100644 index 0000000..db73934 --- /dev/null +++ b/newlib/libc/inttypes/Makefile.am @@ -0,0 +1,24 @@ +## Process this file with automake to generate Makefile.in + +AUTOMAKE_OPTIONS = cygnus + +INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) + +LIB_SOURCES = imaxabs.c imaxdiv.c strtoimax.c strtoumax.c wcstoimax.c wcstoumax.c + +libinttypes_la_LDFLAGS = -Xcompiler -nostdlib + +if USE_LIBTOOL +noinst_LTLIBRARIES = libinttypes.la +libinttypes_la_SOURCES = $(LIB_SOURCES) +noinst_DATA = objectlist.awk.in +else +noinst_LIBRARIES = lib.a +lib_a_SOURCES = $(LIB_SOURCES) +lib_a_CFLAGS = $(AM_CFLAGS) +noinst_DATA = +endif # USE_LIBTOOL + +include $(srcdir)/../../Makefile.shared + + diff --git a/newlib/libc/inttypes/imaxabs.c b/newlib/libc/inttypes/imaxabs.c new file mode 100644 index 0000000..e803869 --- /dev/null +++ b/newlib/libc/inttypes/imaxabs.c @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2001 Mike Barcroft + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* intmax_t data type defined here */ + +#include +#include + +#include + + +intmax_t +imaxabs( + intmax_t j) +{ + return (j < 0 ? -j : j); +} diff --git a/newlib/libc/inttypes/imaxdiv.c b/newlib/libc/inttypes/imaxdiv.c new file mode 100644 index 0000000..aabad09 --- /dev/null +++ b/newlib/libc/inttypes/imaxdiv.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2001 Mike Barcroft + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* intmax_t data type defined here */ + +#include + +#include + +imaxdiv_t +imaxdiv( + intmax_t numer, intmax_t denom) +{ + imaxdiv_t retval; + + retval.quot = numer / denom; + retval.rem = numer % denom; + + #if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) + if (numer >= 0 && retval.rem < 0) { + retval.quot++; + retval.rem -= denom; + } + #endif + return (retval); +} diff --git a/newlib/libc/inttypes/strtoimax.c b/newlib/libc/inttypes/strtoimax.c new file mode 100644 index 0000000..092a2a9 --- /dev/null +++ b/newlib/libc/inttypes/strtoimax.c @@ -0,0 +1,144 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +/* + * This source code was extracted from the Q8 package created and + * placed in the PUBLIC DOMAIN by Doug Gwyn + * last edit: 1999/11/05 gwyn@arl.mil + * + * Implements subclause 7.8.2 of ISO/IEC 9899:1999 (E). + * + * This particular implementation requires the matching . + * It also assumes that character codes for A..Z and a..z are in + * contiguous ascending order; this is true for ASCII but not EBCDIC. + */ + +#include +#include +#include +#include + +/* Helper macros */ + +/* convert digit character to number, in any base */ + +#define ToNumber(c) (isdigit(c) ? (c) - '0' : \ + isupper(c) ? (c) - 'A' + 10 : \ + islower(c) ? (c) - 'a' + 10 : \ + -1 /* "invalid" flag */ \ + ) +/* validate converted digit character for specific base */ + +#define valid(n, b) ((n) >= 0 && (n) < (b)) + +intmax_t +strtoimax( + nptr, endptr, base) + register const char * __restrict__ nptr; + char ** __restrict__ endptr; + register int base; +{ + register uintmax_t accum; + register int n; + int minus; + int toobig; + + /* in case no conversion's performed */ + + if (endptr != NULL) + *endptr = (char *)nptr; + + /* unspecified behavior */ + + if (base < 0 || base == 1 || base > 36){ + errno = EDOM; + return 0; + } + + /* skip initial, possibly empty sequence of white-space characters */ + + while (isspace(*nptr)) + ++nptr; + + /* process subject sequence: */ + + /* optional sign */ + + if ((minus = *nptr == '-') || *nptr == '+') + ++nptr; + + if (base == 0) { + if (*nptr == '0') { + if (nptr[1] == 'X' || nptr[1] == 'x'){ + base = 16; + }else{ + base = 8; + } + }else{ + base = 10; + } + + } + + /* optional "0x" or "0X" for base 16 */ + + /* skip past this prefix */ + + if (base == 16 && *nptr == '0' && (nptr[1] == 'X' || nptr[1] == 'x')) + nptr += 2; + + /* check whether there is at least one valid digit */ + + n = ToNumber(*nptr); + ++nptr; + + /* subject seq. not of expected form */ + + if (!valid(n, base)) + return 0; + + accum = n; + + for (toobig = 0; n = ToNumber(*nptr), valid(n, base); ++nptr) + + /* major wrap-around */ + + if (accum > (uintmax_t)(INTMAX_MAX / base + 2)) + + /* but keep scanning */ + + toobig = 1; + else + accum = base * accum + n; + + /* points to first not-valid-digit */ + + if (endptr != NULL) + *endptr = (char *)nptr; + + if (minus){ + if (accum > (uintmax_t)INTMAX_MAX + 1) + toobig = 1; + } + else + if (accum > (uintmax_t)INTMAX_MAX) + toobig = 1; + + if (toobig){ + errno = ERANGE; + return minus ? INTMAX_MIN : INTMAX_MAX; + } + else + return (intmax_t)(minus ? -accum : accum); +} + +long long __attribute__ ( +(alias ("strtoimax"))) + +strtoll ( +const char* __restrict__ nptr, +char ** __restrict__ endptr, int base ); + diff --git a/newlib/libc/inttypes/strtoumax.c b/newlib/libc/inttypes/strtoumax.c new file mode 100644 index 0000000..48c818b --- /dev/null +++ b/newlib/libc/inttypes/strtoumax.c @@ -0,0 +1,135 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +/* + * This source code was extracted from the Q8 package created and + * placed in the PUBLIC DOMAIN by Doug Gwyn + * last edit: 1999/11/05 gwyn@arl.mil + * + * Implements subclause 7.8.2 of ISO/IEC 9899:1999 (E). + * + * This particular implementation requires the matching . + * It also assumes that character codes for A..Z and a..z are in + * contiguous ascending order; this is true for ASCII but not EBCDIC. +*/ + +#include +#include +#include +#include + +/* Helper macros */ + +/* convert digit character to number, in any base */ + +#define ToNumber(c) (isdigit(c) ? (c) - '0' : \ + isupper(c) ? (c) - 'A' + 10 : \ + islower(c) ? (c) - 'a' + 10 : \ + -1 /* "invalid" flag */ \ + ) +/* validate converted digit character for specific base */ + +#define valid(n, b) ((n) >= 0 && (n) < (b)) + +uintmax_t +strtoumax( + nptr, endptr, base) + register const char * __restrict__ nptr; + char ** __restrict__ endptr; + register int base; +{ + register uintmax_t accum; + register uintmax_t next; + register int n; + int minus; + int toobig; + + /* in case no conversion's performed */ + + if ( endptr != NULL ) + *endptr = (char *)nptr; + + /* unspecified behavior */ + + if ( base < 0 || base == 1 || base > 36 ){ + errno = EDOM; + return 0; + } + + /* skip initial, possibly empty sequence of white-space characters */ + + while ( isspace(*nptr) ) + ++nptr; + + /* process subject sequence: */ + + /* optional sign (yes!) */ + + if ((minus = *nptr == '-') || *nptr == '+') + ++nptr; + + if (base == 0){ + if (*nptr == '0'){ + if (nptr[1] == 'X' || nptr[1] == 'x') + base = 16; + else + base = 8; + } + else + base = 10; + } + + /* optional "0x" or "0X" for base 16 */ + + if (base == 16 && *nptr == '0' && (nptr[1] == 'X' || nptr[1] == 'x')) + + /* skip past this prefix */ + + nptr += 2; + + /* check whether there is at least one valid digit */ + + n = ToNumber(*nptr); + ++nptr; + + /* subject seq. not of expected form */ + + if ( !valid(n, base) ) + return 0; + + accum = n; + + for ( toobig = 0; n = ToNumber(*nptr), valid(n, base); ++nptr ) + + /* major wrap-around and minor wrap-around */ + + if (accum > UINTMAX_MAX / base + 1 || (next = base * accum + n) < accum) + + /* but keep scanning */ + + toobig = 1; + else + accum = next; + + /* points to first not-valid-digit */ + + if (endptr != NULL) + *endptr = (char *)nptr; + + if (toobig){ + errno = ERANGE; + return UINTMAX_MAX; + } + else + return minus ? -accum : accum; /* (yes!) */ +} + +unsigned long long + __attribute__ ( + (alias ("strtoumax"))) +strtoull (const char* __restrict__ nptr, + char ** __restrict__ endptr, int base); + diff --git a/newlib/libc/inttypes/wcstoimax.c b/newlib/libc/inttypes/wcstoimax.c new file mode 100644 index 0000000..4ec0e91 --- /dev/null +++ b/newlib/libc/inttypes/wcstoimax.c @@ -0,0 +1,151 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +/* + * This source code was extracted from the Q8 package created and + * placed in the PUBLIC DOMAIN by Doug Gwyn + * last edit: 1999/11/05 gwyn@arl.mil + * Implements subclause 7.8.2 of ISO/IEC 9899:1999 (E). + * This particular implementation requires the matching . + * It also assumes that character codes for A..Z and a..z are in + * contiguous ascending order; this is true for ASCII but not EBCDIC. +*/ + +#include +#include +#include +#include + +/* convert digit wide character to number, in any base */ + +#define ToWNumber(c) (iswdigit(c) ? (c) - L'0' : \ + iswupper(c) ? (c) - L'A' + 10 : \ + iswlower(c) ? (c) - L'a' + 10 : \ + -1 /* "invalid" flag */ \ + ) + +/* validate converted digit character for specific base */ + +#define valid(n, b) ((n) >= 0 && (n) < (b)) + +intmax_t +wcstoimax( + nptr, endptr, base) + register const wchar_t * __restrict__ nptr; + wchar_t ** __restrict__ endptr; + register int base; +{ + /* accumulates converted value */ + + register uintmax_t accum; + + /* numeral from digit character */ + + register int n; + + /* set iff minus sign seen */ + + int minus; + + /* set iff value overflows */ + + int toobig; + + /* in case no conv performed */ + + if (endptr != NULL) + *endptr = (wchar_t *)nptr; + + /* unspecified behavior */ + + if (base < 0 || base == 1 || base > 36){ + errno = EDOM; + return 0; + } + + /* skip initial, possibly empty sequence of white-space w.characters */ + + while (iswspace(*nptr)) + ++nptr; + + /* process subject sequence: */ + + /* optional sign */ + + if ((minus = *nptr == L'-') || *nptr == L'+') + ++nptr; + + if (base == 0){ + if (*nptr == L'0'){ + if (nptr[1] == L'X' || nptr[1] == L'x') + base = 16; + else + base = 8; + } + else + base = 10; + } + + /* optional "0x" or "0X" for base 16 */ + + if ( base == 16 && *nptr == L'0' && (nptr[1] == L'X' || nptr[1] == L'x')) + + /* skip past this prefix */ + + nptr += 2; + + /* check whether there is at least one valid digit */ + + n = ToWNumber(*nptr); + ++nptr; + + /* subject seq. not of expected form */ + + if (!valid(n, base)) + return 0; + + accum = n; + + for (toobig = 0; n = ToWNumber(*nptr), valid(n, base); ++nptr) + + /* major wrap-around */ + + if (accum > (uintmax_t)(INTMAX_MAX / base + 2)) + + /* but keep scanning */ + + toobig = 1; + else + accum = base * accum + n; + + /* -> first not-valid-digit */ + + if (endptr != NULL) + *endptr = (wchar_t *)nptr; + + if (minus){ + if (accum > (uintmax_t)INTMAX_MAX + 1) + toobig = 1; + } + else + if (accum > (uintmax_t)INTMAX_MAX) + toobig = 1; + + if (toobig){ + errno = ERANGE; + return minus ? INTMAX_MIN : INTMAX_MAX; + } + else + return (intmax_t)(minus ? -accum : accum); +} + +long long +__attribute__ ( + (alias ("wcstoimax"))) +wcstoll ( + const wchar_t* __restrict__ nptr, + wchar_t ** __restrict__ endptr, int base); + diff --git a/newlib/libc/inttypes/wcstoumax.c b/newlib/libc/inttypes/wcstoumax.c new file mode 100644 index 0000000..890126e --- /dev/null +++ b/newlib/libc/inttypes/wcstoumax.c @@ -0,0 +1,144 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +/* + * This source code was extracted from the Q8 package created and + * placed in the PUBLIC DOMAIN by Doug Gwyn + * last edit: 1999/11/05 gwyn@arl.mil + * Implements subclause 7.8.2 of ISO/IEC 9899:1999 (E). + * This particular implementation requires the matching . + * It also assumes that character codes for A..Z and a..z are in + * contiguous ascending order; this is true for ASCII but not EBCDIC. +*/ + +#include +#include +#include +#include + +/* convert digit wide character to number, in any base */ + +#define ToWNumber(c) (iswdigit(c) ? (c) - L'0' : \ + iswupper(c) ? (c) - L'A' + 10 : \ + iswlower(c) ? (c) - L'a' + 10 : \ + -1 /* "invalid" flag */ \ + ) + +/* validate converted digit character for specific base */ +#define valid(n, b) ((n) >= 0 && (n) < (b)) + +uintmax_t +wcstoumax( + nptr, endptr, base) + register const wchar_t * __restrict__ nptr; + wchar_t ** __restrict__ endptr; + register int base; +{ + /* accumulates converted value */ + + register uintmax_t accum, next; + + /* numeral from digit character */ + + register int n; + + /* set iff minus sign seen */ + + int minus; + + /* set iff value overflows */ + + int toobig; + + /* in case no conv performed */ + + if (endptr != NULL) + *endptr = (wchar_t *)nptr; + + /* unspecified behavior */ + + if (base < 0 || base == 1 || base > 36){ + errno = EDOM; + return 0; + } + + + /* skip initial, possibly empty sequence of white-space w.characters */ + + while (iswspace(*nptr)) + ++nptr; + + /* process subject sequence: */ + + /* optional sign */ + + if ((minus = *nptr == L'-') || *nptr == L'+') + ++nptr; + + if (base == 0){ + if (*nptr == L'0'){ + if (nptr[1] == L'X' || nptr[1] == L'x') + base = 16; + else + base = 8; + } + else + base = 10; + } + + /* optional "0x" or "0X" for base 16 */ + + if ( base == 16 && *nptr == L'0' && (nptr[1] == L'X' || nptr[1] == L'x')) + + /* skip past this prefix */ + + nptr += 2; + + /* check whether there is at least one valid digit */ + + n = ToWNumber(*nptr); + ++nptr; + + /* subject seq. not of expected form */ + + if (!valid(n, base)) + return 0; + + accum = n; + + for (toobig = 0; n = ToWNumber(*nptr), valid(n, base); ++nptr) + + /* minor wrap-around */ + + if (accum > UINTMAX_MAX / base + 1 || (next = base * accum + n) < accum) + + /* but keep scanning */ + + toobig = 1; + else + accum = next; + + /* -> first not-valid-digit */ + + if ( endptr != NULL ) + *endptr = (wchar_t *)nptr; + + if ( toobig ) + { + errno = ERANGE; + return UINTMAX_MAX; + } + else + return minus ? -accum : accum; /* (yes!) */ +} + +unsigned long long +__attribute__ ( + (alias ("wcstoumax"))) +wcstoull ( + const wchar_t* __restrict__ nptr, + wchar_t ** __restrict__ endptr, int base); + -- 2.7.4