proj home

Files   Classes   Functions   Hierarchy  

pathstuff.cpp

Go to the documentation of this file.
00001 #include <cassert>
00002 
00003 #include <pathstuff.h>
00004 
00005 #ifndef NDEBUG
00006 // Toggle Debug code.
00007 //#define DEBUG_PATHSTUFF
00008 #endif
00009 
00010 
00011 
00012 // Implementation
00013 // ------------------------------------------------------------ 
00014 //
00015 
00016 
00017 string const pathstuff::root = "/";
00018 string const pathstuff::fwdsep = "/";
00019 string const pathstuff::parent = "..";
00020 
00021 
00022 
00023 /* Forwards processing to rpnprogramstackstate::findprogram. */
00024 /* I haven't moved code out of there to here because at
00025  *  present I do not wish to break working code. */
00026 void pathstuff::pwd(vector<string>& v)
00027 {
00028   string path;
00029   bool found(false);
00030 
00031   deque<rpnprogram*> & ps( * rpnprogramstackstate().ps );
00032   for ( unsigned int i=0; (i<ps.size())&&(!found); ++i )
00033   {
00034     rpnprogramstackstate().findprogram(
00035       found,path,ps[i] );
00036   }
00037 //
00038 //  Replaced with for loop because the top of the
00039 //    stack could be a program.
00040 //
00041 //  rpnprogramstackstate().findprogram(
00042 //    found,path,rpnprogramstackstate().ps->front() );
00043 
00044 if (found==false)
00045 {
00046 cout << "error:";
00047 cout << "  pathstuff::pwd( vector<string>& ) pathstuff 114";
00048 cout << endl;
00049   cout << "  found=false" << endl;
00050 }
00051 
00052 //cout << "path=" << path << endl;
00053 
00054   
00055   convert(v,path);
00056 }
00057 
00058 void pathstuff::findrelativetree
00059 (
00060   bool& found,
00061   rpnprogram*& prog,
00062   rpnprogram* const current,
00063   vector<string> const & pathtree
00064 )
00065 {
00066   found = false;
00067 
00068   if (pathtree.empty())
00069   {
00070     prog = current;
00071     found = true;
00072   
00073     return;
00074   }
00075 
00076   /* Reject absolute paths. */
00077   if (pathtree[0]==root)
00078     return;
00079 
00080   /* Reject relative paths. */
00081   bool res;
00082   contains(res,pathtree,parent);
00083   if (res)
00084     return;
00085 
00086 #ifdef DEBUG_PATHSTUFF
00087 string t;
00088 convert(t,pathtree);
00089 cout << "pathtree=" << t << endl;
00090 #endif
00091 
00092   rpnprogram* p = current;
00093   rpnvar* z;
00094 
00095   bool foundlocal;
00096 
00097 #ifdef DEBUG_PATHSTUFF
00098 cout << "found=" << found << endl;
00099 #endif
00100 
00101   for (unsigned int i=0, imax = pathtree.size(); i<imax; ++i)
00102   {
00103     deque<rpnvar*>& var = p->variables;
00104     if (var.empty())
00105       return;
00106 
00107     foundlocal = false;
00108     for (unsigned int k=0, kmax=var.size(); k<kmax; ++k)
00109     {
00110        z = var[k];
00111 
00112        if ( (z->varname==pathtree[i]) && (z->x->isprogram()) )
00113        {
00114          foundlocal = true;
00115          p = (rpnprogram*)(z->x);
00116          k = kmax;
00117        }
00118     }
00119     if (!foundlocal)
00120       return;
00121   }
00122 
00123   found = true;
00124   prog = p;
00125 }
00126 
00127 
00128 bool const pathstuff::ispurerelative( vector<string> const & path )
00129 {
00130   if(path.empty())
00131     return true;
00132 
00133   if (path[0]==root)
00134     return false;
00135 
00136   bool res;
00137   contains(res,path,parent);
00138 
00139   return !res;
00140 }
00141 
00142 void pathstuff::findrelativetree
00143 (
00144   bool& found,
00145   deque<rpnprogram*>& programlist,
00146   rpnprogram* const current,
00147   vector<string> const & pathtree
00148 )
00149 {
00150   found = false;
00151   programlist.clear();
00152   programlist.push_back(current);
00153 
00154   if (pathtree.empty())
00155   {
00156     found = true;
00157 
00158     return;
00159   }
00160 
00161   if (!ispurerelative(pathtree))
00162   {
00163     programlist.clear();
00164     return;
00165   }
00166 
00167   rpnprogram* p = current;
00168   rpnvar* z;
00169 
00170   bool foundlocal;
00171 
00172   for (unsigned int i=0, imax = pathtree.size(); i<imax; ++i)
00173   {
00174     deque<rpnvar*>& var = p->variables;
00175     if (var.empty())
00176       return;
00177 
00178     for (unsigned int k=0, kmax=var.size(); k<kmax; ++k)
00179     {
00180        z = var[k];
00181        if (z->varname==pathtree[i])
00182        {
00183          foundlocal = true;
00184          p = (rpnprogram*)(z->x);
00185          programlist.push_back(p);
00186          k = kmax;
00187        }
00188     }
00189     if (!foundlocal)
00190     {
00191       programlist.clear();
00192       return;
00193     }
00194   }
00195 
00196   found = true;
00197 }
00198 
00199 
00200 void pathstuff::contains
00201 (
00202   bool& res, 
00203   vector<string> const & path, 
00204   string const & targ
00205 )
00206 {
00207   res = false;
00208 
00209   if (path.empty())
00210     return; 
00211 
00212   for (unsigned int i=0, imax=path.size(); i<imax; ++i)
00213   {
00214     if (path[i]==targ)
00215     {
00216       res = true;
00217       return;
00218     }
00219   }
00220 }
00221 
00222 
00223 void pathstuff::convert(vector<string>& v, string const & path) const
00224 {
00225   assert(false);
00226 
00227 // TODO - looking at alternative
00228 //  tokenizer tk(path);
00229 //  tk.subtract(fwdsep);
00230 
00231 // Commented out non-existing function.
00232 //  linesplit(v,path,fwdsep);
00233   if( path[0]=='/')
00234     v.insert(v.begin(),root);
00235 }
00236 
00237 void pathstuff::convert(string& s, vector<string> const & pth) const
00238 {
00239   vector<string> path(pth);
00240 
00241   s = "";
00242   if (path.empty())
00243     return;
00244 
00245   s = path[0];
00246 
00247   if (path.size()==1)
00248     return;
00249 
00250   if (path[0] != root)
00251     s += fwdsep;
00252   s += path[1]; 
00253 
00254   if (path.size()==2)
00255     return;
00256 
00257   for (unsigned int i=2, imax=path.size(); i<imax; ++i)
00258     s += ( fwdsep + path[i] );
00259 }
00260 
00261 void pathstuff::convert(rpnprogram& p, vector<string> const & path) const
00262 {
00263   if (!p.v.empty())
00264     return;
00265 
00266   if (path.empty())
00267     return;
00268 
00269   unsigned int imax = path.size();
00270   p.v.resize(imax);
00271   rpnstring *w;
00272   for (unsigned int i=0; i<imax; ++i)
00273   {
00274     
00275     p.v[i] = w = new rpnstring();
00276     w->str = path[i];
00277   }
00278 
00279 }
00280 
00281 void pathstuff::convert(vector<string>& path, rpnprogram const & p) const
00282 {
00283   path.clear();
00284 
00285   if (p.v.empty())
00286     return;
00287 
00288   path.resize( p.v.size() );
00289 
00290   /* Verify that each element is an rpnstring. */
00291   rpnbase* w;
00292   for (unsigned int i=0, imax=p.v.size(); i<imax; ++i)
00293   {
00294     w = p.v[i];
00295     if (!w->isstring())    
00296     {
00297       path.clear();
00298       return;
00299     }
00300 
00301     path[i] = ((rpnstring*)w)->str;
00302   }
00303 
00304 }
00305   
00306 
00307 //  Resolve .. as much as possible.
00308 //  eg  h1 .. g1   to  g1
00309 //  but .. cant be resolved because there is no 
00310 //  information to reslove it.
00311 void pathstuff::resolveparent
00312 (
00313   bool& valid, 
00314   vector<string>& path, 
00315   vector<string> const & path0
00316 )
00317 {
00318   valid = false;
00319   path.clear();
00320 
00321   bool res;
00322   contains(res,path0,parent);
00323   if (!res)
00324   {
00325     valid = true;
00326     path = path0;
00327     return;
00328   }
00329 
00330   if (path0[0]==parent)
00331     return;
00332 
00333   path.push_back( path0[0] );
00334   
00335   for (unsigned int i=1, imax=path0.size(); i<imax; ++i)
00336   {
00337     if (path0[i]==parent)
00338     {
00339       if (path.empty())
00340       {
00341         path.clear();
00342         return;
00343       }
00344 
00345       if (path.back()==root)
00346       {
00347         path.clear();
00348         return;
00349       }
00350 
00351       path.pop_back();
00352     }
00353     else
00354       path.push_back(path0[i]);
00355   }
00356 
00357   valid = true;
00358 
00359 }
00360 
00361 
00362 void pathstuff::findpath
00363 (
00364   bool& found,
00365   rpnprogram*& prog,
00366   vector<string> const & path
00367 )
00368 {
00369   found = false;
00370 
00371   if (path.empty())
00372     return;
00373 
00374   vector<string> v;
00375   vector<string> v2;
00376 
00377   bool res;
00378   absolute(res,v,path);
00379  
00380   if (res)
00381   {
00382     /* Remove / from the front. */
00383 
00384     unsigned int k(0);
00385     if (v[0]=="/")
00386       k=1;
00387     v2.resize(v.end()-v.begin()-k);
00388     ::copy(v.begin()+k,v.end(),v2.begin());
00389 
00390 
00391 #ifdef DEBUG_PATHSTUFF
00392 string t;
00393 convert(t,v2);
00394 cout << "-~ :" << t << endl;
00395 #endif
00396 
00397     /* From the home directory find the path. */
00398     findrelativetree
00399     (
00400       found,
00401       prog,
00402       &(rpnprogramstackstate().rpnhome),
00403       v2
00404     ); 
00405 
00406 #ifdef DEBUG_PATHSTUFF
00407 cout << "found=" << found << endl;
00408 #endif
00409 
00410   }
00411 
00412 }
00413 
00414 void pathstuff::absolute
00415 (
00416   bool& found, 
00417   vector<string>& pathfromhome, 
00418   vector<string> const & path 
00419 )
00420 {
00421   found = false;
00422 
00423   if (path.empty())
00424     return;
00425 
00426   vector<string> v(path);
00427   vector<string> v2;
00428 
00429   /* Make the path be relative to the home directory. */
00430   if (v[0] != root)
00431   {
00432     pwd(v2);
00433     ::copy(v.begin(),v.end(),back_inserter(v2));
00434   }
00435   else
00436     v2 = v;
00437 
00438 #ifdef DEBUG_PATHSTUFF
00439 string t;
00440 convert(t,v2);
00441 cout << "~:" << t << endl;
00442 #endif
00443 
00444   /* Realize the path, resolving .. . */
00445   resolveparent(found,pathfromhome,v2);
00446 }
00447 
00448 
00449 void pathstuff::findpath
00450 (
00451   bool& found,
00452   deque<rpnprogram*>& programlist,
00453   vector<string> const & path
00454 )
00455 {
00456   found = false;
00457 
00458   if (path.empty())
00459     return;
00460 
00461   vector<string> v;
00462   vector<string> v2;
00463 
00464   bool res;
00465   absolute(res,v,path);
00466 
00467 #ifdef DEBUG_PATHSTUFF
00468 cout << "res=" << res << endl;
00469 string t;
00470 convert(t,v);
00471 cout << "..:" << t << endl;
00472 #endif
00473 
00474   if (res)
00475   {
00476     /* Remove / from the front. */
00477     v2.resize(v.end()-v.begin()-1);
00478     ::copy(v.begin()+1,v.end(),v2.begin());
00479 
00480 #ifdef DEBUG_PATHSTUFF
00481 convert(t,v2);
00482 cout << "-~ :" << t << endl;
00483 #endif
00484 
00485     /* From the home directory find the path. */
00486     findrelativetree
00487     (
00488       found,
00489       programlist,
00490       rpnprogramstackstate().ps->back(),
00491       v2
00492     );
00493 
00494 #ifdef DEBUG_PATHSTUFF
00495 cout << "found=" << found << endl;
00496 #endif
00497 
00498   }
00499 
00500 }
00501 
00502 
00503 
00504 

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