Back to index

nordugrid-arc-nox  1.1.0~rc6
escaped.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <ctype.h>
00006 #include <cstring>
00007 
00008 #include "escaped.h"
00009 
00010 // TODO: not all functions can handle tabs and other non-space spaces.
00011 
00012 static int hextoint(unsigned char c) {
00013   if(c >= 'a') return (c-('a'-10));
00014   if(c >= 'A') return (c-('A'-10));
00015   return (c-'0');
00016 }
00017 
00020 void make_escaped_string(std::string &str,char e,bool escape_nonprintable) {
00021   std::string::size_type n,nn;
00022   for(nn=0;;) {
00023     if((n=str.find('\\',nn)) == std::string::npos) break;
00024     str.insert(n,"\\",1); nn=n+2;
00025   };
00026   for(nn=0;;) {
00027     if((n=str.find(e,nn)) == std::string::npos) break;
00028     str.insert(n,"\\",1); nn=n+2;
00029   };
00030   if(escape_nonprintable) for(nn=0;;) {
00031     if(isprint(str[nn])) { nn++; continue; };
00032     char buf[5];
00033     buf[0]='\\'; buf[1]='x'; buf[4]=0;
00034     buf[3]=((unsigned char)(str[nn] & 0x0f)) + '0';
00035     buf[2]=(((unsigned char)(str[nn] & 0xf0)) >> 4) + '0';
00036     if(buf[3] > '9') buf[3]+=('a'-'9'-1);
00037     if(buf[2] > '9') buf[2]+=('a'-'9'-1);
00038     str.replace(nn,1,buf); nn+=4;
00039   };
00040 }
00041 
00044 char* make_unescaped_string(char* str,char e) {
00045   size_t l = 0;
00046   char* s_end = str;
00047   // looking for end of string
00048   if(e == 0) { l=strlen(str); s_end=str+l; }
00049   else {
00050     for(;str[l];l++) {
00051       if(str[l] == '\\') { l++; if(str[l] == 0) { s_end=str+l; break; }; };
00052       if(e) { if(str[l] == e) { s_end=str+l+1; str[l]=0; break; }; };
00053     };
00054   };
00055   // unescaping
00056   if(l==0) return s_end;  // string is empty
00057   char* p  = str;
00058   char* p_ = str;
00059   for(;*p;) {
00060     if((*p) == '\\') {
00061       p++; 
00062       if((*p) == 0) { p--; } // backslash at end of string
00063       else if((*p) == 'x') { // 2 hex digits
00064         int high,low;
00065         p++; 
00066         if((*p) == 0) continue; // \x at end of string
00067         if(!isxdigit(*p)) { p--; continue; };
00068         high=*p;
00069         p++;
00070         if((*p) == 0) continue; // \x# at end of string
00071         if(!isxdigit(*p)) { p-=2; continue; };
00072         low=*p;
00073         high=hextoint(high); low=hextoint(low);
00074         (*p)=(high<<4) | low;
00075       };
00076     };
00077     (*p_)=(*p); p++; p_++;
00078   };
00079   return s_end;
00080 }
00081 
00083 void make_unescaped_string(std::string &str) {
00084   std::string::size_type p  = 0;
00085   std::string::size_type l = str.length();
00086   for(;p<l;) {
00087     if(str[p] == '\\') {
00088       p++; 
00089       if(p >= l) break; // backslash at end of string
00090       if(str[p] == 'x') { // 2 hex digits
00091         int high,low;
00092         p++; 
00093         if(p >= l) continue; // \x at end of string
00094         high=str[p];
00095         if(!isxdigit(high)) { p--; continue; };
00096         p++;
00097         if(p >= l) continue; // \x# at end of string
00098         low=str[p];
00099         if(!isxdigit(low)) { p-=2; continue; };
00100         high=hextoint(high); low=hextoint(low);
00101         str[p]=(high<<4) | low;
00102         str.erase(p-3,3); p-=3; l-=3; continue;
00103       } else { str.erase(p-1,1); l--; continue; };
00104     };
00105     p++;
00106   };
00107   return;
00108 }
00109 
00117 int input_escaped_string(const char* buf,std::string &str,char separator,char quotes) {
00118   std::string::size_type i,ii;
00119   str="";
00120   /* skip initial separators and blank spaces */
00121   for(i=0;isspace(buf[i]) || buf[i]==separator;i++) {}
00122   ii=i;
00123   if((quotes) && (buf[i] == quotes)) { 
00124     const char* e = strchr(buf+ii+1,quotes);
00125     while(e) { // look for unescaped quote
00126       if((*(e-1)) != '\\') break; // check for escaped quote
00127       e = strchr(e+1,quotes);
00128     };
00129     if(e) {
00130       ii++; i=e-buf;
00131       str.append(buf+ii,i-ii);
00132       i++;
00133       if(separator && (buf[i] == separator)) i++;
00134       make_unescaped_string(str);
00135       return i;
00136     };
00137   };
00138   // look for unescaped separator (' ' also means '\t')
00139   for(;buf[i]!=0;i++) {
00140     if(buf[i] == '\\') { // skip escape
00141       i++; if(buf[i]==0) break; continue;
00142     };
00143     if(separator == ' ') {
00144       if(isspace(buf[i])) break;
00145     } else {
00146       if(buf[i]==separator) break;
00147     };
00148   };
00149   str.append(buf+ii,i-ii);
00150   make_unescaped_string(str);
00151   if(buf[i]) i++; // skip detected separator
00152   return i;
00153 }
00154