Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/putil/string_utils.cxx

Go to the documentation of this file.
00001 // Filename: string_utils.cxx
00002 // Created by:  drose (18Jan99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "string_utils.h"
00020 
00021 #include <ctype.h>
00022 
00023 // Case-insensitive string comparison, from Stroustrup's C++ third edition.
00024 // Works like strcmp().
00025 int
00026 cmp_nocase(const string &s, const string &s2) {
00027   string::const_iterator p = s.begin();
00028   string::const_iterator p2 = s2.begin();
00029 
00030   while (p != s.end() && p2 != s2.end()) {
00031     if (toupper(*p) != toupper(*p2)) {
00032       return (toupper(*p) < toupper(*p2)) ? -1 : 1;
00033     }
00034     ++p;
00035     ++p2;
00036   }
00037 
00038   return (s2.size() == s.size()) ? 0 :
00039     (s.size() < s2.size()) ? -1 : 1;  // size is unsigned
00040 }
00041 
00042 INLINE int
00043 toupper_uh(int ch) {
00044   return (ch == '_') ? '-' : toupper(ch);
00045 }
00046 
00047 
00048 int
00049 cmp_nocase_uh(const string &s, const string &s2) {
00050   string::const_iterator p = s.begin();
00051   string::const_iterator p2 = s2.begin();
00052 
00053   while (p != s.end() && p2 != s2.end()) {
00054     if (toupper_uh(*p) != toupper_uh(*p2)) {
00055       return (toupper_uh(*p) < toupper_uh(*p2)) ? -1 : 1;
00056     }
00057     ++p;
00058     ++p2;
00059   }
00060 
00061   return (s2.size() == s.size()) ? 0 :
00062     (s.size() < s2.size()) ? -1 : 1;  // size is unsigned
00063 }
00064 
00065 
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: downcase
00069 //  Description: Returns the input string with all uppercase letters
00070 //               converted to lowercase.
00071 ////////////////////////////////////////////////////////////////////
00072 string
00073 downcase(const string &s) {
00074   string result;
00075   result.reserve(s.size());
00076   string::const_iterator p;
00077   for (p = s.begin(); p != s.end(); ++p) {
00078     result += tolower(*p);
00079   }
00080   return result;
00081 }
00082 
00083 ////////////////////////////////////////////////////////////////////
00084 //     Function: upcase
00085 //  Description: Returns the input string with all lowercase letters
00086 //               converted to uppercase.
00087 ////////////////////////////////////////////////////////////////////
00088 string
00089 upcase(const string &s) {
00090   string result;
00091   result.reserve(s.size());
00092   string::const_iterator p;
00093   for (p = s.begin(); p != s.end(); ++p) {
00094     result += toupper(*p);
00095   }
00096   return result;
00097 }
00098 
00099 
00100 ////////////////////////////////////////////////////////////////////
00101 //     Function: extract_words
00102 //  Description: Divides the string into a number of words according
00103 //               to whitespace.  The words vector should be cleared by
00104 //               the user before calling; otherwise, the list of words
00105 //               in the string will be appended to the end of whatever
00106 //               was there before.
00107 //
00108 //               The return value is the number of words extracted.
00109 ////////////////////////////////////////////////////////////////////
00110 int
00111 extract_words(const string &str, vector_string &words) {
00112   int num_words = 0;
00113 
00114   size_t pos = 0;
00115   while (pos < str.length() && isspace((unsigned int)str[pos])) {
00116     pos++;
00117   }
00118   while (pos < str.length()) {
00119     size_t word_start = pos;
00120     while (pos < str.length() && !isspace((unsigned int)str[pos])) {
00121       pos++;
00122     }
00123     words.push_back(str.substr(word_start, pos - word_start));
00124     num_words++;
00125 
00126     while (pos < str.length() && isspace((unsigned int)str[pos])) {
00127       pos++;
00128     }
00129   }
00130 
00131   return num_words;
00132 }
00133 
00134 ////////////////////////////////////////////////////////////////////
00135 //     Function: tokenize
00136 //  Description: Chops the source string up into pieces delimited by
00137 //               any of the characters specified in delimiters.
00138 //               Repeated delimiter characters represent zero-length
00139 //               tokens.
00140 //
00141 //               It is the user's responsibility to ensure the output
00142 //               vector is cleared before calling this function; the
00143 //               results will simply be appended to the end of the
00144 //               vector.
00145 ////////////////////////////////////////////////////////////////////
00146 void
00147 tokenize(const string &str, vector_string &words, const string &delimiters) {
00148   size_t p = 0;
00149   while (p < str.length()) {
00150     size_t q = str.find_first_of(delimiters, p);
00151     if (q == string::npos) {
00152       words.push_back(str.substr(p));
00153       return;
00154     }
00155     words.push_back(str.substr(p, q - p));
00156     p = q + 1;
00157   }
00158   words.push_back(string());
00159 }
00160 
00161 ////////////////////////////////////////////////////////////////////
00162 //     Function: trim_left
00163 //  Description: Returns a new string representing the contents of the
00164 //               given string with the leading whitespace removed.
00165 ////////////////////////////////////////////////////////////////////
00166 string
00167 trim_left(const string &str) {
00168   size_t begin = 0;
00169   while (begin < str.size() && isspace((unsigned int)str[begin])) {
00170     begin++;
00171   }
00172 
00173   return str.substr(begin);
00174 }
00175 
00176 ////////////////////////////////////////////////////////////////////
00177 //     Function: trim_right
00178 //  Description: Returns a new string representing the contents of the
00179 //               given string with the trailing whitespace removed.
00180 ////////////////////////////////////////////////////////////////////
00181 string
00182 trim_right(const string &str) {
00183   size_t begin = 0;
00184   size_t end = str.size();
00185   while (end > begin && isspace((unsigned int)str[end - 1])) {
00186     end--;
00187   }
00188 
00189   return str.substr(begin, end - begin);
00190 }
00191 
00192 ////////////////////////////////////////////////////////////////////
00193 //     Function: string_to_int
00194 //  Description: A string-interface wrapper around the C library
00195 //               strtol().  This parses the ASCII representation of an
00196 //               integer, and then sets tail to everything that
00197 //               follows the first valid integer read.  If, on exit,
00198 //               str == tail, there was no valid integer in the
00199 //               source string; if !tail.empty(), there was garbage
00200 //               after the integer.
00201 //
00202 //               It is legal if str and tail refer to the same string.
00203 ////////////////////////////////////////////////////////////////////
00204 int
00205 string_to_int(const string &str, string &tail) {
00206   const char *nptr = str.c_str();
00207   char *endptr;
00208   int result = strtol(nptr, &endptr, 10);
00209   tail = endptr;
00210   return result;
00211 }
00212 
00213 ////////////////////////////////////////////////////////////////////
00214 //     Function: string_to_int
00215 //  Description: Another flavor of string_to_int(), this one returns
00216 //               true if the string is a perfectly valid integer (and
00217 //               sets result to that value), or false otherwise.
00218 ////////////////////////////////////////////////////////////////////
00219 bool
00220 string_to_int(const string &str, int &result) {
00221   string tail;
00222   result = string_to_int(str, tail);
00223   return tail.empty();
00224 }
00225 
00226 ////////////////////////////////////////////////////////////////////
00227 //     Function: string_to_double
00228 //  Description: A string-interface wrapper around the C library
00229 //               strtol().  This parses the ASCII representation of an
00230 //               floating-point number, and then sets tail to
00231 //               everything that follows the first valid integer read.
00232 //               If, on exit, str == tail, there was no valid integer
00233 //               in the source string; if !tail.empty(), there was
00234 //               garbage after the number.
00235 //
00236 //               It is legal if str and tail refer to the same string.
00237 ////////////////////////////////////////////////////////////////////
00238 double
00239 string_to_double(const string &str, string &tail) {
00240   const char *nptr = str.c_str();
00241   char *endptr;
00242   double result = strtod(nptr, &endptr);
00243   tail = endptr;
00244   return result;
00245 }
00246 
00247 ////////////////////////////////////////////////////////////////////
00248 //     Function: string_to_double
00249 //  Description: Another flavor of string_to_double(), this one
00250 //               returns true if the string is a perfectly valid
00251 //               number (and sets result to that value), or false
00252 //               otherwise.
00253 ////////////////////////////////////////////////////////////////////
00254 bool
00255 string_to_double(const string &str, double &result) {
00256   string tail;
00257   result = string_to_double(str, tail);
00258   return tail.empty();
00259 }
00260 
00261 ////////////////////////////////////////////////////////////////////
00262 //     Function: string_to_float
00263 //  Description: Another flavor of string_to_float(), this one
00264 //               returns true if the string is a perfectly valid
00265 //               number (and sets result to that value), or false
00266 //               otherwise.
00267 ////////////////////////////////////////////////////////////////////
00268 bool
00269 string_to_float(const string &str, float &result) {
00270   string tail;
00271   result = (float)string_to_double(str, tail);
00272   return tail.empty();
00273 }

Generated on Fri May 2 00:43:42 2003 for Panda by doxygen1.3