lugre_robstring.cpp

Go to the documentation of this file.
00001 // ****** ****** ****** robstring1.2.cpp
00002 #include <stdarg.h>
00003 #include <string.h>
00004 #include <assert.h>
00005 #include "lugre_profile.h"
00006 
00007 #include "lugre_robstring.h"
00008 
00009 //#include <utils.h>
00010 
00011 
00012 namespace Lugre {
00013 
00014 
00015 // global buffer, for strprintf
00016 char    gRobStringBuffer[kRobStringBufferSize] = "";
00017 
00018 
00019 
00020 // ****** ****** ****** string generation
00021 
00022 
00023 
00024 
00025 //std::string   strprintvf  (const char* szFormat,void* arglist) {}
00026 // unused
00027 /*
00028 PROFILE
00029 gRobStringBuffer[0] = 0;
00030 vsnprintf(gRobStringBuffer,kRobStringBufferSize-1,szFormat,(va_list)arglist);
00031 return std::string(gRobStringBuffer);
00032 */
00033 
00034 void    explodestr      (const char* separator,const char* str,std::vector<std::string>& res) { PROFILE
00035     assert(separator); if (!separator) return;
00036     assert(str); if (!str) return;
00037     assert(strlen(separator)>0); if (strlen(separator)==0) return;
00038     const char* end;
00039     do {
00040         end = strstr(str,separator);
00041         if (end) {
00042             res.push_back(std::string(str,end-str));
00043             str = end + strlen(separator);
00044             if (!*str) res.push_back(std::string()); // explode("#","a#b#",res) should push 3 strings, the last one being empty
00045         } else {
00046             res.push_back(std::string(str));
00047             return;
00048         }
00049     } while (*str) ;
00050 }
00051 
00052 
00053 // ****** ****** ****** char-ranges
00054 
00055 
00056 
00057 // \ to escape, a-z as range
00058 bool    charmatchrange  (const char c,const char* r) { PROFILE
00059     for (;*r;r++)
00060         if (*r == '\\') // escaped char
00061             if (c == r[1]) return true;
00062             else r += 1; // skip escape char
00063         else if (c == *r) return true; // also valid in case of range match with start
00064         else if (r[1] == '-') // range detected
00065             if (c >= *r && c <= r[2]) return true;
00066             else r += 2; // skip range
00067     return false;
00068 }
00069 
00070 // count chars in range
00071 int     cinrange        (const char* str,const char* range) { PROFILE
00072     int c = 0;
00073     for (;*str && charmatchrange(*str,range);str++) c++;
00074     return c;
00075 }
00076 
00077 // count chars out of range
00078 int     coutrange       (const char* str,const char* range) { PROFILE
00079     int c = 0;
00080     for (;*str && !charmatchrange(*str,range);str++) c++;
00081     return c;
00082 }
00083 
00084 
00085 
00086 // ****** ****** ****** string manipulation
00087 
00088 
00089 
00090 // generate a hash value
00091 unsigned int stringhash (const char* str) { PROFILE
00092     if (!str) return 0;
00093     int res = 0;
00094     for (;*str;str++)
00095         res = (res + *str)*31;
00096     return res;
00097 }
00098 
00099 // escape backslash and quotes
00100 std::string addslashes (const char* str) { PROFILE
00101     std::string res;
00102     for (;*str;str++) {
00103         if (strchr("\\\"'",*str))
00104             res += "\\";
00105         res += *str;
00106     }
00107     return res;
00108 }
00109 
00110 
00111 
00112 // ****** ****** ****** paths
00113 
00114 
00115 
00116 const char* directory_dividers = "\\/:"; // win \\, linux /, mac :
00117 
00118 // get directory without trailing slash
00119 std::string     pathgetdir          (const std::string &path) { PROFILE
00120     return path.substr(0,path.find_last_of(directory_dividers));
00121 }
00122 
00123 // get filename only
00124 std::string     pathgetfile         (const std::string &path) { PROFILE
00125     return path.substr(path.find_last_of(directory_dividers)+1);
00126 }
00127 
00128 // get file extension including dot
00129 std::string     pathgetext          (const std::string &path) { PROFILE
00130     std::string file = pathgetfile(path);
00131     int pos = file.rfind(".");
00132     if (pos >= file.npos) return std::string("");
00133     return file.substr(pos);
00134 }
00135 
00136 // get the type of slash used in this path
00137 char            pathgetdirslash     (const std::string &path) { PROFILE
00138     int pos = path.find_last_of(directory_dividers);
00139     if (pos >= path.npos) return 0;
00140     return path[pos];
00141 }
00142 
00143 // get the drive letter (A: C: ...) in a win path , 0 if not absolute
00144 char            pathgetwindrive     (const std::string &path) { PROFILE
00145     if (path.length() >= 2 && path[1] == ':')
00146             return path[0];
00147     else    return 0;
00148 }
00149 
00150 // is the path absolute (true) or relative(false)
00151 bool            pathisabsolute      (const std::string &path) { PROFILE
00152     return pathgetwindrive(path) || path.find_first_of(directory_dividers) == 0;
00153 }
00154 
00155 // add a relative path to an absolute path
00156 std::string     pathadd     (const std::string &base,std::string &add) { PROFILE
00157     //this function can handle quite strange relative paths ;)
00158     //base must contain last slash if only dir
00159     //abs path in add overrides base
00160     if (pathisabsolute(add)) return add;
00161     char baseslash = pathgetdirslash(base);
00162     std::string s = pathgetdir(base);
00163     do {
00164         if (add.compare(0,2,"..") == 0) {
00165             // eval ../
00166             add = add.substr(3);
00167             s = pathgetdir(s);
00168         } else if (add.compare(0,1,".") == 0) {
00169             // eval ./
00170             add = add.substr(2);
00171         } else {
00172             // eval mydir/
00173             int pos = add.find_first_of(directory_dividers);
00174             if (pos == add.npos) break; // only filename left
00175             s += baseslash + add.substr(0,pos);
00176             add = add.substr(pos+1);
00177         }
00178     } while (1) ;
00179     return s + baseslash + add;
00180 }
00181 
00182 // test if one abs-path is inside another
00183 bool            pathissubpath   (const std::string &base,std::string &path) { PROFILE
00184     // pathissubpath("C:\\a\\b\\","C:/a/b/d") true
00185     // pathissubpath("C:\\a\\b\\","C:/a/c") false
00186     std::string b = base,p = path;
00187     do {
00188         int posa = b.find_first_of(directory_dividers);
00189         int posb = p.find_first_of(directory_dividers);
00190         if (posa == b.npos) return true;        // pathissubpath("C:/","C:/a") true
00191         if (posb == p.npos) return false;   // pathissubpath("C:/a","C:/") false
00192         if (b.compare(0,posa,p,0,posb) != 0) return false; // pathissubpath("C:/a","C:/b") false
00193         b = b.substr(posa+1);
00194         p = p.substr(posb+1);
00195     } while (1) ;
00196 }
00197 
00198 
00199 
00200 // ****** ****** ****** examples
00201 
00202 
00203 
00204 #if 0
00205     // string manipulation
00206     string test = "blaa44 ARGH! 'igitt' sprach der \"weise\" \\n ##";
00207     output("strtest "+test+"\n");
00208     output(string("addslashes ")+addslashes(test.c_str())+"\n");
00209     output(string("strtolower ")+strtolower(test.c_str())+"\n");
00210     output(string("strtoupper ")+strtoupper(test.c_str())+"\n");
00211     /*
00212     strtest blaa44 ARGH! 'igitt' sprach der "weise" \n ##
00213     addslashes blaa44 ARGH! \'igitt\' sprach der \"weise\" \\n ##
00214     strtolower blaa44 argh! 'igitt' sprach der "weise" \n ##
00215     strtoupper BLAA44 ARGH! 'IGITT' SPRACH DER "WEISE" \N ##
00216     */
00217 
00218     // paths
00219     string path,add;
00220     path = "C:\\zeug\\grafik\\datei.txt";
00221     add = "..\\..\\.\\zeug2\\monster\\dump.sql";
00222     output("pathadd("+path+" , "+add+") "+pathadd(path,add)+"\n");
00223     add = "../.././zeug2/../zeug3/./monster/dump.sql";
00224     output("pathadd("+path+" , "+add+") "+pathadd(path,add)+"\n");
00225     /*
00226     pathadd(C:\zeug\grafik\datei.txt , ..\..\.\zeug2\monster\dump.sql) C:\zeug2\monster\dump.sql
00227     pathadd(C:\zeug\grafik\datei.txt , ../.././zeug2/../zeug3/./monster/dump.sql) C:\zeug3\monster\dump.sql
00228     */
00229     string patharr[] = {"C:\\zeug\\grafik\\datei.txt" ,
00230                         "C:\\zeug\\grafik\\datei" ,
00231                         "C:\\zeug\\grafik\\" ,
00232                         "C:\\zeug\\grafik" ,
00233                         "C:/zeug/grafik/datei.txt" ,
00234                         "C:/zeug/grafik/datei" ,
00235                         "C:/zeug/grafik/" ,
00236                         "C:/zeug/grafik" };
00237     for (i=0;i<8;i++) {
00238         string path = patharr[i];
00239         output("pathgetdir("+path+") "+pathgetdir(path)+"\n");
00240         output("pathgetfile("+path+") "+pathgetfile(path)+"\n");
00241         output("pathgetext("+path+") "+pathgetext(path)+"\n");
00242         output("____\n");
00243     }
00244     /*
00245     pathgetdir(C:\zeug\grafik\datei.txt) C:\zeug\grafik
00246     pathgetfile(C:\zeug\grafik\datei.txt) datei.txt
00247     pathgetext(C:\zeug\grafik\datei.txt) .txt
00248     ________
00249     pathgetdir(C:\zeug\grafik\datei) C:\zeug\grafik
00250     pathgetfile(C:\zeug\grafik\datei) datei
00251     pathgetext(C:\zeug\grafik\datei)
00252     ____
00253     pathgetdir(C:\zeug\grafik\) C:\zeug\grafik
00254     pathgetfile(C:\zeug\grafik\)
00255     pathgetext(C:\zeug\grafik\)
00256     ____
00257     pathgetdir(C:\zeug\grafik) C:\zeug
00258     pathgetfile(C:\zeug\grafik) grafik
00259     pathgetext(C:\zeug\grafik)
00260     ____
00261     pathgetdir(C:/zeug/grafik/datei.txt) C:/zeug/grafik
00262     pathgetfile(C:/zeug/grafik/datei.txt) datei.txt
00263     pathgetext(C:/zeug/grafik/datei.txt) .txt
00264     ____
00265     pathgetdir(C:/zeug/grafik/datei) C:/zeug/grafik
00266     pathgetfile(C:/zeug/grafik/datei) datei
00267     pathgetext(C:/zeug/grafik/datei)
00268     ____
00269     pathgetdir(C:/zeug/grafik/) C:/zeug/grafik
00270     pathgetfile(C:/zeug/grafik/)
00271     pathgetext(C:/zeug/grafik/)
00272     ____
00273     pathgetdir(C:/zeug/grafik) C:/zeug
00274     pathgetfile(C:/zeug/grafik) grafik
00275     pathgetext(C:/zeug/grafik)
00276     ____
00277     */
00278 
00279     output(pathissubpath("C:\\a\\b\\","C:/a/c")?"true":"false"); // false
00280     output(pathissubpath("C:\\a\\b\\","C:/a/b/d")?"true":"false"); // true
00281 
00282 #endif
00283 
00284 };
00285 
00286 // ****** ****** ****** END

Generated on Wed May 23 06:00:15 2012 for cpp by  doxygen 1.5.6