path.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) Sergey P. Derevyago, 2008.
00003  *
00004  * Permission to copy, use, modify, sell and distribute this software is granted
00005  * provided this copyright notice appears in all copies.
00006  * This software is provided "as is" without express or implied warranty, and
00007  * with no claim as to its suitability for any purpose.
00008  *
00009  */
00010 
00015 #include <ders/path.hpp>
00016 
00017 namespace {
00018 
00019 using namespace ders;
00020 
00021 inline bool sepr(char ch)
00022 {
00023  return ch=='\\' || ch=='/';
00024 }
00025 
00026 ch_rng fname(const char* beg, const char* end)
00027 {
00028  const char* ptr=beg;
00029  for ( ; ptr<end && !sepr(*ptr); ptr++)
00030      ;
00031 
00032  return ch_rng(beg, ptr);
00033 }
00034 
00035 ch_rng fsepr(const char* beg, const char* end)
00036 {
00037  const char* ptr=beg;
00038  for ( ; ptr<end && sepr(*ptr); ptr++)
00039      ;
00040 
00041  return ch_rng(beg, ptr);
00042 }
00043 
00044 }  // unnamed
00045 
00046 namespace ders {  // ::ders
00047 
00048 void parse_path(mem_pool&, const ch_rng& path, std::vector<path_elmt>& ret)
00049 {
00050  ret.clear();
00051 
00052  const char* ptr=path.beg;
00053 
00054  if (path.end-ptr>=5) {  // "\\a\b"
00055     ch_rng spr=fsepr(ptr, path.end);
00056     if (spr.size()==2) {
00057        ch_rng srv=fname(spr.end, path.end);
00058        if (srv.size()>0) {
00059           ch_rng spr2=fsepr(srv.end, path.end);
00060           if (spr2.size()==1) {
00061              ch_rng shr=fname(spr2.end, path.end);
00062              if (shr.size()>0) {
00063                 ret.push_back(path_elmt(path_elmt::share, ch_rng(ptr,
00064                   shr.end)));
00065                 ptr=fsepr(shr.end, path.end).end;
00066              }
00067           }
00068        }
00069     }
00070  }
00071 
00072  if (path.end-ptr>=2) {  // "A:"
00073     ch_rng nm=fname(ptr, path.end);
00074     if (nm.size()>=2 && nm.beg[1]==':') {
00075        nm.end=nm.beg+2;
00076        ret.push_back(path_elmt(path_elmt::drive, nm));
00077        ptr=nm.end;
00078     }
00079  }
00080 
00081  ch_rng spr=fsepr(ptr, path.end);
00082  if (spr.size()>0) {  // "\"
00083     ret.push_back(path_elmt(path_elmt::root, ch_rng(ptr, ptr+1)));
00084     ptr=spr.end;
00085  }
00086 
00087  for (;;) {
00088      ch_rng nm=fname(ptr, path.end);
00089      if (nm.size()<=0) break;
00090 
00091      ret.push_back(path_elmt(path_elmt::name, nm));
00092      ptr=fsepr(nm.end, path.end).end;
00093  }
00094 }
00095 
00096 sh_text make_path(mem_pool& mp, const path_elmt* beg, const path_elmt* end, char
00097   spr)
00098 {
00099  sh_text ret(nt(mp));
00100  ret->reserve(512);
00101 
00102  for (const path_elmt* ptr=beg; ptr<end; ptr++) {
00103      switch (ptr->tp) {
00104             case path_elmt::drive: {
00105                  assert(ptr==beg);
00106 
00107                  ret->append(ptr->nm);
00108                  break;
00109             }
00110             case path_elmt::name: {
00111                  if (ptr>beg && (ptr[-1].tp==path_elmt::name ||
00112                      ptr[-1].tp==path_elmt::share))
00113                     ret->append(spr);
00114 
00115                  ret->append(ptr->nm);
00116                  break;
00117             }
00118             case path_elmt::root: {
00119                  assert(ptr==beg || ptr==beg+1&&beg->tp==path_elmt::drive);
00120                  assert(ptr->nm.size()==1);
00121 
00122                  ret->append(spr);
00123                  break;
00124             }
00125             case path_elmt::share: {
00126                  assert(ptr==beg);
00127 
00128                  ret->append(ptr->nm);
00129                  break;
00130             }
00131             default: assert(false);
00132      }
00133  }
00134 
00135  return ret;
00136 }
00137 
00138 sh_text normalize_path(mem_pool& mp, const ch_rng& path)
00139 {
00140  std::vector<path_elmt> vpe;
00141  parse_path(mp, path, vpe);
00142  return make_path(mp, &*vpe.begin(), &*vpe.end());
00143 }
00144 
00145 sh_text get_path(mem_pool& mp, const ch_rng& path)
00146 {
00147  std::vector<path_elmt> vpe;
00148  parse_path(mp, path, vpe);
00149 
00150  const path_elmt *beg=&*vpe.begin(), *end=&*vpe.end();
00151  if (end>beg && (end-1)->tp==path_elmt::name) end--;
00152 
00153  return make_path(mp, beg, end);
00154 }
00155 
00156 sh_text get_name(mem_pool& mp, const ch_rng& path)
00157 {
00158  std::vector<path_elmt> vpe;
00159  parse_path(mp, path, vpe);
00160 
00161  if (vpe.size() && vpe.back().tp==path_elmt::name) return nt(mp, vpe.back().nm);
00162  return nt(mp);
00163 }
00164 
00165 }  // namespace ::ders
00166 

Generated on Tue Dec 8 11:35:32 2009 for derslib by  doxygen 1.5.5