]> git.mxchange.org Git - simgear.git/commitdiff
Bernie Bright:
authorcurt <curt>
Fri, 10 May 2002 13:32:44 +0000 (13:32 +0000)
committercurt <curt>
Fri, 10 May 2002 13:32:44 +0000 (13:32 +0000)
Here is a total rewrite of the strutils package.  I've reimplemented the
trimleft(), trimright() and trim() functions as lstrip(), rstrip() and
strip() respectively.  Additionally I've added a split() function that
behaves like its perl/python equivalent.  Just the thing for splitting
comma separated option strings or space separated telnet commands and
arguments.  I've also enclosed the whole thing in a namespace
simgear::strutils.  Since I seem to be the only one who uses these
functions, SimGear and FlightGear compile without change.

PS It is no coincidence that the new function names bear an uncanny
resemblance to the python functions of the same name.

simgear/misc/strutils.cxx
simgear/misc/strutils.hxx

index 2e7afbebdb32da18f2a408868d38e4ee0de2cbfd..2933e0d58427a6627ebc7f329d36c90baf2d3175 100644 (file)
@@ -1,8 +1,8 @@
 // String utilities.
 //
-// Written by Bernie Bright, 1998
+// Written by Bernie Bright, started 1998
 //
-// Copyright (C) 1998  Bernie Bright - bbright@c031.aone.net.au
+// Copyright (C) 1998  Bernie Bright - bbright@bigpond.net.au
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Library General Public
 //
 // $Id$
 
+#include <ctype.h>
 #include "strutils.hxx"
 
-const string whitespace = " \n\r\t";
+namespace simgear {
+    namespace strutils {
 
-//
-string
-trimleft( const string& s, const string& trimmings )
-{
-    string result;
-    string::size_type pos = s.find_first_not_of( trimmings );
-    if ( pos != string::npos )
-    {
-        result.assign( s.substr( pos ) );
-    }
-
-    return result;
-}
+       /**
+        * 
+        */
+       static vector<string>
+       split_whitespace( const string& str, int maxsplit )
+       {
+           vector<string> result;
+           string::size_type len = str.length();
+           string::size_type i = 0;
+           string::size_type j;
+           int countsplit = 0;
 
-//
-string
-trimright( const string& s, const string& trimmings )
-{
-    string result;
-
-    string::size_type pos = s.find_last_not_of( trimmings );
-    if ( pos == string::npos )
-    {
-       // Not found, return the original string.
-       result = s;
-    }
-    else
-    {
-        result.assign( s.substr( 0, pos+1 ) );
-    }
-
-    return result;
-}
+           while (i < len)
+           {
+               while (i < len && isspace(str[i]))
+               {
+                   ++i;
+               }
 
-//
-string
-trim( const string& s, const string& trimmings )
-{
-    return trimright( trimleft( s, trimmings ), trimmings );
-}
+               j = i;
+
+               while (i < len && !isspace(str[i]))
+               {
+                   ++i;
+               }
+
+               if (j < i)
+               {
+                   result.push_back( str.substr(j, i-j) );
+                   ++countsplit;
+                   while (i < len && isspace(str[i]))
+                   {
+                       ++i;
+                   }
+
+                   if (maxsplit && (countsplit >= maxsplit) && i < len)
+                   {
+                       result.push_back( str.substr( i, len-i ) );
+                       i = len;
+                   }
+               }
+           }
+
+           return result;
+       }
+
+       /**
+        * 
+        */
+       vector<string>
+       split( const string& str, const char* sep, int maxsplit )
+       {
+           if (sep == 0)
+               return split_whitespace( str, maxsplit );
+
+           vector<string> result;
+           int n = strlen( sep );
+           if (n == 0)
+           {
+               // Error: empty separator string
+               return result;
+           }
+           const char* s = str.c_str();
+           string::size_type len = str.length();
+           string::size_type i = 0;
+           string::size_type j = 0;
+           int splitcount = 0;
+
+           while (i+n <= len)
+           {
+               if (s[i] == sep[0] && (n == 1 || memcmp(s+i, sep, n) == 0))
+               {
+                   result.push_back( str.substr(j,i-j) );
+                   i = j = i + n;
+                   ++splitcount;
+                   if (maxsplit && (splitcount >= maxsplit))
+                       break;
+               }
+               else
+               {
+                   ++i;
+               }
+           }
+
+           result.push_back( str.substr(j,len-j) );
+           return result;
+       }
+
+       /**
+        * The lstrip(), rstrip() and strip() functions are implemented
+        * in do_strip() which uses an additional parameter to indicate what
+        * type of strip should occur.
+        */
+       const int LEFTSTRIP = 0;
+       const int RIGHTSTRIP = 1;
+       const int BOTHSTRIP = 2;
+
+       static string
+       do_strip( const string& s, int striptype )
+       {
+           //     if (s.empty())
+           //      return s;
+
+           string::size_type len = s.length();
+           string::size_type i = 0;
+           if (striptype != RIGHTSTRIP)
+           {
+               while (i < len && isspace(s[i]))
+               {
+                   ++i;
+               }
+           }
+
+           string::size_type j = len;
+           if (striptype != LEFTSTRIP)
+           {
+               do
+               {
+                   --j;
+               }
+               while (j >= 1 && isspace(s[j]));
+               ++j;
+           }
+
+           if (i == 0 && j == len)
+           {
+               return s;
+           }
+           else
+           {
+               return s.substr( i, j - i );
+           }
+       }
+
+       string
+       lstrip( const string& s )
+       {
+           return do_strip( s, LEFTSTRIP );
+       }
+
+       string
+       rstrip( const string& s )
+       {
+           return do_strip( s, RIGHTSTRIP );
+       }
+
+       string
+       strip( const string& s )
+       {
+           return do_strip( s, BOTHSTRIP );
+       }
 
+    } // end namespace strutils
+} // end namespace simgear
index 1288f7dedbab344da1c40428524786b3a7ccdd7c..ecc14a59064d0d06891e7d52d02ddc06a7928bc5 100644 (file)
@@ -3,9 +3,9 @@
  * String utilities.
  */
 
-// Written by Bernie Bright, 1998
+// Written by Bernie Bright, started 1998
 //
-// Copyright (C) 1998  Bernie Bright - bbright@c031.aone.net.au
+// Copyright (C) 1998  Bernie Bright - bbright@bigpond.net.au
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Library General Public
@@ -32,6 +32,9 @@
 
 #include STL_STRING
 
+#include <vector>
+SG_USING_STD(vector);
+
 #ifdef SG_HAVE_STD_INCLUDES
 #  include <cstdlib>
 #else
 
 SG_USING_STD(string);
 
-
-/** Default characters to remove. */
-extern const string whitespace;
-
-/** Returns a string with trailing characters removed. */
-string trimleft( const string& s, const string& trimmings = whitespace );
-
-/** Returns a string with leading characters removed. */
-string trimright( const string& s, const string& trimmings = whitespace );
-
-/** Returns a string with leading and trailing characters removed. */
-string trim( const string& s, const string& trimmings = whitespace );
-
-/** atof() wrapper for "string" type */
-inline double
-atof( const string& str )
-{
-    return ::atof( str.c_str() );
-}
-
-/** atoi() wrapper for "string" type */
-inline int
-atoi( const string& str )
-{
-    return ::atoi( str.c_str() );
-}
+namespace simgear {
+    namespace strutils {
+
+//     /** 
+//      * atof() wrapper for "string" type
+//      */
+//     inline double
+//     atof( const string& str )
+//     {
+//         return ::atof( str.c_str() );
+//     }
+
+//     /**
+//      * atoi() wrapper for "string" type
+//      */
+//     inline int
+//     atoi( const string& str )
+//     {
+//         return ::atoi( str.c_str() );
+//     }
+
+       /**
+        * Strip leading and/or trailing whitespace from s.
+        * @param s String to strip.
+        * @return The stripped string.
+        */
+       string lstrip( const string& s );
+       string rstrip( const string& s );
+       string strip( const string& s );
+
+       /**
+        * Split a string into a words using 'sep' as the delimiter string.
+        * Produces a result similar to the perl and python functions of the
+        * same name.
+        * 
+        * @param s The string to split into words,
+        * @param sep Word delimiters.  If not specified then any whitespace is a separator,
+        * @param maxsplit If given, splits at no more than maxsplit places,
+        * resulting in at most maxsplit+1 words.
+        * @return Array of words.
+        */
+       vector<string>
+       split( const string& s,
+              const char* sep = 0,
+              int maxsplit = 0 );
+
+    } // end namespace strutils
+} // end namespace simgear
 
 #endif // STRUTILS_H