2001-05-07 Benjamin Kosnik <bkoz@redhat.com>
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 8 May 2001 03:07:56 +0000 (03:07 +0000)
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 8 May 2001 03:07:56 +0000 (03:07 +0000)
libstdc++/2523
* include/bits/std_fstream.h (basic_filebuf): Change signature.
* include/bits/fstream.tcc (basic_filebuf): Change bool argument
to int_type, pass in buffer size info.
* include/bits/std_streambuf.h (_M_is_indeterminate): Check for
unbuffered situation.
(underflow): Remove codecvt bits for the time being.
* include/bits/istream.tcc (istream::sentry): Avoid sputbackc call.
* include/bits/locale_facets.tcc (_M_extract): Cache dereference
values from iterators, clean.
* src/locale.cc: Ditto.
* include/bits/sbuf_iter.h: Format.
* src/ios.cc: Explicitly pass in buffer sizes at creation time.
* testsuite/27_io/narrow_stream_objects.cc: Add tests.
* testsuite/27_io/filebuf.cc: Tweaks.
* testsuite/27_io/filebuf_members.cc: Tweaks.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41908 138bc75d-0d04-0410-961f-82ee72b054a4

12 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/include/bits/istream.tcc
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/include/bits/sbuf_iter.h
libstdc++-v3/include/bits/std_fstream.h
libstdc++-v3/include/bits/std_streambuf.h
libstdc++-v3/src/ios.cc
libstdc++-v3/src/locale.cc
libstdc++-v3/testsuite/27_io/filebuf.cc
libstdc++-v3/testsuite/27_io/filebuf_members.cc
libstdc++-v3/testsuite/27_io/narrow_stream_objects.cc

index 6240492..13d9b06 100644 (file)
@@ -1,3 +1,22 @@
+2001-05-07  Benjamin Kosnik  <bkoz@redhat.com>
+
+       libstdc++/2523
+       * include/bits/std_fstream.h (basic_filebuf): Change signature.
+       * include/bits/fstream.tcc (basic_filebuf): Change bool argument
+       to int_type, pass in buffer size info.
+       * include/bits/std_streambuf.h (_M_is_indeterminate): Check for
+       unbuffered situation.
+       (underflow): Remove codecvt bits for the time being.
+       * include/bits/istream.tcc (istream::sentry): Avoid sputbackc call.
+       * include/bits/locale_facets.tcc (_M_extract): Cache dereference
+       values from iterators, clean.
+       * src/locale.cc: Ditto.
+       * include/bits/sbuf_iter.h: Format.
+       * src/ios.cc: Explicitly pass in buffer sizes at creation time.
+       * testsuite/27_io/narrow_stream_objects.cc: Add tests.
+       * testsuite/27_io/filebuf.cc: Tweaks.
+       * testsuite/27_io/filebuf_members.cc: Tweaks.
+       
 2001-05-07  Mark Mitchell  <mark@codesourcery.com>
 
        * config/os/solaris/solaris2.7/bits/os_defines.h
index c1311e9..8b551ff 100644 (file)
@@ -90,7 +90,7 @@ namespace std
 
   template<typename _CharT, typename _Traits>
     basic_filebuf<_CharT, _Traits>::
-    basic_filebuf(__c_file_type* __f, bool __s, ios_base::openmode __mode)
+    basic_filebuf(__c_file_type* __f, ios_base::openmode __mode, int_type __s)
     : __streambuf_type(),  _M_file(NULL), _M_state_cur(__state_type()), 
     _M_state_beg(__state_type()), _M_last_overflowed(false)
     {
@@ -99,8 +99,9 @@ namespace std
       if (this->is_open())
        {
          _M_mode = __mode;
-         if (!__s)
+         if (__s)
            {
+             _M_buf_size_opt = __s;
              _M_allocate_buffers();
              _M_set_indeterminate();
            }
@@ -208,7 +209,9 @@ namespace std
     {
       int_type __ret = traits_type::eof();
       bool __testin = _M_mode & ios_base::in;
-      
+      bool __testout = _M_mode & ios_base::out;
+
+      // XXX Should re-enable codecvt bits disabled after 2.90.8.
       if (__testin)
        {
          // Check for pback madness, and if so swich back to the
@@ -223,8 +226,6 @@ namespace std
 
          bool __testget = _M_in_cur && _M_in_beg < _M_in_cur;
          bool __testinit = _M_is_indeterminate();
-         bool __testout = _M_mode & ios_base::out;
-
          // Sync internal and external buffers.
          // NB: __testget -> __testput as _M_buf_unified here.
          if (__testget)
@@ -238,7 +239,7 @@ namespace std
 
          if (__testinit || __testget)
            {
-#if 1
+             // Assume buffered case, need to refill internal buffers.
              streamsize __size = _M_file->xsgetn(_M_in_beg, _M_buf_size);
              if (0 < __size)
                {
@@ -252,53 +253,7 @@ namespace std
                    {
                      // XXX Something is wrong, do error checking.
                    }
-               }
-#else
-             // 2000-08-04 bkoz disable
-             // Part one: (Re)fill external buf (_M_file->_IO_*) from
-             // external byte sequence (whatever physical byte sink or
-             // FILE actually is.)
-             char_type* __conv_buf = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * _M_buf_size));
-             streamsize __size = _M_file->xsgetn(__conv_buf, _M_buf_size);
-             
-             // Part two: (Re)fill internal buf contents from external buf.
-             if (0 < __size)
-               {
-                 _M_set_determinate(__size);
-                 
-                 char* __conv_cur = __conv_buf;
-                 _M_state_beg = _M_state_cur;
-                 __res_type __r = _M_fcvt->in(_M_state_cur, 
-                                              __conv_buf,
-                                              __conv_buf + __size,
-                                        const_cast<const char*&>(__conv_cur), 
-                                             _M_in_beg, _M_in_end, _M_in_cur);
-             
-                 if (__r == codecvt_base::partial)
-                   {
-                     // XXX Retry with larger _M_buf size.
-                   }
-                 
-                 // Set pointers to internal and external buffers
-                 // correctly. . .
-                 if (__r != codecvt_base::error)
-                   {
-                     if (__testout)
-                       _M_out_cur = _M_in_cur;
-                     __ret = traits_type::to_int_type(*_M_in_cur);
-                   }
-
-                 // Part three: Sync the current internal buffer
-                 // position with the (now overshot) external buffer
-                 // position.  
-                 streamoff __p = _M_file->seekoff(0 - __size, ios_base::cur, 
-                                                 ios_base::in);
-                 if (__p == -1)
-                   {
-                     // XXX Something is wrong, do error checking.
-                   }
-               }
-#endif       
+               }          
            }
        }
       _M_last_overflowed = false;      
index c13bf67..4f3ff96 100644 (file)
@@ -44,24 +44,16 @@ namespace std {
          if (!__noskipws && (__in.flags() & ios_base::skipws))
            {     
              const __int_type __eof = traits_type::eof();
-             __int_type __c = __int_type(0);
-             __streambuf_type* __sb = __in.rdbuf();
              const __ctype_type* __ctype = __in._M_get_fctype_ios();
-             bool __testsp = true;
-             bool __testeof = false;
-             
-             while (!__testeof && __testsp)
-               {
-                 __c = __sb->sbumpc();
-                 __testeof = __c == __eof;
-                 __testsp = __ctype->is(ctype_base::space, __c);
-               }
+             __streambuf_type* __sb = __in.rdbuf();
+             __int_type __c = __sb->sgetc();
              
-             if (!__testeof && !__testsp)
-               __sb->sputbackc(__c);
+             while (__c != __eof && __ctype->is(ctype_base::space, __c))
+               __c = __sb->snextc();
+
 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
 //195.  Should basic_istream::sentry's constructor ever set eofbit? 
-             else
+             if (__c == __eof)
                __in.setstate(ios_base::eofbit);
 #endif
            }
index edb3d17..482ed9f 100644 (file)
@@ -189,15 +189,15 @@ namespace std
       switch (__ev)
         {
         case ios_base::erase_event:
-          delete static_cast<_Format_cache<_CharT>*> (__p); __p = 0;
+          delete static_cast<_Format_cache<_CharT>*>(__p);
+         __p = 0;
           break;
         case ios_base::copyfmt_event:
           // If just stored zero, the callback would get registered again.
-          try {
-            __p = new _Format_cache<_CharT>;
-          }
-          catch(...) {
-          }
+          try 
+           { __p = new _Format_cache<_CharT>; }
+          catch(...) 
+           { }
           break;
         case ios_base::imbue_event:
           static_cast<_Format_cache<_CharT>*>(__p)->_M_valid = false;
index 4935c11..4d69b58 100644 (file)
@@ -46,7 +46,12 @@ namespace std
       typedef _Traits                          traits_type;
       typedef basic_streambuf<_CharT, _Traits> streambuf_type;
       typedef basic_ostream<_CharT, _Traits>   ostream_type;
-      
+
+    private:
+      streambuf_type*  _M_sbuf;
+      bool             _M_failed;
+
+    public:
       inline 
       ostreambuf_iterator(ostream_type& __s) throw ()
       : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
@@ -72,10 +77,6 @@ namespace std
       bool 
       failed() const throw()
       { return _M_failed; }
-
-    private:
-      streambuf_type*  _M_sbuf;
-      bool             _M_failed;
     };
 
   template<typename _CharT, typename _Traits>
@@ -90,13 +91,12 @@ namespace std
 
 
   // 24.5.3 Template class istreambuf_iterator
-  template<class _CharT, class _Traits>
+  template<typename _CharT, typename _Traits>
     class istreambuf_iterator
     : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type,
                      _CharT*, _CharT&>
     {
     public:
-
       // Types:
       typedef _CharT                                   char_type;
       typedef _Traits                                  traits_type;
@@ -106,6 +106,18 @@ namespace std
       // Non-standard Types:
       typedef istreambuf_iterator<_CharT, _Traits>     __istreambufiter_type;
 
+    private:
+      // 24.5.3 istreambuf_iterator 
+      // p 1 
+      // If the end of stream is reached (streambuf_type::sgetc()
+      // returns traits_type::eof()), the iterator becomes equal to
+      // the "end of stream" iterator value.
+      // NB: This implementation assumes the "end of stream" value
+      // is EOF, or -1.
+      streambuf_type*          _M_sbuf;  
+      int_type                         _M_c;
+
+    public:
       istreambuf_iterator() throw() 
       : _M_sbuf(NULL), _M_c(-2) { }
       
@@ -174,17 +186,6 @@ namespace std
        return (__thiseof && __beof || (!__thiseof && !__beof));
       }
 #endif
-
-    private:
-      // 24.5.3 istreambuf_iterator 
-      // p 1 
-      // If the end of stream is reached (streambuf_type::sgetc()
-      // returns traits_type::eof()), the iterator becomes equal to
-      // the "end of stream" iterator value.
-      // NB: This implementation assumes the "end of stream" value
-      // is EOF, or -1.
-      streambuf_type*          _M_sbuf;  
-      int_type                         _M_c;
     };
 
   template<typename _CharT, typename _Traits>
@@ -198,10 +199,5 @@ namespace std
     operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
               const istreambuf_iterator<_CharT, _Traits>& __b)
     { return !__a.equal(__b); }
-
 } // namespace std
-
 #endif
-
-
-
index 63a86b9..479ee09 100644 (file)
@@ -86,7 +86,8 @@ namespace std
       basic_filebuf();
 
       // Non-standard ctor:
-      basic_filebuf(__c_file_type* __f, bool __s, ios_base::openmode __mode);
+      basic_filebuf(__c_file_type* __f, ios_base::openmode __mode, 
+                   int_type __s = static_cast<int_type>(BUFSIZ));
  
       virtual 
       ~basic_filebuf() 
index 013d7e9..678c140 100644 (file)
@@ -251,17 +251,20 @@ namespace std
          this->setg(_M_buf, _M_buf, _M_buf + __off);
        if (__testout)
          this->setp(_M_buf, _M_buf + __off);
-
       }
 
       bool
       _M_is_indeterminate(void)
       { 
        bool __ret = false;
-       if (_M_mode & ios_base::in)
-         __ret = _M_in_beg == _M_in_cur && _M_in_cur == _M_in_end;
-       if (_M_mode & ios_base::out)
-         __ret = _M_out_beg == _M_out_cur && _M_out_cur == _M_out_end;
+       // Don't return true if unbuffered.
+       if (_M_buf)
+         {
+           if (_M_mode & ios_base::in)
+             __ret = _M_in_beg == _M_in_cur && _M_in_cur == _M_in_end;
+           if (_M_mode & ios_base::out)
+             __ret = _M_out_beg == _M_out_cur && _M_out_cur == _M_out_end;
+         }
        return __ret;
       }
 
@@ -350,7 +353,7 @@ namespace std
       {
        int_type __ret;
        if (_M_in_cur && _M_in_cur < _M_in_end)
-         __ret = traits_type::to_int_type(*gptr());
+         __ret = traits_type::to_int_type(*(this->gptr()));
        else 
          __ret = this->underflow();
        return __ret;
index de577d6..6d4039d 100644 (file)
@@ -136,19 +136,21 @@ namespace std
   void
   ios_base::Init::_S_ios_create(bool __sync)
   {
+    int __bufsize = __sync ? 0 : static_cast<int>(BUFSIZ);
     // NB: The file std_iostream.h creates the four standard files
-    // with NULL buffers. At this point, we swap out these
-    new (&cout) ostream(new filebuf(stdout, __sync, ios_base::out));
-    new (&cin) istream(new filebuf(stdin, __sync, ios_base::in));
-    new (&cerr) ostream(new filebuf(stderr, __sync, ios_base::out));
+    // with NULL buffers. At this point, we swap out the dummy NULL
+    // buffers with the real deal.
+    new (&cout) ostream(new filebuf(stdout, ios_base::out, __bufsize));
+    new (&cin) istream(new filebuf(stdin, ios_base::in, 1));
+    new (&cerr) ostream(new filebuf(stderr, ios_base::out, __bufsize));
     new (&clog) ostream(cerr.rdbuf());
     cin.tie(&cout);
     cerr.flags(ios_base::unitbuf);
     
 #ifdef _GLIBCPP_USE_WCHAR_T
-    new (&wcout) wostream( new wfilebuf(stdout, __sync, ios_base::out));
-    new (&wcin) wistream(new wfilebuf(stdin, __sync, ios_base::in));
-    new (&wcerr) wostream(new wfilebuf(stderr, __sync, ios_base::out));
+    new (&wcout) wostream( new wfilebuf(stdout, ios_base::out, __bufsize));
+    new (&wcin) wistream(new wfilebuf(stdin, ios_base::in, 1));
+    new (&wcerr) wostream(new wfilebuf(stderr, ios_base::out, __bufsize));
     new (&wclog) wostream(wcerr.rdbuf());
     wcin.tie(&wcout);
     wcerr.flags(ios_base::unitbuf);
index 3b43090..26bbc56 100644 (file)
@@ -676,9 +676,9 @@ namespace std
 
       // Stage 2: extract characters.
       __cache_type const* __fmt = __cache_type::_S_get(__io);
-      bool __valid = __beg != __end;
+
       // Fail quickly if !__valid
-      if (!__valid)
+      if (__beg == __end)
         {
           __err |= (ios_base::eofbit | ios_base::failbit);
           return;
@@ -694,14 +694,19 @@ namespace std
       // Check first for sign
       bool __testsign = false;
       if ((__c == __lits[__cache_type::_S_minus])
-          || (__c == __lits[__cache_type::_S_plus]))
+         || (__c == __lits[__cache_type::_S_plus]))
         {
+          __testsign = true;
           __xtrc[__pos++] = __c;
           ++__beg;
-          __testsign = true;
-          // whitespace may follow a sign
-          while ((__beg != __end) && (isspace(*__beg)))
-            ++__beg;
+         __c = * __beg;
+
+          // Whitespace may follow a sign
+          while ((__beg != __end) && (isspace(__c)))
+           {
+             ++__beg;
+             __c = *__beg;
+           }
 
           // There had better be more to come...
           if (__beg == __end)
@@ -712,20 +717,19 @@ namespace std
             }
         }
 
-      bool __testzero = false;    // Has there been a leading zero?
-
-      // Now check if first character is a zero
-      __c = *__beg;
+      // Now check if first character is a zero.
+      bool __testzero = false;    
       if (__c == __lits[__cache_type::_S_digits])
         {
            __testzero = true;
            ++__beg;
+          __c = *__beg;
 
            // We have to check for __beg == __end here. If so,
            // a plain '0' (possibly with a sign) can be got rid of now
            if (__beg == __end)
              {
-               __xtrc[__pos++] = __c;
+               __xtrc[__pos++] = __lits[__cache_type::_S_digits];
                __xtrc[__pos] = '\0';
                __err |= ios_base::eofbit;
                return;
@@ -736,11 +740,11 @@ namespace std
           if (!__fp && __base != 10 && __base != 8)
             {
               // Here, __base == 0 or 16
-              __c = *__beg;
               if ((__c == __lits[__cache_type::_S_x])
                  || (__c == __lits[__cache_type::_S_X]))
                 {
                   ++__beg;
+                 __c = *__beg;
                   __base = 16;
                   __testzero = false; // "0x" is not a leading zero
                 }
@@ -751,9 +755,10 @@ namespace std
           // Remove any more leading zeros
           while (__beg != __end)
             {
-              if (*__beg == __lits[__cache_type::_S_digits])
+              if (__c == __lits[__cache_type::_S_digits])
                 {
                   ++__beg;
+                 __c = *__beg;
                   __testzero = true;
                 }
               else
@@ -767,44 +772,45 @@ namespace std
       // We may need to know if anything is found here. A leading zero
       // (removed by now) would count.
       bool __testunits = __testzero;
-      while (__valid && __beg != __end)
+      while (__beg != __end)
         {
-          __valid = false;
-          __c = *__beg;
-          const char* __p = strchr(__fmt->_S_literals, __c);
+          const char* __p = strchr(__lits, __c);
 
           // NB: strchr returns true for __c == 0x0
-          if (__p && __c)
-            {
-              // Try first for acceptable digit; record it if found
-              if ((__p >= &__lits[__cache_type::_S_digits]
-                    && __p < &__lits[__cache_type::_S_digits + __base])
-                   || (__p >= &__lits[__cache_type::_S_udigits]
-                       && __p < &__lits[__cache_type::_S_udigits + __base]))
-                {
-                  __xtrc[__pos++] = __c;
-                  ++__sep_pos;
-                  __valid = true;
-                  __testunits = true;
-                }
-            }
-          else if (__c == __fmt->_M_thousands_sep
-                   && __fmt->_M_use_grouping)
-            {
+          if (__p && __c
+             &&((__p >= &__lits[__cache_type::_S_digits]
+                 && __p < &__lits[__cache_type::_S_digits + __base])
+                || (__p >= &__lits[__cache_type::_S_udigits]
+                    && __p < &__lits[__cache_type::_S_udigits + __base])))
+           {
+             // Try first for acceptable digit; record it if found.
+             __xtrc[__pos++] = __c;
+             ++__sep_pos;
+             __testunits = true;
+             ++__beg;
+             __c = *__beg;
+           }
+          else if (__c == __fmt->_M_thousands_sep && __fmt->_M_use_grouping)
+           {
               // NB: Thousands separator at the beginning of a string
               // is a no-no, as is two consecutive thousands
-              // separators
+              // separators.
               if (__sep_pos)
                 {
                   __grp += static_cast<char>(__sep_pos);
                   __sep_pos = 0;
-                  __valid = true;
+                 ++__beg;
+                 __c = *__beg;
                 }
               else
-                __err |= ios_base::failbit;
+               {
+                 __err |= ios_base::failbit;
+                 break;
+               }
             }
-          if (__valid)
-            ++__beg;
+         else
+           // Not a valid input item.
+           break;
         }
 
       // Digit grouping is checked. If _M_groupings() doesn't
@@ -852,7 +858,6 @@ namespace std
       // That's it for integer types. Remaining code is for floating point
       if (__fp && __beg != __end)
         {
-          __c = *__beg;
           // Check first for decimal point. There MUST be one if
           // __testunits is false.
           bool __testdec = false;    // Is there a decimal point
@@ -861,12 +866,13 @@ namespace std
             {
               __xtrc[__pos++] = '.';
               ++__beg;
+             __c = *__beg;
+
               // Now we get any digits after the decimal point
               // There MUST be some if __testunits is false.
               while (__beg != __end)
                 {
-                  __c = *__beg;
-                  const char* __p = strchr(__fmt->_S_literals, __c);
+                  const char* __p = strchr(__lits, __c);
                   if ((__p >= &__lits[__cache_type::_S_digits]
                         && __p < &__lits[__cache_type::_S_digits + __base])
                        || (__p >= &__lits[__cache_type::_S_udigits]
@@ -874,6 +880,7 @@ namespace std
                     {
                       __xtrc[__pos++] = __c;
                       ++__beg;
+                     __c = *__beg;
                       __testdec = true;
                     }
                   else
@@ -892,25 +899,28 @@ namespace std
           // Now we may find an exponent
           if (__beg != __end)
             {
-              __c = *__beg;
               if ((__c == __lits[__cache_type::_S_ee])
                    || (__c == __lits[__cache_type::_S_Ee]))
                 {
                   __xtrc[__pos++] = __c;
                   ++__beg;
+                 __c = *__beg;
+
                   // Now there may be a sign
                   if (__beg != __end)
                     {
-                      __c = *__beg;
                       if ((__c == __lits[__cache_type::_S_minus])
                           || (__c == __lits[__cache_type::_S_plus]))
                         {
                           __xtrc[__pos++] = __c;
                           ++__beg;
+                         __c = *__beg;
                           // whitespace may follow a sign
-                          while ((__beg != __end) && (isspace(*__beg)))
-                            ++__beg;
-
+                          while ((__beg != __end) && (isspace(__c)))
+                           {
+                             ++__beg;
+                             __c = *__beg;
+                           }
                         }
                     }
                   // And now there must be some digits
@@ -922,8 +932,7 @@ namespace std
                     }
                   while (__beg != __end)
                     {
-                      __c = *__beg;
-                      const char* __p = strchr(__fmt->_S_literals, __c);
+                      const char* __p = strchr(__lits, __c);
                       if ((__p >= &__lits[__cache_type::_S_digits]
                             && __p < &__lits[__cache_type::_S_digits + __base])
                            || (__p >= &__lits[__cache_type::_S_udigits]
@@ -931,6 +940,7 @@ namespace std
                         {
                           __xtrc[__pos++] = __c;
                           ++__beg;
+                         __c = *__beg;
                         }
                       else
                         break;
index c59c291..d31614c 100644 (file)
@@ -546,6 +546,9 @@ public:
   operator<(const gnu_char_type& __lhs) 
   { return character < __lhs.character; }
 
+  // default ctor
+  gnu_char_type() { }
+
   // to_char_type
   gnu_char_type(const unsigned long& __l) : character(__l) { } 
 
index 3eda6f5..2e21232 100644 (file)
@@ -52,7 +52,7 @@ test_01()
   FILE* f2 = fopen(name_01, "r");
   VERIFY( f2 != NULL );
   {
-    std::filebuf fb(f2, false, std::ios_base::in);
+    std::filebuf fb(f2, std::ios_base::in, 512);
   }
   close_num = fclose(f2);
   VERIFY( close_num == 0 );
index 3fbe3dd..c1ca3ca 100644 (file)
@@ -1,6 +1,6 @@
 // 2000-08-02 bkoz
 
-// Copyright (C) 2000 Free Software Foundation, Inc.
+// Copyright (C) 2000, 2001 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -93,11 +93,31 @@ test01()
   return 0;
 }
 
+// libstdc++/2523
+void test02()
+{
+  int i;
+  cin >> i;
+  cout << "i == " << i << endl;
+}
+
+// libstdc++/2523
+void test03()
+{
+  ios_base::sync_with_stdio(false);
+
+  int i;
+  cin >> i;
+  cout << "i == " << i << endl;
+}
 
 int 
 main()
 {
   test01();
+
+  // test02();
+  // test03();
   return 0;
 }