Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

vul_string.cxx

Go to the documentation of this file.
00001 // This is core/vul/vul_string.cxx
00002 #include "vul_string.h"
00003 //:
00004 // \file
00005 
00006 #include <vcl_cassert.h>
00007 #include <vcl_cstdlib.h>
00008 #include <vcl_cstring.h>
00009 #include <vcl_cctype.h>
00010 #include <vcl_algorithm.h>
00011 
00012 #ifndef END_OF_STRING                           // If END_OF_STRING not defined
00013 #define END_OF_STRING (0)
00014 #endif
00015 
00016 // Converts all alphabetical characters to uppercase.
00017 char* vul_string_c_upcase(char* s)  // Convert entire string to upper case
00018 {
00019   char* p = s;                  // Point to beginning of string
00020   while (*p) {                  // While there are still valid characters
00021     if (vcl_islower(*p))        // if this is lower case
00022       *p = vcl_toupper(*p);     // convert to uppercase
00023     p++;                        // Advance pointer
00024   }
00025   return s;                     // Return reference to modified string
00026 }
00027 
00028 // Converts all alphabetical characters to lowercase.
00029 char* vul_string_c_downcase(char* s)  // Convert entire string to lower case
00030 {
00031   char* p = s;                  // Point to beginning of string
00032   while (*p) {                  // While there are still valid characters
00033     if (vcl_isupper(*p))        // if this is upper case
00034       *p = vcl_tolower(*p);     // convert to lowercase
00035     p++;                        // Advance pointer
00036   }
00037   return s;                     // Return reference to modified string
00038 }
00039 
00040 // Capitalizes all words in a string. A word is defined as
00041 // a sequence of characters separated by non-alphanumerics.
00042 char* vul_string_c_capitalize(char* s)  // Capitalize each word in string
00043 {
00044   char* p = s;                          // Point to beginning of string
00045   while (true) {                        // Infinite loop
00046     for (; *p && !vcl_isalnum(*p); p++);// Skip to first alphanumeric
00047     if (*p == END_OF_STRING)            // If end of string
00048       return s;                         // Return string
00049     *p = vcl_toupper(*p);               // Convert character
00050     while (*++p && vcl_isalnum(*p));    // Search for next word
00051   }
00052 }
00053 
00054 // Removes any occurrence of the string rem from string str,
00055 // and returns the modified string str.
00056 char* vul_string_c_trim(char* str, const char* rem) // Trim characters from string
00057 {
00058   char* s = str;
00059   char* result = str;
00060   register char c;
00061   while ((c=*s++) != END_OF_STRING) {
00062     register const char* r = rem;
00063     register char t;
00064     while ((t=*r++) != END_OF_STRING && t != c); // Scan for match
00065     if (t == END_OF_STRING)                      // If no match found
00066       *result++ = c;
00067   }
00068   *result = END_OF_STRING;                      // NULL terminate string
00069   return str;                                   // Return pointer to string
00070 }
00071 
00072 // Removes any prefix occurrence of the string rem from
00073 // the first string str, and returns the modified string str.
00074 char* vul_string_c_left_trim(char* str, const char* rem) // Trim prefix from string
00075 {
00076   char* result = str;
00077   char* s;
00078   register char c;
00079   for (s=str; (c=*s) != END_OF_STRING; s++) {
00080     register const char* r = rem;
00081     register char t;
00082     while ((t=*r++) != END_OF_STRING && t != c); // Scan for match
00083     if (t == END_OF_STRING)                      // If no match found
00084       break;
00085   }
00086   if (s != result)                               // when characters trimed
00087     while ((*result++ = *s++) != END_OF_STRING); // shift string down
00088   return str;                                    // Return pointer to string
00089 }
00090 
00091 // Removes any suffix occurrence of the string rem
00092 // from the first string str, and returns the modified string str.
00093 char* vul_string_c_right_trim(char* str, const char* rem) // Trim suffix from string
00094 {
00095   char* s = str + vcl_strlen(str) - 1;           // last character of str
00096   for (; s >= str; s--) {
00097     register const char* r = rem;
00098     register char t;
00099     register char c = *s;
00100     while ((t=*r++) != END_OF_STRING && t != c); // Scan for match
00101     if (t == END_OF_STRING)                      // If no match found
00102       break;
00103   }
00104   *(s+1) = END_OF_STRING;
00105   return str;                                     // Return pointer to string
00106 }
00107 
00108 // Reverses the order of the characters in char*.
00109 char* vul_string_c_reverse(char* c)     // Reverse the order of characters
00110 {
00111   int length = vcl_strlen(c);           // Number of characters in string
00112   char temp;
00113 
00114   for (int i = 0, j = length-1;         // Counting from front and rear
00115        i < j; ++i, --j)                 // until we reach the middle
00116   {
00117     temp = c[i];                        // Save front character
00118     c[i] = c[j];                        // Switch with rear character
00119     c[j] = temp;                        // Copy new rear character
00120   }
00121   return c;
00122 }
00123 
00124 // Reverses the order of the characters in string
00125 vcl_string& vul_string_reverse(vcl_string& s)
00126 {
00127   for (int i=0, j=vcl_strlen(s.c_str())-1; i<j; ++i,--j)
00128   {
00129     char c = s[i]; s[i] = s[j]; s[j] = c;
00130   }
00131   return s;
00132 }
00133 
00134 // In some implementations of <cctype>, toupper and tolower are macros
00135 // instead of functions.  In that case, they cannot be passed as 4th argument
00136 // to std::transform.  Hence it's easier to "inline" std::transform here,
00137 // instead of using it explicitly. - PVr.
00138 
00139 // Converts all alphabetical characters in string s to uppercase.
00140 vcl_string& vul_string_upcase(vcl_string& s)
00141 {
00142   for (vcl_string::iterator i=s.begin(); i != s.end(); ++i)
00143     *i = vcl_toupper(*i);
00144   return s;
00145 }
00146 
00147 // Converts all alphabetical characters in string s to lowercase.
00148 vcl_string& vul_string_downcase(vcl_string& s)
00149 {
00150   for (vcl_string::iterator i=s.begin(); i != s.end(); ++i)
00151     *i = vcl_tolower(*i);
00152   return s;
00153 }
00154 
00155 // Capitalizes all words in string s.
00156 vcl_string& vul_string_capitalize(vcl_string& s)
00157 {
00158   // Word beginnings are defined as the transition from
00159   // non-alphanumeric to alphanumeric, and word endings as the reverse
00160   // transition.
00161   vcl_string::iterator si;
00162   bool in_word = false;
00163   for ( si = s.begin(); si != s.end(); ++si ) {
00164     if ( !in_word && vcl_isalnum( *si ) ) {
00165       *si = vcl_toupper( *si );
00166       in_word = true;
00167     } else if ( in_word && !vcl_isalnum( *si ) ) {
00168       in_word = false;
00169     }
00170   }
00171   return s;
00172 }
00173 
00174 // Removes any occurrence of the character string rem
00175 // from the string sr, and returns the modified string sr.
00176 vcl_string& vul_string_trim(vcl_string& sr, const char* rem)
00177 {
00178   int l = vcl_strlen(rem);
00179   for (;;) {
00180     vcl_string::size_type loc = sr.find(rem);
00181     if (loc == vcl_string::npos)
00182       break;
00183     sr.erase(loc, l);
00184   }
00185   return sr;
00186 }
00187 
00188 // Removes any prefix occurrence of the character string rem
00189 // from the string sr, and returns the modified string sr.
00190 vcl_string& vul_string_left_trim(vcl_string& sr, const char* rem)
00191 {
00192   int l = vcl_strlen(rem);
00193   if (vcl_strncmp(sr.c_str(), rem, l) == 0)
00194     sr.erase(0, l);
00195   return sr;
00196 }
00197 
00198 // Removes any suffix occurrence of the character string rem
00199 // from the string sr, and returns the modified string sr.
00200 vcl_string& vul_string_right_trim(vcl_string& sr, const char* rem)
00201 {
00202   int l = vcl_strlen(rem);
00203   int lsr = sr.length();
00204   if (vcl_strncmp(sr.c_str() + lsr - l, rem, l) == 0)
00205     sr.erase(lsr - l, l);
00206   return sr;
00207 }
00208 
00209 int vul_string_atoi(vcl_string const& s)
00210 {
00211   return vcl_atoi(s.c_str());
00212 }
00213 
00214 double vul_string_atof(vcl_string const& s)
00215 {
00216   return vcl_atof(s.c_str());
00217 }
00218 
00219 static bool NotSpace(char a)
00220 {
00221   return !vcl_isspace(a);
00222 }
00223 
00224 template <class IT>
00225 static bool myequals(IT b1, IT e1,
00226                      const char * b2, const char * e2)
00227 {
00228   for (;b1 != e1 && b2 != e2; ++b1, ++b2)
00229     if (vcl_toupper(*b1) != *b2) return false;
00230   if (b1 == e1 && b2 == e2) return true;
00231   return false;
00232 }
00233 
00234 bool vul_string_to_bool(const vcl_string &str)
00235 {
00236   vcl_string::const_iterator begin = vcl_find_if(str.begin(), str.end(), NotSpace);
00237   const vcl_string::const_reverse_iterator rend(begin);
00238   vcl_string::const_iterator end = vcl_find_if(str.rbegin(), rend, NotSpace).base();
00239   const char *syes = "YES";
00240   const char *strue = "TRUE";
00241   const char *s1 = "1";
00242   const char *son = "ON";
00243   return myequals(begin, end, syes, syes+3)
00244      ||  myequals(begin, end, strue, strue+4)
00245      ||  myequals(begin, end, s1, s1+1)
00246      ||  myequals(begin, end, son, son+2);
00247 }
00248 
00249 //Leave verbatim in to avoid $->LaTeX munging.
00250 
00251 //: Expand any environment variables in the string.
00252 // \verbatim
00253 // Expands "foo$VARfoo" to "foobarfoo" when $VAR=bar. If
00254 // both $VAR and $VARfoo exists, an arbitrary choice will
00255 // be made of which variable to use. This problem can
00256 // be avoided by using the syntax "foo${VAR}foo." "$(VAR)"
00257 // and "$[VAR]" can also be used.
00258 // There are no inbuilt variables like in shell scripting, and
00259 // variable names cannot contain whitespace or "$"s. "$$"
00260 // can be used to insert a literal "$" in to the output.
00261 // \endverbatim
00262 // \returns false if a matching variable could not be found.
00263 bool vul_string_expand_var(vcl_string &str)
00264 {
00265   vcl_string::size_type i = 0; // index to current char.
00266   const vcl_string::size_type npos = vcl_string::npos;
00267 
00268   // If there is a problem, carry on trying to convert rest
00269   bool success=true; //  of string, but remember failure.
00270 
00271   enum {not_in_var, start_var, in_var, in_bracket_var} state = not_in_var;
00272   vcl_string::size_type var_begin = 0;
00273 
00274   vcl_string::size_type bracket_type = npos; //index into open_brackets.
00275   const vcl_string  open_brackets("{([");
00276   const vcl_string close_brackets("})]");
00277 
00278   while (i<str.size())
00279   {
00280     switch (state)
00281     {
00282      case not_in_var: // not currently in a variable
00283       if (str[i] == '$')
00284       {
00285         state = start_var;
00286         var_begin = i;
00287       }
00288       break;
00289      case start_var: // just started a variable
00290       if (str[i] == '$')
00291       {
00292         str.erase(i,1);
00293         state=not_in_var;
00294         continue;
00295       }
00296       else if ((bracket_type = open_brackets.find_first_of(str[i])) != npos)
00297       {
00298         state=in_bracket_var;
00299         break;
00300       }
00301       else // or this is the first letter of the variable, in which case go through
00302         state=in_var;
00303      case in_var:  // in a non-bracketed variable
00304       assert(var_begin+1 < str.size());
00305       assert(i > var_begin);
00306       if (str[i] == '$')
00307       { // no dollars allowed - assume we missed last variable and this is a new one.
00308         success=false;
00309         state = start_var;
00310         var_begin = i;
00311         break;
00312       }
00313       else
00314       {
00315         const char * value= vcl_getenv(str.substr(var_begin+1, i-var_begin).c_str());
00316         if (value)
00317         {
00318           str.replace(var_begin, i+1-var_begin, value);
00319           i = var_begin + vcl_strlen(value);
00320           state=not_in_var;
00321           continue;
00322         }
00323       }
00324       break;
00325      case in_bracket_var:  // in a bracketed variable
00326       if (str[i] == close_brackets[bracket_type])
00327       {
00328         assert(var_begin+2 < str.size());
00329         assert(i > var_begin+1);
00330         state=not_in_var;
00331         if (i==var_begin+2) // empty variable name
00332         {
00333           success=false;
00334           break;
00335         }
00336         else
00337         {
00338           const char * value= vcl_getenv(str.substr(var_begin+2, i-var_begin-2).c_str());
00339           if (value)
00340           {
00341             str.replace(var_begin, i+1-var_begin, value);
00342             i = var_begin + vcl_strlen(value);
00343             continue;
00344           }
00345           else
00346             success=false;
00347         }
00348       }
00349       break;
00350     }
00351     ++i;
00352   }
00353   return success;
00354 }

Generated on Thu Jan 10 14:41:00 2008 for core/vul by  doxygen 1.4.4