summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/trunk/kernel')
-rw-r--r--sca-cpp/trunk/kernel/dynlib.hpp2
-rw-r--r--sca-cpp/trunk/kernel/fstream.hpp23
-rw-r--r--sca-cpp/trunk/kernel/gc.hpp4
-rw-r--r--sca-cpp/trunk/kernel/kernel-test.cpp14
-rw-r--r--sca-cpp/trunk/kernel/monad.hpp102
-rw-r--r--sca-cpp/trunk/kernel/value.hpp2
-rw-r--r--sca-cpp/trunk/kernel/xml.hpp4
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;
}