Author Topic: PCL: GenericString.Break() has a bug  (Read 4121 times)

Offline georg.viehoever

  • PTeam Member
  • PixInsight Jedi Master
  • ******
  • Posts: 2132
PCL: GenericString.Break() has a bug
« on: 2012 November 30 08:44:58 »
The following code using Break() produces this output:
Code: [Select]
sArgs=-y 2014
arg=-y
arg=014
Obviously, Break() swollows a character in the second string.
Georg
Code: [Select]
StringList argvList;
 
std::cout<<"sArgs="<<sArgs<<std::endl;
  sArgs.Break(argvList,String(" "),true);
  const std::size_t
argc=argvList.Length()+1;
  StringVec_t argv(argc);
argv[0]="";
  for(std::size_t
i=1;i<argc;++i)
  {
std::cout<<"arg="<<argvList[i-1]<<std::endl;
argv[i]=IsoString(argvList[i-1]).c_str();
  }
Georg (6 inch Newton, unmodified Canon EOS40D+80D, unguided EQ5 mount)

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: PCL: GenericString.Break() has a bug
« Reply #1 on: 2012 November 30 10:37:39 »
Hi Georg,

This bug is already fixed in PCL 2.0. Thank you for reporting it anyway. You have two workarounds:

- Use:

Code: [Select]
sArgs.Break( argvList, ' ', true/*trim*/ );
That is, specify the token separator as a single character.

- Or patch the pcl/String.h file with the fixed code from PCL 2.0:

Code: [Select]
   /*!
    * Gets a sequence of \e tokens (substrings) extracted from this string.
    *
    * \param[out] list  The list of extracted tokens. Must be a reference to a
    *                   container, such as Array or List, or a derived class.
    *                   Typically, this parameter is a reference to a
    *                   StringList.
    *
    * \param s          The token separator null-terminated string.
    *
    * \param trim       True to \e trim the extracted tokens. If this parameter
    *                   is true, existing leading and trailing whitespace
    *                   characters will be removed from each extracted token.
    *
    * \param i          Starting character index.
    */
   template <class C>
   void Break( C& list, const T* s, bool trim = false, size_type i = 0 ) const
   {
      size_type len = Length();
      if ( i < len )
      {
         size_type n = R::Length( s );
         if ( n > 0 )
         {
            for ( ;; )
            {
               size_type j = Find( s, i );
               if ( j == notFound )
                  break;

               GenericString<T,R,A> t;
               if ( j > i )
               {
                  size_type m = j - i;
                  t.data->Allocate( m );
                  R::Copy( t.data->string, data->string+i, m );
                  t.data->string[m] = R::Null();
                  if ( trim )
                     t.Trim();
               }
               list.Add( t );

               if ( (i = j+n) == len )
                  return;
            }

            GenericString<T,R,A> t;
            t.data->Allocate( n = len-i );
            R::Copy( t.data->string, data->string+i, n );
            t.data->string[n] = R::Null();
            if ( trim )
               t.Trim();
            list.Add( t );
         }
      }
   }

This function should be around line 1615 of String.h.

Let me know if this helps.
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline georg.viehoever

  • PTeam Member
  • PixInsight Jedi Master
  • ******
  • Posts: 2132
Re: PCL: GenericString.Break() has a bug
« Reply #2 on: 2012 December 01 04:46:23 »
Thanks. Using
Code: [Select]
sArgs.Break( argvList, ' ', true/*trim*/ ); works fine  :)
Georg
Georg (6 inch Newton, unmodified Canon EOS40D+80D, unguided EQ5 mount)