Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

string_util.cc

Go to the documentation of this file.
00001 #include "string_util.h"
00002 #include <cctype>
00003 #include <locale>
00004 #include <pwd.h>
00005 #include <stdlib.h>
00006 #include <regex.h>
00007 
00008 using namespace std;
00009 
00010 namespace string_util {
00011 
00012   //! reference to the current standard library 'locale'
00013   static const std::locale& curLocale=std::locale::classic();
00014   
00015   char localeToUpper(char c) {
00016     return std::toupper(c,curLocale);
00017   }
00018 
00019   char localeToLower(char c) {
00020     return std::tolower(c,curLocale);
00021   }
00022   
00023   string makeUpper(const string& s) {
00024     string ans(s); // yes, I actually checked if it's faster to copy and then overwrite or reserve and use std::back_inserter(ans)
00025     std::transform(ans.begin(), ans.end(), ans.begin(), (int(*)(int)) std::toupper);
00026     return ans;
00027   }
00028   
00029   string makeLower(const string& s) {
00030     string ans(s);
00031     std::transform(ans.begin(), ans.end(), ans.begin(), (int(*)(int)) std::tolower);
00032     return ans;
00033   }
00034 
00035   string removePrefix(const string& str, const string& pre) {
00036     if(str.compare(0,pre.size(),pre)==0)
00037       return str.substr(pre.size());
00038     return string();
00039   }
00040   
00041   string tildeExpansion(const string& str) {
00042     string ans;
00043     if(str[0]!='~') {
00044       return str;
00045     }
00046 #ifndef PLATFORM_APERIOS
00047     else if(str=="~" || str[1]=='/') {
00048       char* home=getenv("HOME");
00049       if(home==NULL)
00050         return str;
00051       if(str=="~")
00052         return home;
00053       return home+str.substr(1);
00054     } else {
00055       string::size_type p=str.find('/');
00056       struct passwd * pw;
00057       pw=getpwnam(str.substr(1,p-1).c_str());
00058       if(pw==NULL)
00059         return str;
00060       return pw->pw_dir+str.substr(p);
00061     }
00062 #else
00063     return str.substr(1);
00064 #endif
00065   }
00066 
00067   string trim(const string& str) {
00068     if(str.size()==0)
00069       return str;
00070     unsigned int b=0;
00071     unsigned int e=str.size()-1;
00072     while(b<str.size() && isspace(str[b]))
00073       b++;
00074     while(b<e && isspace(str[e]))
00075       e--;
00076     return str.substr(b,e-b+1);
00077   }
00078   
00079   bool parseArgs(const string& input, vector<string>& args, vector<unsigned int>& offsets) {
00080     string cur;
00081     bool isDoubleQuote=false;
00082     bool isSingleQuote=false;
00083     args.clear();
00084     offsets.clear();
00085     unsigned int begin=-1U;
00086     for(unsigned int i=0; i<input.size(); i++) {
00087       char c=input[i];
00088       if(begin==-1U && !isspace(c))
00089         begin=i;
00090       switch(c) {
00091       case ' ':
00092       case '\n':
00093       case '\r':
00094       case '\t':
00095       case '\v':
00096       case '\f':
00097         if(isSingleQuote || isDoubleQuote)
00098           cur+=c;
00099         else if(cur.size()!=0) {
00100           args.push_back(cur);
00101           offsets.push_back(begin);
00102           cur.clear();
00103           begin=-1U;
00104         }
00105         break;
00106       case '\\':
00107         if(i==input.size()-1) { //escaped line break
00108           return false;
00109         } else
00110           cur.push_back(input[++i]);
00111         break;
00112       case '"':
00113         if(isSingleQuote)
00114           cur.push_back(c);
00115         else
00116           isDoubleQuote=!isDoubleQuote;
00117         break;
00118       case '\'':
00119         if(isDoubleQuote)
00120           cur+=c;
00121         else
00122           isSingleQuote=!isSingleQuote;
00123         break;
00124       default:
00125         cur+=c;
00126         break;
00127       }
00128     }
00129     if(cur.size()>0) {
00130       args.push_back(cur);
00131       offsets.push_back(begin);
00132     }
00133     return !isDoubleQuote && !isSingleQuote;
00134   }
00135 
00136   bool reMatch(const std::string& str, const std::string& regex) {
00137     return reMatch(str,regex,REG_EXTENDED);
00138   }
00139   
00140   bool reMatch(const std::string& str, const std::string& regex, int flags) {
00141     regex_t re;
00142     if(int err=regcomp(&re,regex.c_str(),flags | REG_NOSUB)) {
00143       char msg[128];
00144       regerror(err,&re,msg,128);
00145       string errmsg;
00146       errmsg.append("Bad filter '").append(regex).append("': ").append(msg);
00147       regfree(&re);
00148       throw errmsg;
00149     }
00150     int match=regexec(&re,str.c_str(),0,NULL,0);
00151     regfree(&re);
00152     if(match==0) {
00153       return true;
00154     } else if(match==REG_NOMATCH) {
00155       return false;
00156     } else {
00157       char msg[128];
00158       regerror(match,&re,msg,128);
00159       string errmsg;
00160       errmsg.append("Regex error on reMatch('").append(str).append("', '").append(regex).append("'): ").append(msg);
00161       throw errmsg;
00162     }
00163   }
00164 
00165 }
00166 
00167 /*! @file
00168  * @brief Implements some useful functions for string manipulation in the string_util namespace
00169  * @author ejt (Creator)
00170  *
00171  * $Author: ejt $
00172  * $Name: tekkotsu-4_0 $
00173  * $Revision: 1.12 $
00174  * $State: Exp $
00175  * $Date: 2007/11/09 19:01:14 $
00176  */

Tekkotsu v4.0
Generated Thu Nov 22 00:54:56 2007 by Doxygen 1.5.4