OSDN Git Service

2003-12-04 Artem B. Bityuckiy <abitytsky@softminecorp.com>
authorjjohnstn <jjohnstn>
Fri, 5 Dec 2003 01:42:25 +0000 (01:42 +0000)
committerjjohnstn <jjohnstn>
Fri, 5 Dec 2003 01:42:25 +0000 (01:42 +0000)
        * libc/stdio/vfprintf.c (_VFPRINTF_R): Use _r versions
        of mb routines for %lc and %ls support.
        * libc/stdio/vfscanf.c (_svfscanf_r): Add %lc, %C,
        %ls, and %S support.  Remove CYGNUS_NEC markers and
        code within.

newlib/ChangeLog
newlib/libc/stdio/vfprintf.c
newlib/libc/stdio/vfscanf.c

index 2d09818..07fca26 100644 (file)
@@ -1,3 +1,11 @@
+2003-12-04  Artem B. Bityuckiy  <abitytsky@softminecorp.com>
+
+       * libc/stdio/vfprintf.c (_VFPRINTF_R): Use _r versions
+       of mb routines for %lc and %ls support.
+       * libc/stdio/vfscanf.c (_svfscanf_r): Add %lc, %C,
+       %ls, and %S support.  Remove CYGNUS_NEC markers and
+       code within.
+
 2003-12-04  Jeff Johnston  <jjohnstn@redhat.com>
 
        * libc/include/wchar.h: Add prototypes for _mbrtowc_r,
@@ -24,7 +32,7 @@
        * libc/stdlib/atol.c (_atol_r): New reentrant function.
        * libc/stdlib/atoll.c (_atoll_r): Ditto.
 
-2003-11-27  Artem B. Bityuckiy  <mail_lists@mail.ru>
+2003-11-27  Artem B. Bityuckiy  <abitytsky@softminecorp.com>
            Jeff Johnston  <jjohnstn@redhat.com>
 
        * libc/include/stdlib.h (lldiv_t): New type.
        * libc/include/unistd.h: Ditto.
        * libc/include/stat.h: Ditto.  Also declare struct stat64.
 
-2003-11-24  Artem B. Bityuckiy  <mail_lists@mail.ru>
+2003-11-24  Artem B. Bityuckiy  <abitytsky@softminecorp.com>
 
        * libc/stdio/vfprintf.c (_VFPRINTF_R): Fix check for 'C' format
        specifier to use ch instead of *fmt.
 
-2003-11-21  Artem B. Bityuckiy  <mail_lists@mail.ru>
+2003-11-21  Artem B. Bityuckiy  <abitytsky@softminecorp.com>
 
        * libc/stdio/vfprintf.c (_VFPRINTF_R, get_arg): Move mb-specific
        code within checks for MB_CAPABLE.  For non-mb-capable platforms,
        * libc/sys/linux/linuxthreads/td_thr_validate.c: Ditto.
 
 2003-11-05  Jeff Johnston  <jjohnstn@redhat.com>
-            Artem B. Bityuckiy  <mail_lists@mail.ru>
+            Artem B. Bityuckiy  <abitytsky@softminecorp.com>
 
        * libc/stdio/vfprintf.c (_VFPRINTF_R): Add support for
        %ls, %S, %lc, and %C format specifiers.
        CC_FOR_NEWLIB include options.
        * configure: Regenerated.
 
-2003-10-23  Artem B. Bityuckiy  <mail_lists@mail.ru>
+2003-10-23  Artem B. Bityuckiy  <abitytsky@softminecorp.com>
 
        * libc/string/wcsnlen.c: New file.
        * libc/include/wchar.h: Add wcsnlen prototype.
index 743d307..7015740 100644 (file)
@@ -750,7 +750,7 @@ reswitch:   switch (ch) {
                                mbstate_t ps;
 
                                memset((void *)&ps, '\0', sizeof(mbstate_t));
-                               if ((size = (int)wcrtomb(cp, 
+                               if ((size = (int)_wcrtomb_r(data, cp, 
                                               (wchar_t)GET_ARG(N, ap, wint_t), 
                                                &ps)) == -1)
                                        goto error; 
@@ -931,8 +931,8 @@ reswitch:   switch (ch) {
                                        while (1) {
                                                if (wcp[m] == L'\0')
                                                        break;
-                                               if ((n = (int)wcrtomb(buf
-                                                       wcp[m], &ps)) == -1)
+                                               if ((n = (int)_wcrtomb_r(data
+                                                     buf, wcp[m], &ps)) == -1)
                                                        goto error;
                                                if (n + size > prec)
                                                        break;
@@ -943,8 +943,8 @@ reswitch:   switch (ch) {
                                        }
                                }
                                else {
-                                       if ((size = (int)wcsrtombs(NULL, &wcp
-                                                               0, &ps)) == -1)
+                                       if ((size = (int)_wcsrtombs_r(data
+                                                   NULL, &wcp, 0, &ps)) == -1)
                                                goto error; 
                                        wcp = (_CONST wchar_t *)cp;
                                }
@@ -953,13 +953,13 @@ reswitch: switch (ch) {
                                        break;
  
                                if ((malloc_buf = 
-                                   (char *)malloc(size + 1)) == NULL)
+                                   (char *)_malloc_r(data, size + 1)) == NULL)
                                        goto error;
                              
                                /* Convert widechar string to multibyte string. */
                                memset((void *)&ps, '\0', sizeof(mbstate_t));
-                               if (wcsrtombs(malloc_buf, &wcp, size, &ps) 
-                                   != size)
+                               if (_wcsrtombs_r(data, malloc_buf, 
+                                                 &wcp, size, &ps) != size)
                                        goto error;
                                cp = malloc_buf;
                                cp[size] = '\0';
index fab2fbf..eef38b9 100644 (file)
@@ -104,6 +104,7 @@ Supporting OS subroutines required:
 
 #include <_ansi.h>
 #include <ctype.h>
+#include <wctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <limits.h>
@@ -138,7 +139,13 @@ extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr));
 #endif
 
 #include "floatio.h"
-#define        BUF     (MAXEXP+MAXFRACT+3)     /* 3 = sign + decimal point + NUL */
+
+#if ((MAXEXP+MAXFRACT+3) > MB_LEN_MAX)
+#  define BUF (MAXEXP+MAXFRACT+3)        /* 3 = sign + decimal point + NUL */
+#else
+#  define BUF MB_LEN_MAX
+#endif
+
 /* An upper bound for how long a long prints in decimal.  4 / 13 approximates
    log (2).  Add one char for roundoff compensation and one for the sign.  */
 #define MAX_LONG_LEN ((CHAR_BIT * sizeof (long)  - 1) * 4 / 13 + 2)
@@ -254,14 +261,14 @@ __svfscanf_r (rptr, fp, fmt0, ap)
   int base = 0;                        /* base argument to strtol/strtoul */
   int nbytes = 1;               /* number of bytes read from fmt string */
   wchar_t wc;                   /* wchar to use to read format string */
+  wchar_t *wcp;                 /* handy wide character pointer */
+  size_t mbslen;                /* length of converted multibyte sequence */
+  mbstate_t state;              /* value to keep track of multibyte state */
 
   u_long (*ccfn) () = 0;       /* conversion function (strtol/strtoul) */
   char ccltab[256];            /* character class table for %[...] */
   char buf[BUF];               /* buffer for numeric conversions */
   char *lptr;                   /* literal pointer */
-#ifdef MB_CAPABLE
-  mbstate_t state;                /* value to keep track of multibyte state */
-#endif
 
   char *cp;
   short *sp;
@@ -272,8 +279,6 @@ __svfscanf_r (rptr, fp, fmt0, ap)
   long *lp;
 #ifndef _NO_LONGLONG
   long long *llp;
-#else
-       u_long _uquad;
 #endif
 
   /* `basefix' is used to avoid `if' tests in the integer scanner */
@@ -428,6 +433,9 @@ __svfscanf_r (rptr, fp, fmt0, ap)
          c = CT_FLOAT;
          break;
 #endif
+        case 'S':
+          flags |= LONG;
+          /* FALLTHROUGH */
 
        case 's':
          c = CT_STRING;
@@ -439,6 +447,10 @@ __svfscanf_r (rptr, fp, fmt0, ap)
          c = CT_CCL;
          break;
 
+        case 'C':
+          flags |= LONG;
+          /* FALLTHROUGH */
+
        case 'c':
          flags |= NOSKIP;
          c = CT_CHAR;
@@ -516,9 +528,7 @@ __svfscanf_r (rptr, fp, fmt0, ap)
              if (--fp->_r > 0)
                fp->_p++;
              else
-#ifndef CYGNUS_NEC
              if (__srefill (fp))
-#endif
                goto input_failure;
            }
          /*
@@ -538,10 +548,47 @@ __svfscanf_r (rptr, fp, fmt0, ap)
          /* scan arbitrary characters (sets NOSKIP) */
          if (width == 0)
            width = 1;
-         if (flags & SUPPRESS)
+          if (flags & LONG) 
+            {
+              if ((flags & SUPPRESS) == 0)
+                wcp = va_arg(ap, wchar_t *);
+              else
+                wcp = NULL;
+              n = 0;
+              while (width != 0) 
+                {
+                  if (n == MB_CUR_MAX)
+                    goto input_failure;
+                  buf[n++] = *fp->_p;
+                  fp->_r -= 1;
+                  fp->_p += 1;
+                  memset((void *)&state, '\0', sizeof(mbstate_t));
+                  if ((mbslen = _mbrtowc_r(rptr, wcp, buf, n, &state)) 
+                                                         == (size_t)-1)
+                    goto input_failure; /* Invalid sequence */
+                  if (mbslen == 0 && !(flags & SUPPRESS))
+                    *wcp = L'\0';
+                  if (mbslen != (size_t)-2) /* Incomplete sequence */
+                    {
+                      nread += n;
+                      width -= 1;
+                      if (!(flags & SUPPRESS))
+                        wcp += 1;
+                      n = 0;
+                    }
+                  if (BufferEmpty) 
+                   {
+                      if (n != 0) 
+                        goto input_failure;
+                      break;
+                    }
+                }
+              if (!(flags & SUPPRESS))
+                nassigned++;
+            } 
+          else if (flags & SUPPRESS) 
            {
              size_t sum = 0;
-
              for (;;)
                {
                  if ((n = fp->_r) < (int)width)
@@ -549,16 +596,12 @@ __svfscanf_r (rptr, fp, fmt0, ap)
                      sum += n;
                      width -= n;
                      fp->_p += n;
-#ifndef CYGNUS_NEC
                      if (__srefill (fp))
                        {
-#endif
                          if (sum == 0)
                            goto input_failure;
                          break;
-#ifndef CYGNUS_NEC
                        }
-#endif
                    }
                  else
                    {
@@ -572,27 +615,11 @@ __svfscanf_r (rptr, fp, fmt0, ap)
            }
          else
            {
-#ifdef CYGNUS_NEC
-             /* Kludge city for the moment */
-             char *dest = va_arg (ap, char *);
-             int n = width;
-             if (fp->_r == 0)
-               goto input_failure;
-
-             while (n && fp->_r)
-               {
-                 *dest++ = *(fp->_p++);
-                 n--;
-                 fp->_r--;
-                 nread++;
-               }
-#else
              size_t r = fread ((_PTR) va_arg (ap, char *), 1, width, fp);
 
              if (r == 0)
                goto input_failure;
              nread += r;
-#endif
              nassigned++;
            }
          break;
@@ -648,8 +675,56 @@ __svfscanf_r (rptr, fp, fmt0, ap)
        case CT_STRING:
          /* like CCL, but zero-length string OK, & no NOSKIP */
          if (width == 0)
-           width = ~0;
-         if (flags & SUPPRESS)
+            width = (size_t)~0;
+          if (flags & LONG) 
+            {
+              /* Process %S and %ls placeholders */
+              if ((flags & SUPPRESS) == 0)
+                wcp = va_arg(ap, wchar_t *);
+              else
+                wcp = &wc;
+              n = 0;
+              while (!isspace(*fp->_p) && width != 0) 
+                {
+                  if (n == MB_CUR_MAX)
+                    goto input_failure;
+                  buf[n++] = *fp->_p;
+                  fp->_r -= 1;
+                  fp->_p += 1;
+                  memset((void *)&state, '\0', sizeof(mbstate_t));
+                  if ((mbslen = _mbrtowc_r(rptr, wcp, buf, n, &state)) 
+                                                        == (size_t)-1)
+                    goto input_failure;
+                  if (mbslen == 0)
+                    *wcp = L'\0';
+                  if (mbslen != (size_t)-2) /* Incomplete sequence */
+                    {
+                      if (iswspace(*wcp)) 
+                        {
+                          while (n != 0)
+                            ungetc(buf[--n], fp);
+                          break;
+                        }
+                      nread += n;
+                      width -= 1;
+                      if ((flags & SUPPRESS) == 0)
+                        wcp += 1;
+                      n = 0;
+                    }
+                  if (BufferEmpty) 
+                    {
+                      if (n != 0)
+                        goto input_failure;
+                      break;
+                    }
+                }
+              if (!(flags & SUPPRESS)) 
+                {
+                  *wcp = L'\0';
+                  nassigned++;
+                }
+            }
+          else if (flags & SUPPRESS) 
            {
              n = 0;
              while (!isspace (*fp->_p))
@@ -797,9 +872,7 @@ __svfscanf_r (rptr, fp, fmt0, ap)
              if (--fp->_r > 0)
                fp->_p++;
              else
-#ifndef CYGNUS_NEC
              if (__srefill (fp))
-#endif
                break;          /* EOF */
            }
          /*
@@ -961,9 +1034,7 @@ __svfscanf_r (rptr, fp, fmt0, ap)
              if (--fp->_r > 0)
                fp->_p++;
              else
-#ifndef CYGNUS_NEC
              if (__srefill (fp))
-#endif
                break;          /* EOF */
            }
          if (zeroes)
@@ -998,11 +1069,11 @@ __svfscanf_r (rptr, fp, fmt0, ap)
            }
          if ((flags & SUPPRESS) == 0)
            {
-             double res;
+             double res = 0;
 #ifdef _NO_LONGDBL
 #define QUAD_RES res;
 #else  /* !_NO_LONG_DBL */
-             long double qres;
+             long double qres = 0;
 #define QUAD_RES qres;
 #endif /* !_NO_LONG_DBL */
              long new_exp = 0;