summaryrefslogtreecommitdiffabout
path: root/lib
authorMichael Krelin <hacker@klever.net>2005-04-25 16:36:32 (UTC)
committer Michael Krelin <hacker@klever.net>2005-04-25 16:36:32 (UTC)
commit981b219f5297ad2ccc1fc1d0e24e41ec009c35a3 (patch) (side-by-side diff)
tree9fa81d7fe70883ad26d946c902ba06edcebd4516 /lib
parent54e344b7e3623e807b893b7febad3adfc6c1648f (diff)
downloadsitecing-981b219f5297ad2ccc1fc1d0e24e41ec009c35a3.zip
sitecing-981b219f5297ad2ccc1fc1d0e24e41ec009c35a3.tar.gz
sitecing-981b219f5297ad2ccc1fc1d0e24e41ec009c35a3.tar.bz2
moved a few utility functions to konforka and bumped konforka version requirement accordingly
Diffstat (limited to 'lib') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/component_factory.cc31
-rw-r--r--lib/configuration.cc9
-rw-r--r--lib/sitecing_parser.ll13
-rw-r--r--lib/sitecing_util.cc117
-rw-r--r--lib/sitespace.cc3
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)));