Logo Search packages:      
Sourcecode: hitop version File versions

nav.cc

#include "nav.h"
#ifndef __htmlh__
  #include "html.h"
#endif
#ifndef __errorh__
  #include "error.h"
#endif

#include <vector>
#include <fstream>

static void OptPath(string& path) {
  bool isabsolute = ((!path.empty())&&(path[0]=='/'));
  bool trailingslash = false;
  int parts=0;
  list<pair<string::iterator,string::iterator> > processed;
  pair<string::iterator,string::iterator> element;
  string::iterator scanstart = path.begin();
  string::iterator scanend = path.end();
  if (isabsolute) ++scanstart;
  while (scanstart!=path.end()) {
    scanend=find(scanstart,path.end(),'/');
    element=make_pair<string::iterator,string::iterator>(scanstart,scanend);
    scanstart=scanend;
    if (scanend!=path.end()) {
      ++scanstart;
      if (scanstart==path.end()) trailingslash=true;
    }
    if ((element.second-element.first==1) && (*(element.first)=='.')) continue;
    if ((element.second-element.first==2) && (element.first[0]=='.') && (element.first[1]=='.')) {
      if (parts>0) {
        processed.pop_back();
        --parts;
      } else {
        processed.push_back(element);
      }
    } else {
      processed.push_back(element);
      ++parts;
    }
  }
  string result;
  if (isabsolute) {
    result="/";
  }
  for(list<pair<string::iterator,string::iterator> >::iterator i=processed.begin();i!=processed.end();) {
    result.append(i->first,i->second);
    if (++i!=processed.end()||trailingslash) result+='/';
  }
  path=result;
}

static string RelPath(string current,string dest){
  string result;
  OptPath(current);
  OptPath(dest);
  if(isAbsolute(dest)) return dest;
  string::iterator a=current.begin();
  string::iterator b=dest.begin();
  while ((a!=current.end())&&(b!=dest.end())&&(*a==*b)) {
    ++a;
    ++b;
  }
  int c = count(a,current.end(),'/');
  if (b!=dest.begin()) {
    --b;
    while ((b!=dest.begin())&&(*b!='/')) {
      --b;
    }
  }
  if ((b!=dest.end())&&(b!=dest.begin())) ++b;
  while (c-->0) {
    result+="../";
  }
  result.append(b,dest.end());
  return result;
}

void Nav::Set(HTMLStream& stream,HTMLStream::iterator cur,
  const string& data,const string& URLPath,NavStore::OutputFormat format){
  enum State{ExpectLHS,ExpectRHS,ExpectLevel};
  State curState=ExpectLHS;
  int level=0;
  string left,right;
  for(string::const_iterator i=data.begin();i!=data.end();++i){
    switch(curState){
    case ExpectLHS:
      if(*i=='=') curState=ExpectRHS; else left+=*i;
      break;
    case ExpectRHS:
      if(right.empty()&&(*i=='(')){
        m_data.addtolevel(cur,level,left,"");
        left.erase();
        right.erase();
        curState=ExpectLHS;
        ++level;
      }else{
        if((*i==',')||(*i==')')){
          m_data.addtolevel(cur,level,left,right);
          left.erase();
          right.erase();        
          if(*i==','){
            curState=ExpectLHS;
          }else{
            --level;
            if(level<0) Error(*cur,e_DataBadFormat);
            curState=ExpectLevel;
          }
        }else{
          right+=*i;
        }
      }
      break;
    case ExpectLevel:
      if(*i==','){
        curState=ExpectLHS;
      }else if(*i==')'){
        --level;
        if(level<0) Error(*cur,e_DataBadFormat);
        curState=ExpectLevel;
      }else{
        Error(*cur,e_DataBadFormat);
      }
    }
  }
  if(curState==ExpectRHS) m_data.addtolevel(cur,level,left,right);
  if((level!=0)||(curState==ExpectLHS)) Error(*cur,e_DataBadFormat);
  m_data.verify(cur,FilePart(URLPath),format);
}

void Nav::Load(HTMLStream& stream,HTMLStream::iterator Cur,
  const string& filename,const string& URLPath,
  NavStore::OutputFormat format){
  ifstream navfile(filename.c_str());
  if (!navfile.is_open()) Error(*Cur,"Unable to open Navfile");
  string line;
  string::iterator namestart,nameend,valuestart,valueend;
  int level;
  string curFilename;
  stream.m_curVars.Get(*Cur,"FILE",curFilename);
  string pp = PathPart(filename);
  while (!navfile.eof()) {
    getline(navfile,line);
    if (navfile.eof()) break;
    namestart=line.begin();
    if (*namestart=='#') continue;
    level=0;
    while((namestart!=line.end()) && (*namestart==' ')) {
      ++level;
      ++namestart;
    }
    if (namestart==line.end()) Error(*Cur,"Invalid (blank?) line in Nav File");
    nameend=find(namestart,line.end(),'=');
    if (nameend==line.end()) Error(*Cur,"Invalid (Missing '='?)line in Nav File");
    valuestart=nameend;
    ++valuestart;
    valueend=line.end();
    string url(valuestart,valueend);
    //if ((!url.empty()) &&(!isAbsolute(url))) url=RelPath(PathPart(filename),url);
    if ((!url.empty()) &&(!isAbsolute(url))){
      url=RelPath(curFilename,RelPath(pp,url));
    }
    m_data.addtolevel(Cur,level,string(namestart,nameend),url);
  }
  m_data.verify(Cur,FilePart(URLPath),format);
}

void Nav::Execute(HTMLStream& stream,HTMLStream::iterator Cur,
  const ParamMap& paramMap,NavStore::OutputFormat format,
  TokenMap::Token preToken,TokenMap::Token entryToken,
  TokenMap::Token postToken,int from,int to) {
  switch (format) {
    case NavStore::of_flat :
      m_data.DoFlat(stream,Cur,paramMap,preToken,entryToken,postToken,from,to);
      break;
    default :
      m_data.DoOpen(stream,Cur,paramMap,preToken,entryToken,postToken,from,to);
  }
}


Generated by  Doxygen 1.6.0   Back to index