proj home

Files   Classes   Functions   Hierarchy  

commandline.cpp

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <sstream>
00003 #include <string>
00004 #include <fstream>
00005 #include <map>
00006 
00007 using namespace std;
00008 
00009 /*
00010 Notes: 
00011 
00012 Limited parsing support for quoted
00013  text.
00014 
00015 A command line constructed from a
00016  string is different from a command
00017  line constructed from the actual
00018  command line because of the shell.
00019 
00020 This is bad but as the command line
00021  is so useful I have worked around
00022  by providing a subset of 1 level
00023  quoting.
00024 
00025 It could rightly be argued that I did
00026  it in the wrong place, instead
00027  of read(string&) i did it in 
00028  read(istream&).  
00029 
00030 Not sure about readfile. 
00031 */
00032 
00033 
00034 #include <commandline.h>
00035 
00036 
00037 bool splitstring
00038 (
00039   string& sleft,
00040   string& sright,
00041   stringc & s,
00042   char const delim
00043 );
00044 
00045 void readToMap(map<string,string>& m, int argc, char **argv);
00046 void writeMap(string& s, map<string,string> const & m);
00047 
00048 void commandline::readfile( stringc var )
00049 {
00050   if (var.empty())
00051     return;
00052 
00053   string file;
00054   mapvar(file,var.c_str());
00055   if (!file.empty())
00056   {
00057     ifstream f1(file.c_str());
00058     read(f1);
00059   }
00060 }
00061 
00062 
00063 commandline::commandline(int argc, char** argv)
00064 { 
00065   for (uint i=1; i<(uint)argc; ++i)
00066   {
00067     string s1, s2;
00068     if (splitstring(s1,s2,string(argv[i]),'='))
00069     {
00070       mp[s1] = s2;
00071 //cout << "*** s2=*" << s2 << "*" << endl;
00072 //cout << "*** mp[s1]=*" << mp[s1] << "*" << endl;
00073     }
00074     else
00075       tokens.insert(argv[i]);
00076     args.push_back(argv[i]);
00077   }
00078 }
00079 
00080 void commandline::read(stringc & arg)
00081 {
00082   stringstream ss(arg);
00083   read(ss);
00084 
00085 //cout << SHOW(arg) << endl;
00086 //  assert(false);
00087 }
00088 
00089 /*
00090 void commandline::read(istream & is )
00091 {
00092   string s;
00093   char ch='';
00094   if (is.eof()==false)
00095     is >> ch;
00096 
00097   for (; is.eof()==false; )
00098   {
00099     s += ch;
00100     is >> ch;
00101   }
00102 
00103   read(s);
00104 }
00105 */
00106     
00107     
00108 
00109 void commandline::read(istream & is )
00110 {
00111   string s;
00112   args.clear();
00113   vector<string>& vi(args);
00114 
00115   if (is.eof()==false)
00116     is >> s;
00117 
00118   for (; is.eof()==false; )
00119   {
00120     vi.push_back(s);
00121     s.clear();
00122     is >> s;
00123   }
00124   if (s.size()!=0)
00125     vi.push_back(s);
00126   
00127 //  for (uint i=0; i<vi.size(); ++i)
00128 //  {
00129 //cout << "*vi[" << i << "]=" <<  vi[i] << "*" << endl;
00130 //  }
00131 
00132 //Converting v to v2
00133 //*vi[0]=s1=abc*
00134 //*vi[1]=points="1*
00135 //*vi[2]=19*
00136 //*vi[3]=32*
00137 //*vi[4]=4"*
00138 //*vi[5]=N=350*
00139 //*v2[0]=s1=abc*
00140 //*v2[1]=points=1 19 32 4*
00141 //*v2[2]=N=350*
00142 
00143   if (vi.size()==0)
00144     return;
00145 
00146   vector<string> v2;
00147   bool quote=false;
00148   
00149   string::size_type k;
00150   for (uint i=0; i<vi.size(); ++i)
00151   { 
00152     string current(vi[i]);
00153     k = current.find('"');
00154  
00155     // Looking for closing quote
00156     if (quote)
00157     {
00158       if(k!=string::npos)    
00159       {
00160         current.erase(k,1);
00161         quote=false;
00162       }      
00163       v2[v2.size()-1] += (string(" ")+current);
00164     }
00165     else
00166     {
00167       if (k!=string::npos)
00168       {
00169         current.erase(k,1);
00170         quote=true;
00171       } 
00172       v2.push_back(current);
00173     }  
00174   }
00175 
00176 //  for (uint i=0; i<v2.size(); ++i)
00177 //  {
00178 //cout << "*v2[" << i << "]=" <<  v2[i] << "*" << endl;
00179 //  }
00180 
00181 
00182   // Now do parsing
00183   for (uint i=0; i<v2.size(); ++i)
00184   {
00185     string s1, s2;
00186     if (splitstring(s1,s2,v2[i],'='))
00187       mp[s1] = s2;
00188     else
00189       tokens.insert(v2[i]);
00190   }
00191 }
00192 
00193 
00194 commandline::commandline(stringc & arg)
00195 {
00196   read(arg);
00197 }
00198 
00199 commandline::commandline(istream & is)
00200 {
00201   read(is);
00202 }
00203 
00204 ostream & commandline::enablehelp(ostream & os) const
00205 {
00206   stringc hlp("-h");
00207 
00208   boolc hflag = (tokens.find(hlp)!=tokens.end());
00209   if (hflag)
00210   {
00211     for (uint i=0; i<bindvar.size(); ++i)
00212       os << bindvar[i] << " ";
00213     os << endl;
00214   }
00215 
00216   return os;
00217 }
00218 
00219 
00220 void readToMap(map<string,string>& m, int argc, char **argv)
00221 {
00222   for (uint i=1; i<(uint)argc; ++i)
00223   {
00224     string s1, s2;
00225     if (splitstring(s1,s2,string(argv[i]),'='))
00226       m[s1] = s2;
00227    }
00228 }
00229 
00230 
00231 // <TODO> Make delimit a string so function is more general, 
00232 // CE Friday 9th November 2001
00233 //
00234 
00235 bool splitstring
00236 (
00237   string& sleft, 
00238   string& sright, 
00239   stringc& s, 
00240   const char delim 
00241 )
00242 {
00243 //cout << "s=*" << s << "*" << endl;
00244 
00245   string::size_type k = s.find(delim);
00246   uint len = s.length();
00247   if (k<1 || (k>=len-1) || len==0)
00248     return false;
00249 
00250   sleft = s;
00251   sleft.erase(k);
00252   sright = s;
00253   sright.erase(0,k+1);
00254 
00255 //cout << "sright=*" << sright << "*" << endl;
00256 
00257   return true;
00258 }
00259 
00260 
00261 void writeMap(string& s, const map<string,string>& m)
00262 {
00263   string s2;
00264   map<string,string>::const_iterator i=m.begin();
00265   for(;i!=m.end();++i)
00266     s2 += (i->first + "=" + i->second + " ");
00267 
00268   s = s2;
00269 }
00270 
00271 
00272 

Generated on Fri Mar 4 00:49:29 2011 for Chelton Evans Source by  doxygen 1.5.8