This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Adding Methods related to inttypes.h


Hello Developers,

I have ported the methods what are declared inside the inttypes.h
header file from freebsd. I am requesting you to please review the
code.

I am not able to push the code of ccoshl.c in my forked repo. It is
saying fatal error. I do not know how to apply the signature.asc file.
Please have a look on my issue.


Thanks & Regards,
Aditya Upadhyay
From b1eca6d665fc82eead745c49be9c7ccb27719483 Mon Sep 17 00:00:00 2001
From: Aditya Upadhyay <aadit0402@gmail.com>
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 <mike@FreeBSD.org>
+ *  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 <stdint.h> 
+#include <stdio.h>
+
+#include <inttypes.h>
+
+
+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 <mike@FreeBSD.org>
+ *  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 <stdint.h> 
+
+#include <inttypes.h>
+
+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 <gwyn@arl.mil>
+ *  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 <inttypes.h>.
+ *  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 <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+/* 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 <gwyn@arl.mil>
+ *  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 <inttypes.h>.
+ *  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 <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+/* 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 <gwyn@arl.mil>
+ *  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 <inttypes.h>.
+ *  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 <wchar.h>
+#include <errno.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+/* 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 <gwyn@arl.mil>
+ *  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 <inttypes.h>.
+ *  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 <wchar.h>
+#include <errno.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+/* 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]