author | Michael Krelin <hacker@klever.net> | 2005-04-25 16:36:32 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2005-04-25 16:36:32 (UTC) |
commit | 981b219f5297ad2ccc1fc1d0e24e41ec009c35a3 (patch) (side-by-side diff) | |
tree | 9fa81d7fe70883ad26d946c902ba06edcebd4516 /lib | |
parent | 54e344b7e3623e807b893b7febad3adfc6c1648f (diff) | |
download | sitecing-981b219f5297ad2ccc1fc1d0e24e41ec009c35a3.zip sitecing-981b219f5297ad2ccc1fc1d0e24e41ec009c35a3.tar.gz sitecing-981b219f5297ad2ccc1fc1d0e24e41ec009c35a3.tar.bz2 |
moved a few utility functions to konforka and bumped konforka version requirement accordingly
-rw-r--r-- | lib/component_factory.cc | 31 | ||||
-rw-r--r-- | lib/configuration.cc | 9 | ||||
-rw-r--r-- | lib/sitecing_parser.ll | 13 | ||||
-rw-r--r-- | lib/sitecing_util.cc | 117 | ||||
-rw-r--r-- | lib/sitespace.cc | 3 |
5 files changed, 30 insertions, 143 deletions
diff --git a/lib/component_factory.cc b/lib/component_factory.cc index d9692de..af3d911 100644 --- a/lib/component_factory.cc +++ b/lib/component_factory.cc @@ -1,50 +1,51 @@ #ifdef USE_PCH #include "pch.h" #else #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <sys/wait.h> #include <fcntl.h> #include <iostream> #include <fstream> #include <stdexcept> #include <vector> using namespace std; + #include <konforka/util.h> #include "sitecing/component_factory.h" #include "sitecing/sitecing_util.h" #include "sitecing/sitecing_parser.h" #include "sitecing/sitecing_exception.h" #endif namespace sitecing { static const char *pp_targets[] = { ".cc", ".h", ".imports", ".classname", ".baseclassname", ".ancestors", ".pp_stamp" }; static const char *cc_targets[] = { ".o", ".d" }; component_factory::component_factory(configuration& c) : config(c), - root_source(normalize_path(c.root_source,strip_trailing_slash)+'/'), - root_intermediate(normalize_path(c.root_intermediate,strip_trailing_slash)+'/'), - root_so(normalize_path(c.root_so,strip_trailing_slash)+'/') { + root_source(konforka::normalize_path(c.root_source,konforka::strip_trailing_slash)+'/'), + root_intermediate(konforka::normalize_path(c.root_intermediate,konforka::strip_trailing_slash)+'/'), + root_so(konforka::normalize_path(c.root_so,konforka::strip_trailing_slash)+'/') { } void component_factory::get_dependencies(const string& dst,file_list_t& deps) { deps.clear(); - string dp = normalize_path(dst,strip_trailing_slash); + string dp = konforka::normalize_path(dst,konforka::strip_trailing_slash); // source documents try { // XXX: or just compare it off? string noro = strip_prefix(dp,root_source); return; }catch(utility_no_affix& una) { } // .so binaries try { string noso = strip_suffix(dp,".so"); string noro = strip_prefix(noso,root_so); deps.push_back(root_intermediate+noro+".o"); config_options *co_so_deps = config.lookup_config(noro,config_options::flag_so_deps); if(co_so_deps) { for(list<string>::const_iterator i=co_so_deps->so_deps.begin();i!=co_so_deps->so_deps.end();++i) deps.push_back(*i); } return; @@ -85,85 +86,85 @@ namespace sitecing { return; }catch(utility_no_suffix& uns) { } } // compiler targets for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) { try { string nos = strip_suffix(noro,cc_targets[cct]); deps.push_back(root_intermediate+nos+".cc"); config_options *co_cpp_deps = config.lookup_config(noro,config_options::flag_cpp_deps); if( (!co_cpp_deps) || co_cpp_deps->cpp_deps) { ifstream df((root_intermediate+nos+".d").c_str(),ios::in); if(df.good()) { string str; while(!df.eof()) { df >> str; if(str.find_first_of("\\:")==string::npos) - deps.push_back(combine_path(config.root_source+nos,str)); + deps.push_back(konforka::combine_path(config.root_source+nos,str)); } } } // XXX: intermediate_deps should be broken down config_options *co_intermediate_deps = config.lookup_config(nos,config_options::flag_intermediate_deps); if(co_intermediate_deps) { for(list<string>::const_iterator i=co_intermediate_deps->intermediate_deps.begin();i!=co_intermediate_deps->intermediate_deps.end();++i) deps.push_back(*i); } }catch(utility_no_suffix& uns) { } } }catch(utility_no_prefix& unp) { } } bool component_factory::is_uptodate(const string& dst,file_list_t *deps) { - string dp = normalize_path(dst,strip_trailing_slash); + string dp = konforka::normalize_path(dst,konforka::strip_trailing_slash); try { string noro = strip_prefix(dp,root_intermediate); for(int ppt=0;(ppt+1)<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { try { string nos = strip_suffix(noro,pp_targets[ppt]); return file_factory::is_uptodate(root_intermediate+nos+".pp_stamp",deps); }catch(utility_no_suffix& uns) { } } bool rv = file_factory::is_uptodate(dst,deps); return rv; }catch(utility_no_prefix& unp) { } // XXX: or just compare it off, instead of throwing things around. try { strip_prefix(dp,root_so); return file_factory::is_uptodate(dst,deps); }catch(utility_no_prefix& unp) { } return true; } void component_factory::build(const string& dst) { - string dp = normalize_path(dst,strip_trailing_slash); + string dp = konforka::normalize_path(dst,konforka::strip_trailing_slash); // sources try { string noro = strip_prefix(dp,root_source); // building the sources is left up to developer return; }catch(utility_no_prefix& unp) { } // .so files try { string noso = strip_suffix(dp,".so"); string noro = strip_prefix(noso,root_so); string o = root_intermediate+noro+".o"; cerr << "Linking " << noro << endl; if(access(o.c_str(),R_OK)) throw konforka::exception(CODEPOINT,string("can't access compiled component code (")+o+")"); - make_path(dir_name(root_so+noro),0755); + konforka::make_path(konforka::dir_name(root_so+noro),0755); file_lock lock_cc(root_intermediate+noro+".o.lock"); file_lock lock_so(root_so+noro+".so.lock"); int stdO = open((root_intermediate+noro+".ld.stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); if(stdO<0) throw konforka::exception(CODEPOINT,"failed to open/create linker stdout"); int stdE = open((root_intermediate+noro+".ld.stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); if(stdE<0) { close(stdO); throw konforka::exception(CODEPOINT,"failed to open/create linker stderr"); } list<string> args; config_options *co_ld_flags = config.lookup_config(noro,config_options::flag_ld_flags); if(co_ld_flags) { args.insert(args.end(),co_ld_flags->ld_flags.begin(),co_ld_flags->ld_flags.end()); } args.push_back("-shared"); @@ -182,34 +183,34 @@ namespace sitecing { throw link_error(CODEPOINT,"failed to link component",noro); return; }catch(utility_no_prefix& unp) { throw konforka::exception(CODEPOINT,"component is outside of component root"); }catch(utility_no_suffix& uns) { } try { string noro = strip_prefix(dp,root_intermediate); // compiler targets for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) { try { string nos = strip_suffix(noro,cc_targets[cct]); string cc = root_intermediate+nos+".cc"; string o = root_intermediate+nos+".o"; cerr << "Compiling " << nos << endl; if(access(cc.c_str(),R_OK)) throw konforka::exception(CODEPOINT,string("can't access preprocessed component code (")+cc+")"); - make_path(dir_name(cc),0755); - string pwd = dir_name(root_source+nos); + konforka::make_path(konforka::dir_name(cc),0755); + string pwd = konforka::dir_name(root_source+nos); auto_chdir dir_changer(pwd); file_lock lock_source(root_intermediate+nos+".lock"); file_lock lock_cc(root_intermediate+nos+".o.lock"); int stdO = open((root_intermediate+nos+".stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); if(stdO<0) throw konforka::exception(CODEPOINT,"failed to open/create compiler stdout"); int stdE = open((root_intermediate+nos+".stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); if(stdE<0) { close(stdO); throw konforka::exception(CODEPOINT,"failed to open/create compiler's stderr"); } list<string> args; config_options *co_cpp_flags = config.lookup_config(nos,config_options::flag_cpp_flags); if(co_cpp_flags) { args.insert(args.end(),co_cpp_flags->cpp_flags.begin(),co_cpp_flags->cpp_flags.end()); } @@ -222,66 +223,66 @@ namespace sitecing { args.push_back("-o"); args.push_back(o); // TODO: "g++" configurable int rv = execute("g++",args,stdO,stdE); if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) ) throw compile_error(CODEPOINT,"failed to compile component",nos); return; }catch(utility_no_suffix& uns) { } } // preprocessor targets for(int ppt=0;ppt<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { try { string nos = strip_suffix(noro,pp_targets[ppt]); string src = root_source+nos; cerr << "Preprocessing " << nos << endl; if(access(src.c_str(),R_OK)) throw konforka::exception(CODEPOINT,string("can't access component source (")+src+")"); - make_path(dir_name(root_intermediate+nos),0755); + konforka::make_path(konforka::dir_name(root_intermediate+nos),0755); file_lock lock(root_intermediate+nos+".lock"); sitecing_parser parser(*this); config_options *co_skeleton = config.lookup_config(nos,config_options::flag_skeleton); if(co_skeleton) parser.skeleton = co_skeleton->skeleton; static const char *id_chars = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - parser.class_name = normalize_path(nos,strip_leading_slash|strip_trailing_slash); + parser.class_name = konforka::normalize_path(nos,konforka::strip_leading_slash|konforka::strip_trailing_slash); for(string::size_type illc = parser.class_name.find_first_not_of(id_chars);illc!=string::npos;illc=parser.class_name.find_first_not_of(id_chars,illc)) { string::size_type lc = parser.class_name.find_first_of(id_chars,illc); int n = ((lc==string::npos)?parser.class_name.length():lc)-illc; parser.class_name.replace(illc,n,n,'_'); } parser.class_name = "_SCC_"+parser.class_name; parser.output_basename = root_intermediate+nos; parser.component_basename = nos; try { parser.preprocess(src); string sf = root_intermediate+nos+".pp_stamp"; ofstream sfs(sf.c_str(),ios::trunc|ios::out); // touch .pp_stamp }catch(preprocessor_error& pe) { pe.component_name = nos; pe.see(CODEPOINT); throw; } return; }catch(utility_no_suffix& uns) { } } }catch(utility_no_prefix& unp) { } cerr << "ignoring build request for " << dp << endl; } void component_factory::make(const string& dst) { - string dp = normalize_path(dst,strip_trailing_slash); + string dp = konforka::normalize_path(dst,konforka::strip_trailing_slash); try { string noso = strip_suffix(dp,".so"); string noro = strip_prefix(noso,root_so); file_list_t a; get_ancestors(noro,a); for(file_list_t::const_iterator i=a.begin();i!=a.end();++i) { make(root_so+*i+".so"); } }catch(utility_no_affix& una) { } file_factory::make(dst); } int component_factory::execute(const string& cmd, const list<string>& args,int stdo,int stde) { // XXX: is it right that we do stdio/stderr tricks outside of the function? // cerr << "executing: " << cmd; vector<const char*> argv(args.size()+2); @@ -304,41 +305,41 @@ namespace sitecing { _exit(-1); if(dup2(stde,2)!=2) _exit(-1); close(0); execvp(cmd.c_str(),(char**)&argv.front()); _exit(-1); } // parent close(stdo); close(stde); int rv; if(waitpid(pid,&rv,0)<0) throw konforka::exception(CODEPOINT,"failed to waitpid()"); return rv; } string component_factory::get_classname(const string& component) { - string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".classname"; + string cn = root_intermediate+konforka::normalize_path(component,konforka::strip_trailing_slash|konforka::strip_leading_slash)+".classname"; make(cn); ifstream ifs(cn.c_str()); if(!ifs.good()) throw konforka::exception(CODEPOINT,"failed to access component .classname"); ifs >> cn; return cn; } void component_factory::get_ancestors(const string& component,file_list_t& rv) { - string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".ancestors"; + string cn = root_intermediate+konforka::normalize_path(component,konforka::strip_trailing_slash|konforka::strip_leading_slash)+".ancestors"; make(cn); ifstream ifs(cn.c_str()); if(!ifs.good()) throw konforka::exception(CODEPOINT,string("failed to access component '")+component+"' .ancestors"); rv.clear(); while(!ifs.eof()) { string a; ifs >> a; if(!a.empty()) rv.push_back(a); } } } diff --git a/lib/configuration.cc b/lib/configuration.cc index 4ee1526..6b21690 100644 --- a/lib/configuration.cc +++ b/lib/configuration.cc @@ -1,24 +1,25 @@ #ifdef USE_PCH #include "pch.h" #else #include <unistd.h> #include <fnmatch.h> #include <cassert> #include <stdexcept> using namespace std; + #include <konforka/util.h> #include <dotconf.h> #include "sitecing/configuration.h" #include "sitecing/sitecing_util.h" #include "sitecing/scoreboard.h" #endif namespace sitecing { configuration::configuration() : flags(0), autobuild(false) { } configuration::configuration(const string& cfile,bool ab) : flags(0), autobuild(ab) { parse(cfile); } enum dc_ctx { @@ -291,98 +292,98 @@ namespace sitecing { if(i->regex.search(target)) return &*i; } return NULL; } string config_options::lookup_http_status_handler(const string& status) { http_status_handlers_t::const_iterator i = http_status_handlers.find(status); string rv; if(i!=http_status_handlers.end()) rv = i->second; return rv; } string configuration::lookup_http_status_handler(const string& target,const string& status) { string t = "/"; - t += normalize_path(target,strip_leading_slash); + t += konforka::normalize_path(target,konforka::strip_leading_slash); string rv; for(;;) { if(t[t.length()-1]=='/') { loaded_options* lo = lookup_loaded_options(t); if( lo && (lo->flags&config_options::flag_http_status_handlers) ) { rv = lo->lookup_http_status_handler(status); if(!rv.empty()) return rv; } } specs_t::iterator i = specs.find(t); if( i!=specs.end() && (i->second.flags&&config_options::flag_http_status_handlers) ) { rv = i->second.lookup_http_status_handler(status); if(!rv.empty()) return rv; } if(t.empty()) return rv; string::size_type sl=t.rfind('/'); if(sl==string::npos) { t.erase(); }else{ if(sl==(t.length()-1)) t.erase(sl); else t.erase(sl+1); } } } config_options::action_handler_t *configuration::lookup_action_handler(const string& target) { string t = "/"; - t += normalize_path(target,strip_leading_slash); + t += konforka::normalize_path(target,konforka::strip_leading_slash); for(;;) { if(t[t.length()-1]=='/') { loaded_options* lo = lookup_loaded_options(t); if( lo && (lo->flags&config_options::flag_action_handlers) ) { config_options::action_handler_t *rv = lo->lookup_action_handler(target); if(rv) return rv; } } specs_t::iterator i = specs.find(t); if( i!=specs.end() && (i->second.flags&&config_options::flag_action_handlers) ) { config_options::action_handler_t *rv = i->second.lookup_action_handler(target); if(rv) return rv; } if(t.empty()) return NULL; string::size_type sl=t.rfind('/'); if(sl==string::npos) { t.erase(); }else{ if(sl==(t.length()-1)) t.erase(sl); else t.erase(sl+1); } } } config_options* configuration::lookup_config(const string& target,int flag) { string t = "/"; // always assume leading slash - t += normalize_path(target,strip_leading_slash); + t += konforka::normalize_path(target,konforka::strip_leading_slash); // XXX: reconsider precedence for(;;) { if(t[t.length()-1]=='/') { loaded_options* lo = lookup_loaded_options(t); if( lo && (lo->flags&flag)==flag ) return lo; } specs_t::iterator i = specs.find(t); if( i!=specs.end() && (i->second.flags&flag)==flag ) return &(i->second); if(t.empty()) return NULL; string::size_type sl=t.rfind('/'); if(sl==string::npos) { t.erase(); }else{ @@ -401,33 +402,33 @@ namespace sitecing { if((*pat)=='+') pat++; else if((*pat)=='-') { plus = false; pat++; } if(!fnmatch(pat,fn,FNM_NOESCAPE|FNM_PATHNAME|FNM_PERIOD)) { rv = plus; return true; } } return false; } bool configuration::match_autobuild_files(const string& target,const char *fn) { string t = "/"; - t += normalize_path(target,strip_leading_slash|strip_trailing_slash); + t += konforka::normalize_path(target,konforka::strip_leading_slash|konforka::strip_trailing_slash); t += "/"; bool rv = false; for(;;) { if(t[t.length()-1]=='/') { loaded_options* lo = lookup_loaded_options(t); if(lo && (lo->flags&config_options::flag_auto_build_files) && lo->match_autobuild_files(fn,rv) ) return rv; } specs_t::iterator i = specs.find(t); if( i!=specs.end() && (i->second.flags&config_options::flag_auto_build_files) && i->second.match_autobuild_files(fn,rv) ) return rv; if(t.empty()) return rv; string::size_type sl=t.rfind('/'); if(sl==string::npos) { t.erase(); diff --git a/lib/sitecing_parser.ll b/lib/sitecing_parser.ll index 4fd6709..8dd8d5f 100644 --- a/lib/sitecing_parser.ll +++ b/lib/sitecing_parser.ll @@ -1,25 +1,26 @@ %{ /* * XXX: I have a strong feeling that this parser should be completely rewritten. */ #include <iostream> #include <fstream> #include <cassert> #include <stdexcept> using namespace std; +#include <konforka/util.h> #include "sitecing/sitecing_util.h" #include "sitecing/sitecing_exception.h" using namespace sitecing; #define sitecing_parser_flexlexer_once #include "sitecing/sitecing_parser.h" #include "sitecing/sitecing_enflesher.h" #undef yyFlexLexer #define yyFlexLexer sitecing_parserFlexLexer %} %x SLASHSTAR_COMMENT SLASHSLASH_COMMENT STRING %x CODELINE CLASSLINE DECLLINE IMPLLINE DECLBLOCK IMPLBLOCK VARLINE VARINIT %x IMPORTLINE IMPORTCOMPONENT %x IMPORTTYPELINE IMPORTTYPECOMPONENT %x DERIVELINE DERIVECOMPONENT %x CONSTRUCTOR DESTRUCTOR CODEMETHODLINE CODEMETHODARGS %x CODEMETHODBLOCK INLINE METHODLINE METHODARGS METHODBLOCK CODEBLOCK OUTPUTBLOCK @@ -284,102 +285,102 @@ NOIDCHAR [^A-Za-z0-9_] } } <IMPORTCOMPONENT>{ {WHITESPACE}+ { } \n { modus_operandi& m = M(); string::size_type t = m.output.find_first_not_of(" \t"); if(t!=string::npos) m.output.erase(0,t); t = m.output.find_last_not_of(" \t;"); if(t!=string::npos) m.output.erase(t+1); if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') { m.output.erase(0,1); m.output.erase(m.output.length()-1); } - string c = combine_path(component_basename,m.output); - member_variables.push_back(member_variable(m._type,m._name,normalize_path(c,strip_leading_slash),true)); + string c = konforka::combine_path(component_basename,m.output); + member_variables.push_back(member_variable(m._type,m._name,konforka::normalize_path(c,konforka::strip_leading_slash),true)); modi.pop_front(); BEGIN(INITIAL); } } <IMPORTTYPELINE>{ {WHITESPACE}+ { } {ID} { modus_operandi& m = M(); if(!m._name.empty()) throw preprocessor_error(CODEPOINT,"syntax error",lineno()); m._name = yytext; } \= { M().output.clear(); BEGIN(IMPORTTYPECOMPONENT); } } <IMPORTTYPECOMPONENT>{ {WHITESPACE}+ { } \n { modus_operandi& m = M(); string::size_type t = m.output.find_first_not_of(" \t"); if(t!=string::npos) m.output.erase(0,t); t = m.output.find_last_not_of(" \t;"); if(t!=string::npos) m.output.erase(t+1); if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') { m.output.erase(0,1); m.output.erase(m.output.length()-1); } - string c = combine_path(component_basename,m.output); - member_variables.push_back(member_variable(m._type,m._name,normalize_path(c,strip_leading_slash),true,true)); + string c = konforka::combine_path(component_basename,m.output); + member_variables.push_back(member_variable(m._type,m._name,konforka::normalize_path(c,konforka::strip_leading_slash),true,true)); modi.pop_front(); BEGIN(INITIAL); } } <DERIVELINE>{ {WHITESPACE}+ { } {ID} { modus_operandi& m = M(); if(!m._name.empty()) throw preprocessor_error(CODEPOINT,"syntax_error",lineno()); m._name = yytext; } \= { M().output.clear(); BEGIN(DERIVECOMPONENT); } } <DERIVECOMPONENT>{ {WHITESPACE}+ { } \n { modus_operandi& m = M(); string::size_type t = m.output.find_first_not_of(" \t"); if(t!=string::npos) m.output.erase(0,t); t = m.output.find_last_not_of(" \t;"); if(t!=string::npos) m.output.erase(t+1); if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') { m.output.erase(0,1); m.output.erase(m.output.length()-1); } - string c = combine_path(component_basename,m.output); - ancestor_classes.push_back(ancestor_class(m._name,normalize_path(c,strip_leading_slash))); + string c = konforka::combine_path(component_basename,m.output); + ancestor_classes.push_back(ancestor_class(m._name,konforka::normalize_path(c,konforka::strip_leading_slash))); modi.pop_front(); BEGIN(INITIAL); } } <VARLINE>{ {WHITESPACE}+ { modus_operandi& m = M(); if(!m.output.empty()) { if(!m._lastid.empty()) { if(!m._type.empty()) m._type += ' '; m._type += m._lastid; } m._lastid = m.output; m.output.clear(); } diff --git a/lib/sitecing_util.cc b/lib/sitecing_util.cc index f892a60..f1432df 100644 --- a/lib/sitecing_util.cc +++ b/lib/sitecing_util.cc @@ -7,106 +7,44 @@ #include <fcntl.h> #include <sys/ipc.h> #include <sys/sem.h> #include <errno.h> #include <iostream> #include <fstream> #include <cassert> #include "sitecing/sitecing_util.h" #endif namespace sitecing { /* * XXX: all of these utilities could be sheerly optimized. */ - string normalize_path(const string& path,int opts) { - const char *s = path.c_str(); - string rv; - string::size_type notslash = 0; - if( (*s)=='.' && s[1]=='/' ) - s+=2; - if(opts&strip_leading_slash) - for(;(*s) && (*s)=='/';s++); - for(;*s;s++) { - if( (*s)=='/' ) { - if(s[1]=='/') - continue; - if(s[1]=='.' && s[2]=='/') { - s+=2; - continue; - } - } - if(opts&restrict_dotdot) { - if( - ( rv.empty() && s[0]=='.' && s[1]=='.' && s[2]=='/' ) // "^../" - || ( s[0]=='/' && s[1]=='.' && s[2]=='.' && (s[3]==0 || s[3]=='/') ) // "/..(/|$)" - ) - throw utility_restricted_sequence(CODEPOINT,"restricted updir sequence encountered"); - } - rv += *s; - if( (*s) != '/' ) - notslash=rv.length(); - } - if(!(opts&strip_trailing_slash)) - notslash++; - if(notslash<rv.length()) - rv.erase(notslash); // XXX: check the logic of stripping/not strippling trailing slash - return rv; - } - string strip_prefix(const string& str,const string& prefix) { if( (str.length()<prefix.length()) || str.compare(0,prefix.length(),prefix)) throw utility_no_prefix(CODEPOINT,"no such prefix"); return str.substr(prefix.length()); } string strip_suffix(const string& str,const string& suffix) { if( (str.length()<suffix.length()) || str.compare(str.length()-suffix.length(),suffix.length(),suffix)) throw utility_no_suffix(CODEPOINT,"no such suffix"); return str.substr(0,str.length()-suffix.length()); } - string dir_name(const string& filename) { - string::size_type sl = filename.find_last_of('/'); - if(sl==string::npos) - return ""; // no slashes -- no dir. - string::size_type nosl = filename.find_last_not_of('/',sl); - if(nosl==string::npos) - return ""; // only slashes -- no dir. XXX: only slashes after the last slash... does it mean no dir? - return filename.substr(0,nosl+1); - } - - void make_path(const string& path,mode_t mode) { - struct stat st; - for(string::size_type sl=0;sl!=string::npos;sl=path.find('/',sl+1)) { - if(!sl) - continue; - string p = path.substr(0,sl); - if(stat(p.c_str(),&st) || !S_ISDIR(st.st_mode)) { - if(mkdir(p.c_str(),mode)) - throw konforka::exception(CODEPOINT,"failed to mkdir()"); - } - } - if(stat(path.c_str(),&st) || !S_ISDIR(st.st_mode)) { - if(mkdir(path.c_str(),mode)) - throw konforka::exception(CODEPOINT,"failed to mkdir()"); - } - } - void file_lock::lock(const string& f) { unlock(); fd = open(f.c_str(),O_CREAT|O_RDWR,S_IRUSR|S_IWUSR); if(fd<0) throw konforka::exception(CODEPOINT,"failed to open/create lockfile"); try { lock(); }catch(konforka::exception& ke) { ke.see(CODEPOINT); close(fd); fd=-1; throw; }catch(...) { close(fd); fd=-1; throw; } } @@ -191,87 +129,32 @@ namespace sitecing { void semaphore_lock::lock() { assert(sem); if(locked) return; sem->on(); locked = true; } void semaphore_lock::unlock() { if(!sem) return; if(!locked) return; sem->off(); locked=false; } - string combine_path(const string& origin,const string& relative,int opts) { - string r = normalize_path(relative,0); - string rv; - // XXX: what to do if relative is empty is a question, really. - if(r.empty()) { - return normalize_path( (opts&origin_is_file)?dir_name(origin):origin ,strip_leading_slash|restrict_dotdot|strip_trailing_slash); - }else{ - if(r[0]=='/') { - r.erase(0,1); - }else{ - rv = normalize_path((opts&origin_is_file)?dir_name(origin):origin,restrict_dotdot|strip_trailing_slash); - } - } - string::size_type lsl = rv.rfind('/'); - for(string::size_type sl=r.find('/');sl!=string::npos;sl=r.find('/')) { - assert(sl!=0); - if(sl==1 && r[0]=='.') { - // it's a "./" - r.erase(0,2); - }else if(sl==2 && r[0]=='.' && r[1]=='.') { - // we have a "../" - if(lsl==string::npos) { - if(rv.empty() && (opts&fail_beyond_root)) - throw utility_beyond_root(CODEPOINT,"went beyond root while combining path"); - rv.clear(); - }else{ - rv.erase(lsl); - lsl = rv.rfind('/'); - } - r.erase(0,3); - }else{ - // we have a "something/" - lsl = rv.length(); - rv += '/'; - rv += r.substr(0,sl); - r.erase(0,sl+1); - } - } - if(r.empty()) - return rv+'/'; - if(r.length()==2 && r[0]=='.' && r[0]=='.') { - if(lsl==string::npos) { - if(rv.empty() & (opts&fail_beyond_root)) - throw utility_beyond_root(CODEPOINT,"went beyond root while combining path"); - return "/"; - }else{ - rv.erase(lsl+1); - return rv; - } - } - rv += '/'; - rv += r; - return rv; - } - void auto_chdir::pushdir(const string& td,bool ap) { /* TODO: make use of fchdir(2) instead */ char *tmp = getcwd(0,0); assert(tmp); saved_pwd = tmp; free(tmp); autopop=ap; if(chdir(td.c_str())) throw konforka::exception(CODEPOINT,"failed to chdir()"); } void auto_chdir::popdir() { autopop=false; if(chdir(saved_pwd.c_str())) throw konforka::exception(CODEPOINT,"failed to chdir()"); // XXX: or should it be thrown? after all we call it from destructor... } diff --git a/lib/sitespace.cc b/lib/sitespace.cc index 0406d11..d5592bf 100644 --- a/lib/sitespace.cc +++ b/lib/sitespace.cc @@ -1,39 +1,40 @@ #ifdef USE_PCH #include "pch.h" #else #include <cassert> + #include <konforka/util.h> #include "sitecing/sitespace.h" #include "sitecing/sitecing_util.h" #endif namespace sitecing { sitespace::sitespace(configuration& c) : config(c), factory(c) { } sitespace::~sitespace() { for(sentenced_t::iterator i = sentenced.begin();i!=sentenced.end();++i) { assert((*i)->chickens_used.empty()); delete *i; } } so_component sitespace::fetch(const string& c,sitecing_interface* scif) { execute_sentenced(); - string sobase = normalize_path(c); + string sobase = konforka::normalize_path(c); string sopath = factory.root_so+sobase+".so"; config_options *co_build = config.lookup_config(sobase,config_options::flag_build); if( (!co_build) || co_build->build ) factory.make(sopath); components_t::iterator i = components.find(sopath); if(i!=components.end()) { if(i->second->is_uptodate()) return so_component(i->second,scif); if(i->second->chickens_used.empty()) { delete i->second; }else{ sentenced.push_back(i->second); } components.erase(i); } pair<components_t::iterator,bool> ins = components.insert(components_t::value_type(sopath,new component_so(sopath))); |