diff options
Diffstat (limited to '')
-rw-r--r-- | sca-cpp/trunk/kernel/dynlib.hpp | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/fstream.hpp | 23 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/gc.hpp | 4 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/kernel-test.cpp | 14 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/monad.hpp | 102 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/value.hpp | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/xml.hpp | 4 |
7 files changed, 106 insertions, 45 deletions
diff --git a/sca-cpp/trunk/kernel/dynlib.hpp b/sca-cpp/trunk/kernel/dynlib.hpp index 9f55dc4a49..484de3d666 100644 --- a/sca-cpp/trunk/kernel/dynlib.hpp +++ b/sca-cpp/trunk/kernel/dynlib.hpp @@ -80,7 +80,7 @@ private: */ template<typename S> const failable<lambda<S> > dynlambda(const string& name, const lib& l) { if (!hasContent(l.h)) - return mkfailure<lambda<S> >(reason(l.h)); + return mkfailure<lambda<S>>(l.h); const void* s = dlsym(content(l.h), c_str(name)); if (s == NULL) return mkfailure<lambda<S> >(string("Could not load symbol: ") + name); diff --git a/sca-cpp/trunk/kernel/fstream.hpp b/sca-cpp/trunk/kernel/fstream.hpp index 6afec8bd35..5ea9df2d62 100644 --- a/sca-cpp/trunk/kernel/fstream.hpp +++ b/sca-cpp/trunk/kernel/fstream.hpp @@ -329,7 +329,17 @@ logfstream cdebug(stderr, "debug"); /** * Return true if debug log is enabled. */ -#define debug_islogging() true +bool debug_isLoggingSet = false; +bool debug_isLoggingEnv = false; + +const bool debug_isLogging() { + if (debug_isLoggingSet) + return debug_isLoggingEnv; + debug_isLoggingEnv = getenv("TUSCANY_DEBUG_LOG") != NULL; + return debug_isLoggingEnv; +} + +#define debug_islogging() debug_isLogging() #endif @@ -355,7 +365,16 @@ template<typename V> const bool debugLog(const V& v, const string& msg) { return true; } -#define debug(...) if (debug_islogging()) tuscany::debugLog(__VA_ARGS__) +/** + * Log a debug message and two values. + */ +template<typename V, typename W> const bool debugLog(const V& v, const W& w, const string& msg) { + gc_scoped_pool(); + cdebug << msg << ": " << v << " : " << w << endl; + return true; +} + +#define debug(...) do { if (debug_islogging()) tuscany::debugLog(__VA_ARGS__); } while(0) #else diff --git a/sca-cpp/trunk/kernel/gc.hpp b/sca-cpp/trunk/kernel/gc.hpp index ed5482cfff..260688f4ff 100644 --- a/sca-cpp/trunk/kernel/gc.hpp +++ b/sca-cpp/trunk/kernel/gc.hpp @@ -26,6 +26,7 @@ * Garbage collected memory management, using APR memory pools. */ +#include "config.hpp" #ifdef WANT_MALLOC_MMAP #include <sys/mman.h> #include <malloc.h> @@ -36,7 +37,6 @@ #include <apr_strings.h> #include <assert.h> #include <new> -#include "config.hpp" #ifdef WANT_THREADS #include <pthread.h> #endif @@ -267,7 +267,7 @@ public: } private: - gc_scoped_pool(const unused gc_scoped_pool& pool) : gc_pool(pool.apr_pool), prev(NULL), owner(false) { + gc_scoped_pool(const gc_scoped_pool& pool) : gc_pool(pool.apr_pool), prev(NULL), owner(false) { } apr_pool_t* prev; diff --git a/sca-cpp/trunk/kernel/kernel-test.cpp b/sca-cpp/trunk/kernel/kernel-test.cpp index 9b87397b96..7bde4fb526 100644 --- a/sca-cpp/trunk/kernel/kernel-test.cpp +++ b/sca-cpp/trunk/kernel/kernel-test.cpp @@ -501,13 +501,23 @@ const failable<int> failableH(const int v) { bool testFailableMonad() { const failable<int> m(2); assert(m >> failableF == failableF(2)); - assert((m >> success<int, string>()) == m); + assert((m >> success<int, string, int>()) == m); assert(m >> failableF >> failableG == m >> failableH); cout << "Failable monad test... " << endl; - failable<int> ooops = mkfailure<int>("test"); + const failable<int> ooops = mkfailure<int>("test", 500); assert(reason(ooops) == "test"); + assert(rcode(ooops) == 500); assert(ooops >> failableF >> failableG == ooops); + + const failable<value> vooops = mkfailure<value>(ooops); + assert(reason(vooops) == "test"); + assert(rcode(vooops) == 500); + + const value v = value(vooops); + assert(car<value>(v) == value()); + assert(cadr<value>(v) == string("test")); + assert(caddr<value>(v) == value((double)500)); return true; } diff --git a/sca-cpp/trunk/kernel/monad.hpp b/sca-cpp/trunk/kernel/monad.hpp index b1bef7996c..657a809c1c 100644 --- a/sca-cpp/trunk/kernel/monad.hpp +++ b/sca-cpp/trunk/kernel/monad.hpp @@ -203,59 +203,63 @@ template<typename R, typename V> const maybe<R> operator>>(const maybe<V>& m, co * To get the value in the monad, just cast it to the value type. * To get the failure in the monad, cast it to the failure type. */ -template<typename V, typename F = string> class failable { +template<typename V, typename F = string, typename C = int> class failable { public: - failable() : hasv(false) { + failable() : hasv(false), c(-1) { } - failable(const V& v) : hasv(true), v(v) { + failable(const V& v) : hasv(true), v(v), c(-1) { } - failable(const failable<V, F>& m) : hasv(m.hasv), v(m.v), f(m.f) { + failable(const failable<V, F, C>& m) : hasv(m.hasv), v(m.v), f(m.f), c(m.c) { } - const failable<V, F>& operator=(const failable<V, F>& m) { + const failable<V, F, C>& operator=(const failable<V, F, C>& m) { if (&m == this) return *this; hasv = m.hasv; v = m.v; f = m.f; + c = m.c; return *this; } - const bool operator!=(const failable<V, F>& m) const { + const bool operator!=(const failable<V, F, C>& m) const { return !this->operator==(m); } - const bool operator==(const failable<V, F>& m) const { + const bool operator==(const failable<V, F, C>& m) const { if (this == &m) return true; if (!hasv) - return !m.hasv && f == m.f; + return !m.hasv && f == m.f && c == m.c; return m.hasv && v == m.v; } private: - failable(const bool hasv, const F& f) : hasv(hasv), f(f) { + failable(const bool hasv, const F& f, const C& c) : hasv(hasv), f(f), c(c) { } - template<typename A, typename B> friend const bool hasContent(const failable<A, B>& m); - template<typename A, typename B> friend const A content(const failable<A, B>& m); - template<typename A, typename B> friend const B reason(const failable<A, B>& m); - template<typename A, typename B> friend const failable<A, B> mkfailure(const B& f, const bool log); - template<typename A> friend const failable<A, string> mkfailure(); + template<typename A, typename B, typename R> friend const bool hasContent(const failable<A, B, R>& m); + template<typename A, typename B, typename R> friend const A content(const failable<A, B, R>& m); + template<typename A, typename B, typename R> friend const B reason(const failable<A, B, R>& m); + template<typename A, typename B, typename R> friend const R rcode(const failable<A, B, R>& m); + template<typename A, typename B, typename R> friend const failable<A, B, R> mkfailure(const B& f, const R& c, const bool log); + template<typename A, typename B> friend const failable<A, B> mkfailure(const B& f, const int c, const bool log); + template<typename A> friend const failable<A> mkfailure(); bool hasv; V v; F f; + C c; }; /** * Write a failable monad to a stream. */ -template<typename V, typename F> ostream& operator<<(ostream& out, const failable<V, F>& m) { +template<typename V, typename F, typename C> ostream& operator<<(ostream& out, const failable<V, F, C>& m) { if (!hasContent(m)) { - out << reason(m); + out << reason(m) << " : " << rcode(m); return out; } out << content(m); @@ -265,18 +269,18 @@ template<typename V, typename F> ostream& operator<<(ostream& out, const failabl /** * Returns a failable monad with a success value in it. */ -template<typename V, typename F> const failable<V, F> mksuccess(const V& v) { - return failable<V, F>(v); +template<typename V, typename F, typename C> const failable<V, F, C> mksuccess(const V& v) { + return failable<V, F, C>(v); } -template<typename V, typename F> const lambda<failable<V, F>(const V)> success() { - return mksuccess<V, F>; +template<typename V, typename F, typename C> const lambda<failable<V, F, C>(const V)> success() { + return mksuccess<V, F, C>; } /** * Returns a failable monad with a failure in it. */ -template<typename V, typename F> const failable<V, F> mkfailure(const F& f, const bool log = true) { +template<typename V, typename F, typename C> const failable<V, F, C> mkfailure(const F& f, const C& c, const bool log = true) { #ifdef WANT_MAINTAINER_LOG if (!log) debug(f, "failable::mkfailure"); @@ -285,57 +289,85 @@ template<typename V, typename F> const failable<V, F> mkfailure(const F& f, cons ostringstream os; os << f; if (length(str(os)) != 0) - cfailure << "failable::mkfailure" << ": " << f << endl; + cfailure << "failable::mkfailure" << ": " << f << " : " << c << endl; } - return failable<V, F>(false, f); + return failable<V, F, C>(false, f, c); } -template<typename V> const failable<V> mkfailure(const char* f, const bool log = true) { - return mkfailure<V, string>(string(f), log); +template<typename V, typename F> const failable<V, F> mkfailure(const F& f, const int c = -1, const bool log = true) { +#ifdef WANT_MAINTAINER_LOG + if (!log) + debug(f, c, "failable::mkfailure"); +#endif + if (log) { + ostringstream os; + os << f; + if (length(str(os)) != 0) + cfailure << "failable::mkfailure: " << str(os) << " : " << c << endl; + } + return failable<V, F>(false, f, c); +} + +template<typename V> const failable<V> mkfailure(const char* f, const int c = -1, const bool log = true) { + return mkfailure<V, string>(string(f), c, log); } template<typename V> const failable<V> mkfailure() { - return failable<V, string>(false, string()); + return failable<V, string>(false, string(), -1); +} + +template<typename V, typename F, typename C> const lambda<failable<V, F, C>(const V)> failure() { + return mkfailure<V, F, C>; } -template<typename V, typename F> const lambda<failable<V, F>(const V)> failure() { - return mkfailure<V, F>; +/** + * Convert a failable of a given type to a failable of another type. + */ +template<typename V, typename F, typename C, typename X> const failable<V, F, C> mkfailure(const failable<X, F, C>& f, const bool log = true) { + return mkfailure<V, F, C>(reason(f), rcode(f), log); } /** * Returns true if the monad contains a content. */ -template<typename V, typename F> const bool hasContent(const failable<V, F>& m) { +template<typename V, typename F, typename C> const bool hasContent(const failable<V, F, C>& m) { return m.hasv; } /** * Returns the content of a failable monad. */ -template<typename V, typename F> const V content(const failable<V, F>& m) { +template<typename V, typename F, typename C> const V content(const failable<V, F, C>& m) { return m.v; } /** * Returns the reason for failure of a failable monad. */ -template<typename V, typename F> const F reason(const failable<V, F>& m) { +template<typename V, typename F, typename C> const F reason(const failable<V, F, C>& m) { return m.f; } /** + * Returns the reason code for failure of a failable monad. + */ +template<typename V, typename F, typename C> const C rcode(const failable<V, F, C>& m) { + return m.c; +} + +/** * Bind a function to a failable monad. Passes the success value in the monad to the function * if present, or does nothing if there's no value and a failure instead. */ -template<typename R, typename FR, typename V, typename FV> -const failable<R, FR> operator>>(const failable<V, FV>& m, const lambda<failable<R, FR>(const V)>& f) { +template<typename R, typename FR, typename XR, typename V, typename FV, typename XV> +const failable<R, FR, XR> operator>>(const failable<V, FV, XV>& m, const lambda<failable<R, FR, XR>(const V)>& f) { if (!hasContent(m)) return m; return f(content(m)); } -template<typename R, typename FR, typename V, typename FV> -const failable<R, FR> operator>>(const failable<V, FV>& m, const failable<R, FR> (* const f)(const V)) { +template<typename R, typename FR, typename XR, typename V, typename FV, typename XV> +const failable<R, FR, XR> operator>>(const failable<V, FV, XV>& m, const failable<R, FR, XR> (* const f)(const V)) { if (!hasContent(m)) return m; return f(content(m)); diff --git a/sca-cpp/trunk/kernel/value.hpp b/sca-cpp/trunk/kernel/value.hpp index 3b0e9beb73..206fe8b32b 100644 --- a/sca-cpp/trunk/kernel/value.hpp +++ b/sca-cpp/trunk/kernel/value.hpp @@ -193,7 +193,7 @@ public: } value(const failable<value>& m) : type(value::List), - data(vdata(result(hasContent(m)? mklist<value>(content(m)) : mklist<value>(value(), reason(m))))) { + data(vdata(result(hasContent(m)? mklist<value>(content(m)) : rcode(m) == 1? mklist<value>(value(), reason(m)) : mklist<value>(value(), reason(m), rcode(m))))) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); diff --git a/sca-cpp/trunk/kernel/xml.hpp b/sca-cpp/trunk/kernel/xml.hpp index b53093201d..14549e5dfc 100644 --- a/sca-cpp/trunk/kernel/xml.hpp +++ b/sca-cpp/trunk/kernel/xml.hpp @@ -321,7 +321,7 @@ const failable<bool> writeList(const list<value>& l, const xmlTextWriterPtr xml) const failable<bool> write(const list<value>& l, const xmlTextWriterPtr xml, bool xmlTag) { if (xmlTag) { if (xmlTextWriterStartDocument(xml, NULL, encoding, NULL) < 0) - return mkfailure<bool>(string("xmlTextWriterStartDocument failed")); + return mkfailure<bool>("xmlTextWriterStartDocument failed"); } const failable<bool> w = writeList(l, xml); @@ -371,7 +371,7 @@ template<typename R> const failable<R> writeXML(const lambda<R(const string&, co const failable<bool> w = write(l, xml, xmlTag); xmlFreeTextWriter(xml); if (!hasContent(w)) { - return mkfailure<R>(reason(w)); + return mkfailure<R>(w); } return cx.accum; } |