From 157ca678dee75e7881a0198425d0c8328f0bee04 Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Thu, 3 Jan 2013 07:41:02 +0000 Subject: Improve handling of nested lists, trees, null and floating point values. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1428191 13f79535-47bb-0310-9956-ffa450edef68 --- sca-cpp/trunk/components/chat/xmpp.hpp | 2 - sca-cpp/trunk/components/http/server-test.scm | 2 +- sca-cpp/trunk/components/queue/qpid.hpp | 2 - sca-cpp/trunk/components/webservice/axis2.hpp | 1 - sca-cpp/trunk/configure.ac | 4 +- sca-cpp/trunk/kernel/element.hpp | 31 +-- sca-cpp/trunk/kernel/gc.hpp | 31 +-- sca-cpp/trunk/kernel/kernel-test.cpp | 105 ++++++++-- sca-cpp/trunk/kernel/list.hpp | 218 ++++++++++++++------- sca-cpp/trunk/kernel/stream.hpp | 2 +- sca-cpp/trunk/kernel/tree.hpp | 168 +++++++++++++--- sca-cpp/trunk/kernel/value.hpp | 61 +++--- sca-cpp/trunk/modules/atom/atom.hpp | 29 +-- sca-cpp/trunk/modules/http/http.hpp | 5 +- sca-cpp/trunk/modules/http/httpd.hpp | 26 +-- sca-cpp/trunk/modules/http/mod-openauth.cpp | 6 +- sca-cpp/trunk/modules/http/openauth.hpp | 6 +- sca-cpp/trunk/modules/json/json.hpp | 4 +- sca-cpp/trunk/modules/oauth/mod-oauth1.cpp | 32 +-- sca-cpp/trunk/modules/oauth/mod-oauth2.cpp | 28 +-- sca-cpp/trunk/modules/rss/rss.hpp | 23 +-- sca-cpp/trunk/modules/scdl/scdl-test.cpp | 8 +- sca-cpp/trunk/modules/scheme/primitive.hpp | 59 +++++- sca-cpp/trunk/modules/scheme/test.scm | 2 +- sca-cpp/trunk/patches/jansson-2.4.patch | 2 +- .../trunk/samples/store-constdb/shopping-cart.scm | 10 +- .../samples/store-cpp/htdocs/test/items-result.txt | 24 +-- .../store-python/htdocs/test/items-result.txt | 24 +-- .../trunk/samples/store-scheme/shopping-cart.scm | 10 +- sca-cpp/trunk/samples/store-sql/shopping-cart.scm | 10 +- 30 files changed, 601 insertions(+), 334 deletions(-) (limited to 'sca-cpp') diff --git a/sca-cpp/trunk/components/chat/xmpp.hpp b/sca-cpp/trunk/components/chat/xmpp.hpp index 88174613a0..31b4ed3a13 100644 --- a/sca-cpp/trunk/components/chat/xmpp.hpp +++ b/sca-cpp/trunk/components/chat/xmpp.hpp @@ -51,7 +51,6 @@ public: } ~XMPPRuntime() { - debug("chat::~xmppruntime"); xmpp_shutdown(); } @@ -79,7 +78,6 @@ public: XMPPClient& operator=(const XMPPClient& xc) = delete; ~XMPPClient() { - debug("chat::~xmppclient"); extern const failable disconnect(XMPPClient& xc); if (!owner) return; diff --git a/sca-cpp/trunk/components/http/server-test.scm b/sca-cpp/trunk/components/http/server-test.scm index 4bbff6e5c2..41d6296ba3 100644 --- a/sca-cpp/trunk/components/http/server-test.scm +++ b/sca-cpp/trunk/components/http/server-test.scm @@ -22,7 +22,7 @@ ; ATOMPub test case (define (get id) - (if (nul id) + (if (null? id) '((feed (title "Sample Feed") (id "123456789") (entry (((title "Item") (id "111") (content (item (name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99)))) ((title "Item") (id "222") (content (item (name "Orange") (currencyCode "USD") (currencySymbol "$") (price 3.55)))) diff --git a/sca-cpp/trunk/components/queue/qpid.hpp b/sca-cpp/trunk/components/queue/qpid.hpp index 77361461c6..076d9f1241 100644 --- a/sca-cpp/trunk/components/queue/qpid.hpp +++ b/sca-cpp/trunk/components/queue/qpid.hpp @@ -68,7 +68,6 @@ public: QpidConnection& operator=(const QpidConnection& qc) = delete; ~QpidConnection() { - debug("queue::~qpidonnection"); if (!owner) return; c.close(); @@ -109,7 +108,6 @@ public: } ~QpidSession() { - debug("queue::~qpidsession"); if (!owner) return; s.close(); diff --git a/sca-cpp/trunk/components/webservice/axis2.hpp b/sca-cpp/trunk/components/webservice/axis2.hpp index fd4d1f9a02..d6d2107f03 100644 --- a/sca-cpp/trunk/components/webservice/axis2.hpp +++ b/sca-cpp/trunk/components/webservice/axis2.hpp @@ -72,7 +72,6 @@ public: } ~Axis2Context() { - debug("webservice::~axis2context"); if (!owner || env == NULL) return; axutil_env_free(env); diff --git a/sca-cpp/trunk/configure.ac b/sca-cpp/trunk/configure.ac index eb626c710a..b0992a58b1 100644 --- a/sca-cpp/trunk/configure.ac +++ b/sca-cpp/trunk/configure.ac @@ -119,7 +119,7 @@ AC_ARG_ENABLE(maintainer-mode, [AS_HELP_STRING([--enable-maintainer-mode], [comp if test "${want_maintainer_mode}" = "true"; then cxxflags="${cxxflags} -ggdb -g3 -Werror -Wall -Wextra -Wno-ignored-qualifiers -Wno-strict-aliasing -Winit-self -Wmissing-include-dirs -Wcast-qual -Wcast-align -Wwrite-strings -Wpointer-arith -Waddress -Wredundant-decls -std=c++0x -fmessage-length=0" if test "${cxxtype}" = "clang"; then - cxxflags="${cxxflags} -O2 -stdlib=libc++ -Qunused-arguments -Wno-return-type-c-linkage" + cxxflags="${cxxflags} -O1 -stdlib=libc++ -Qunused-arguments -Wno-return-type-c-linkage" else cxxflags="${cxxflags} -O2 -Wlogical-op -Wconversion" fi @@ -128,7 +128,7 @@ if test "${want_maintainer_mode}" = "true"; then else cxxflags="${cxxflags} -g -std=c++0x -fmessage-length=0" if test "${cxxtype}" = "clang"; then - cxxflags="${cxxflags} -O2 -stdlib=libc++ -Qunused-arguments" + cxxflags="${cxxflags} -O1 -stdlib=libc++ -Qunused-arguments" else cxxflags="${cxxflags} -O2" fi diff --git a/sca-cpp/trunk/kernel/element.hpp b/sca-cpp/trunk/kernel/element.hpp index 9ae1e632cb..d8907c8d21 100644 --- a/sca-cpp/trunk/kernel/element.hpp +++ b/sca-cpp/trunk/kernel/element.hpp @@ -227,34 +227,13 @@ inline const list valuesToElements(const list& l) { return cons(valueToElement(car(l)), valuesToElements(cdr(l))); } -/** - * Returns a selector lambda function which can be used to filter - * elements against the given element pattern. - */ -inline const lambda selector(const list& select) { - return [select](const value& v) -> const bool { - const lambda&, const list&)> evalSelect = [&evalSelect](const list& s, const list& v) -> const bool { - if (isNil(s)) - return true; - if (isNil(v)) - return false; - if (car(s) != car(v)) - return false; - return evalSelect(cdr(s), cdr(v)); - }; - if (!isList(v)) - return false; - return evalSelect(select, v); - }; -} - /** * Returns the value of the attribute with the given name. */ -inline const value attributeValue(const value& name, const value& l) { +inline const value attributeValue(const value& name, const list& l) { const list f = filter([name](const value& v) { return isAttribute(v) && attributeName((list)v) == name; - }, list(l)); + }, l); if (isNil(f)) return nilValue; return caddr(car(f)); @@ -263,16 +242,16 @@ inline const value attributeValue(const value& name, const value& l) { /** * Returns child elements with the given name. */ -inline const value elementChildren(const value& name, const value& l) { +inline const list elementChildren(const value& name, const list& l) { return filter([name](const value& v) { return isElement(v) && elementName((list)v) == name; - }, list(l)); + }, l); } /** * Return the child element with the given name. */ -inline const value elementChild(const value& name, const value& l) { +inline const value elementChild(const value& name, const list& l) { const list f = elementChildren(name, l); if (isNil(f)) return nilValue; diff --git a/sca-cpp/trunk/kernel/gc.hpp b/sca-cpp/trunk/kernel/gc.hpp index 7853c551dc..2b65132588 100644 --- a/sca-cpp/trunk/kernel/gc.hpp +++ b/sca-cpp/trunk/kernel/gc.hpp @@ -214,7 +214,7 @@ public: gc_pool& operator=(const gc_pool& pool) = delete; private: - friend apr_pool_t* pool(const gc_pool& pool) noexcept; + friend apr_pool_t* const pool(const gc_pool& pool) noexcept; friend class gc_global_pool_t; friend class gc_child_pool; friend class gc_local_pool; @@ -226,7 +226,7 @@ private: /** * Return the APR pool used by a gc_pool. */ -inline apr_pool_t* pool(const gc_pool& pool) noexcept { +inline apr_pool_t* const pool(const gc_pool& pool) noexcept { return pool.apr_pool; } @@ -242,21 +242,22 @@ public: inline gc_pool_stack_t() noexcept : key(mkkey()) { } - inline operator apr_pool_t*() const noexcept { - return (apr_pool_t*)pthread_getspecific(key); + inline operator apr_pool_t* const () const noexcept { + return (apr_pool_t* const )pthread_getspecific(key); } - inline const gc_pool_stack_t& operator=(apr_pool_t* p) noexcept { - pthread_setspecific(key, p); + const gc_pool_stack_t& operator=(apr_pool_t* const p) noexcept { + const int rc = pthread_setspecific(key, p); + assertOrFail(rc == 0); return *this; } private: - pthread_key_t key; + const pthread_key_t key; - pthread_key_t mkkey() { + inline const pthread_key_t mkkey() noexcept { pthread_key_t k; - int rc = pthread_key_create(&k, NULL); + const int rc = pthread_key_create(&k, NULL); assertOrFail(rc == 0); return k; } @@ -278,7 +279,7 @@ apr_pool_t* gc_pool_stack = NULL; /** * Push a pool onto the stack. */ -inline apr_pool_t* const gc_push_pool(apr_pool_t* pool) noexcept { +inline apr_pool_t* const gc_push_pool(apr_pool_t* const pool) noexcept { apr_pool_t* const p = gc_pool_stack; gc_pool_stack = pool; return p; @@ -287,7 +288,7 @@ inline apr_pool_t* const gc_push_pool(apr_pool_t* pool) noexcept { /** * Pop a pool from the stack. */ -inline apr_pool_t* const gc_pop_pool(apr_pool_t* pool) noexcept { +inline apr_pool_t* const gc_pop_pool(apr_pool_t* const pool) noexcept { apr_pool_t* const p = gc_pool_stack; gc_pool_stack = pool; return p; @@ -326,7 +327,7 @@ public: private: const bool owner; - apr_pool_t* const mkpool() { + inline apr_pool_t* const mkpool() noexcept { apr_pool_t* p; apr_pool_create(&p, gc_current_pool()); assertOrFail(p != NULL); @@ -356,7 +357,7 @@ public: private: const bool owner; - apr_pool_t* const mkpool() { + inline apr_pool_t* const mkpool() noexcept { apr_pool_t* p; apr_pool_create(&p, gc_current_pool()); assertOrFail(p != NULL); @@ -375,7 +376,7 @@ public: gc_push_pool(apr_pool); } - inline gc_scoped_pool(apr_pool_t* p) noexcept : gc_pool(p), prev(gc_current_pool()), owner(false) { + inline gc_scoped_pool(apr_pool_t* const p) noexcept : gc_pool(p), prev(gc_current_pool()), owner(false) { gc_push_pool(apr_pool); } @@ -394,7 +395,7 @@ private: apr_pool_t* const prev; const bool owner; - apr_pool_t* const mkpool() { + inline apr_pool_t* const mkpool() noexcept { apr_pool_t* p; apr_pool_create(&p, gc_current_pool()); assertOrFail(p != NULL); diff --git a/sca-cpp/trunk/kernel/kernel-test.cpp b/sca-cpp/trunk/kernel/kernel-test.cpp index 0e2a14246a..4c68975961 100644 --- a/sca-cpp/trunk/kernel/kernel-test.cpp +++ b/sca-cpp/trunk/kernel/kernel-test.cpp @@ -557,11 +557,37 @@ const bool testListRef() { return true; } +const bool testSubst() { + assert(subst(1, 9, mklist(1, 2, 1, 3, 1)) == mklist(9, 2, 9, 3, 9)); + assert(subst(1, 9, mklist(1, 2, 1, 3, 1)) == mklist(9, 2, 9, 3, 9)); + return true; +} + const bool testAssoc() { const list > l = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(assoc("a", l) == mklist("a", "A")); assert(isNil(assoc("z", l))); + const list > l3 = mklist(mklist("x", "X"), mklist("a", "A"), mklist("a", "AA")); + assert(delAssoc("y", l) == l3); + + const list > l4 = mklist(mklist("x", "X"), mklist("y", "Y")); + assert(delAssoc("a", l) == l4); + + const list > l5 = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "YY"), mklist("a", "AA")); + assert(substAssoc("y", mklist("y", "YY"), l) == l5); + + const list > l6 = mklist(mklist("x", "X"), mklist("a", "AAA"), mklist("y", "Y"), mklist("a", "AAA")); + assert(substAssoc("a", mklist("a", "AAA"), l) == l6); + + const list > l7 = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA"), mklist("z", "ZZ")); + assert(substAssoc("z", mklist("z", "ZZ"), l) == l); + assert(substAssoc("z", mklist("z", "ZZ"), l, true) == l7); + + return true; +} + +const bool testValueAssoc() { const list > u = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(assoc("a", u) == mklist("a", "A")); @@ -570,6 +596,50 @@ const bool testAssoc() { const list v2 = mklist(mklist("x", "X"), "a", mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(assoc("a", v2) == mklist("a", "A")); + + const list v3 = mklist(mklist("x", "X"), mklist("a", "A"), mklist("a", "AA")); + assert(delAssoc("y", v) == v3); + + const list v4 = mklist(mklist("x", "X"), mklist("y", "Y")); + assert(delAssoc("a", v) == v4); + + const list v5 = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "YY"), mklist("a", "AA")); + assert(substAssoc("y", mklist("y", "YY"), v) == v5); + + const list v6 = mklist(mklist("x", "X"), mklist("a", "AAA"), mklist("y", "Y"), mklist("a", "AAA")); + assert(substAssoc("a", mklist("a", "AAA"), v) == v6); + + const list v7 = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA"), mklist("z", "ZZ")); + assert(substAssoc("z", mklist("z", "ZZ"), v) == v); + assert(substAssoc("z", mklist("z", "ZZ"), v, true) == v7); + return true; +} + +const bool testTreeAssoc() { + const list tv = mklist(mklist("a", "A"), mklist("b", mklist("ba", "BA"), mklist("bc", "BC"), mklist("bd", mklist("z", "ZZ"), mklist("bda", "BDA"))), mklist("z", "Z")); + assert(treeSelectAssoc(mklist("a"), tv) == mklist(mklist("a", "A"))); + assert(treeSelectAssoc(mklist("b", "bc"), tv) == mklist(mklist("bc", "BC"))); + assert(treeSelectAssoc(mklist("b", "bx"), tv) == list()); + assert(treeSelectAssoc(mklist("b", "bd", "bda"), tv) == mklist(mklist("bda", "BDA"))); + assert(treeSelectAssoc(mklist("bc"), tv) == mklist(mklist("bc", "BC"))); + assert(treeSelectAssoc(mklist("bda"), tv) == mklist(mklist("bda", "BDA"))); + assert(treeSelectAssoc(mklist("bd", "bda"), tv) == mklist(mklist("bda", "BDA"))); + assert(treeSelectAssoc(mklist("bd", "bda", "bdax"), tv) == list()); + assert(treeSelectAssoc(mklist("z"), tv) == mklist(mklist("z", "ZZ"), mklist("z", "Z"))); + + const list tv2 = mklist(mklist("a", "A"), mklist("b", mklist("ba", "BA"), mklist("bc", "BC"), mklist("bd", mklist("bda", "BDA")))); + const list tv3 = mklist(mklist("a", "A"), mklist("b", mklist("ba", "BA"), mklist("bc", "BC"), mklist("bd", mklist("z", "ZZ"))), mklist("z", "Z")); + assert(treeDelAssoc(mklist("z"), tv) == tv2); + assert(treeDelAssoc(mklist("bda"), tv) == tv3); + assert(treeDelAssoc(mklist("bd", "bda"), tv) == tv3); + assert(treeDelAssoc(mklist("bd", "bda", "bdax"), tv) == tv); + + const list tv4 = mklist(mklist("a", "A"), mklist("b", mklist("ba", "BA"), mklist("bc", "BC"), mklist("bd", mklist("z", "ZZZ"), mklist("bda", "BDA"))), mklist("z", "ZZZ")); + const list tv5 = mklist(mklist("a", "A"), mklist("b", mklist("ba", "BA"), mklist("bc", "BC"), mklist("bd", mklist("z", "ZZ"), mklist("bda", "BDAX"))), mklist("z", "Z")); + assert(treeSubstAssoc(mklist("z"), mklist("z", "ZZZ"), tv) == tv4); + assert(treeSubstAssoc(mklist("bda"), mklist("bda", "BDAX"), tv) == tv5); + assert(treeSubstAssoc(mklist("bd", "bda"), mklist("bda", "BDAX"), tv) == tv5); + assert(treeSubstAssoc(mklist("bd", "bda", "bdax"), mklist("bda", "BDAX"), tv) == tv); return true; } @@ -638,7 +708,7 @@ const bool testValue() { assert(value(mklist(1, 2)) == value(mklist(1, 2))); const list v = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y")); - assert(cadr((list >)value(v)) == mklist("a", "A")); + assert(cadr(value(v)) == mklist("a", "A")); const value pv(gc_ptr(new (gc_new()) value(1))); assert(*(gc_ptr)pv == value(1)); @@ -662,16 +732,16 @@ const bool testValueGC() { return true; } -const bool testTree() { - const list t = mktree("a", nilListValue, nilListValue); - const list ct = constree("d", constree("f", constree("c", constree("e", constree("b", t))))); - const list mt = mktree(mklist("d", "f", "c", "e", "b", "a")); +const bool testBinaryTree() { + const list t = mkrbtree("a", nilListValue, nilListValue); + const list ct = rbtreeCons("d", rbtreeCons("f", rbtreeCons("c", rbtreeCons("e", rbtreeCons("b", t))))); + const list mt = mkrbtree(mklist("d", "f", "c", "e", "b", "a")); assert(mt == ct); const list l = flatten(mt); assert(length(l) == 6); assert(car(l) == "a"); assert(car(reverse(l)) == "f"); - const list bt = mkbtree(l); + const list bt = mkbrbtree(l); assert(car(bt) == "c"); return true; } @@ -680,19 +750,19 @@ const list lta(const string& x) { return mklist(c_str(x), c_str(x + x)); } -const bool testTreeAssoc() { - const list t = mktree(lta("a"), nilListValue, nilListValue); - const list at = constree(lta("d"), constree(lta("f"), constree(lta("c"), constree(lta("e"), constree(lta("b"), t))))); +const bool testBinaryTreeAssoc() { + const list t = mkrbtree(lta("a"), nilListValue, nilListValue); + const list at = rbtreeCons(lta("d"), rbtreeCons(lta("f"), rbtreeCons(lta("c"), rbtreeCons(lta("e"), rbtreeCons(lta("b"), t))))); const list l = flatten(at); assert(length(l) == 6); assert(car(l) == mklist("a", "aa")); assert(car(reverse(l)) == mklist("f", "ff")); - const list bt = mkbtree(l); + const list bt = mkbrbtree(l); assert(car(bt) == mklist("c", "cc")); - assert(assoctree("a", bt) == mklist("a", "aa")); - assert(assoctree("b", bt) == mklist("b", "bb")); - assert(assoctree("f", bt) == mklist("f", "ff")); - assert(isNil(assoctree("x", bt))); + assert(rbtreeAssoc("a", bt) == mklist("a", "aa")); + assert(rbtreeAssoc("b", bt) == mklist("b", "bb")); + assert(rbtreeAssoc("f", bt) == mklist("f", "ff")); + assert(isNil(rbtreeAssoc("x", bt))); return true; } @@ -893,14 +963,17 @@ int main() { tuscany::testMember(); tuscany::testReverse(); tuscany::testListRef(); + tuscany::testSubst(); tuscany::testAssoc(); + tuscany::testValueAssoc(); + tuscany::testTreeAssoc(); tuscany::testZip(); tuscany::testTokenize(); tuscany::testSeq(); tuscany::testValue(); tuscany::testValueGC(); - tuscany::testTree(); - tuscany::testTreeAssoc(); + tuscany::testBinaryTree(); + tuscany::testBinaryTreeAssoc(); tuscany::testCppPerf(); tuscany::testIdMonad(); tuscany::testMaybeMonad(); diff --git a/sca-cpp/trunk/kernel/list.hpp b/sca-cpp/trunk/kernel/list.hpp index 16a0649fe9..02df2c2dc5 100644 --- a/sca-cpp/trunk/kernel/list.hpp +++ b/sca-cpp/trunk/kernel/list.hpp @@ -43,16 +43,16 @@ long countILists = 0; long countCLists = 0; long countELists = 0; -inline const bool resetListCounters() { +inline const bool resetListCounters() noexcept { countLists = countILists = countCLists = countELists = 0; return true; } -inline const bool checkListCounters() { +inline const bool checkListCounters() noexcept { return countLists == 0; } -inline const bool printListCounters() { +inline const bool printListCounters() noexcept { cout << "countLists " << countLists << endl; cout << "countELists " << countELists << endl; cout << "countILists " << countILists << endl; @@ -91,19 +91,19 @@ inline const bool printListCounters() { template class list { public: - inline list() : car() { + inline list() noexcept : car() { debug_inc(countLists); debug_inc(countELists); debug_watchList(); } - inline list(const T& car, const lambda()>& cdr) : car(car), cdr(cdr) { + inline list(const T& car, const lambda()>& cdr) noexcept : car(car), cdr(cdr) { debug_inc(countLists); debug_inc(countILists); debug_watchList(); } - inline list(const list& p) : car(p.car), cdr(p.cdr) { + inline list(const list& p) noexcept : car(p.car), cdr(p.cdr) { debug_inc(countLists); debug_inc(countCLists); #ifdef WANT_MAINTAINER_WATCH @@ -113,11 +113,11 @@ public: list& operator=(const list& p) = delete; - inline ~list() { + inline ~list() noexcept { debug_dec(countLists); } - inline const bool operator==(const list& p) const { + inline const bool operator==(const list& p) const noexcept { if(this == &p) return true; if(isNil(cdr)) @@ -131,7 +131,7 @@ public: return cdr() == p.cdr(); } - inline const bool operator<(const list& p) const { + inline const bool operator<(const list& p) const noexcept { if(this == &p) return false; if (isNil(cdr)) @@ -145,7 +145,7 @@ public: return cdr() < p.cdr(); } - inline const bool operator>(const list& p) const { + inline const bool operator>(const list& p) const noexcept { if(this == &p) return false; if (isNil(cdr)) @@ -159,24 +159,23 @@ public: return cdr() > p.cdr(); } - inline const bool operator!=(const list& p) const { + inline const bool operator!=(const list& p) const noexcept { return !this->operator==(p); } - inline operator const list >() const { + inline operator const list >() const noexcept { return (list >)T(*this); } private: #ifdef WANT_MAINTAINER_WATCH - template friend const string watchList(const list& p); + template friend const string watchList(const list& p) noexcept; string watch; #endif - template friend const bool isNil(const list& p); - template friend const X car(const list& p); - template friend const list cdr(const list& p); - template friend const bool setlist(list& target, const list& l); + template friend const bool isNil(const list& p) noexcept; + template friend const X car(const list& p) noexcept; + template friend const list cdr(const list& p) noexcept; const T car; const lambda()> cdr; @@ -188,7 +187,7 @@ private: * Debug utility used to write the contents of a list to a string, easier * to watch than the list itself in a debugger. */ -template inline const string watchList(const list& p) { +template inline const string watchList(const list& p) noexcept { if(isNil(p)) return "()"; odebugstream os; @@ -201,21 +200,21 @@ template inline const string watchList(const list& p) { /** * Returns true if the given list is nil. */ -template inline const bool isNil(const list& p) { +template inline const bool isNil(const list& p) noexcept { return isNil(p.cdr); } /** * Write a list to an output stream. */ -template inline ostream& writeHelper(ostream& out, const list& l) { +template inline ostream& writeHelper(ostream& out, const list& l) noexcept { if (isNil(l)) return out; out << " " << car(l); return writeHelper(out, cdr(l)); } -template inline ostream& operator<<(ostream& out, const list& l) { +template inline ostream& operator<<(ostream& out, const list& l) noexcept { if(isNil(l)) return out << "()"; out << "(" << car(l); @@ -226,74 +225,74 @@ template inline ostream& operator<<(ostream& out, const list& l) /** * Construct a (lazy) list from a value and a lambda function that returns the cdr. */ -template inline const list cons(const T& car, const lambda()>& cdr) { +template inline const list cons(const T& car, const lambda()>& cdr) noexcept { return list (car, cdr); } /** * Construct a list from a value and a cdr list. */ -template inline const list cons(const T& car, const list& cdr) { +template inline const list cons(const T& car, const list& cdr) noexcept { return list (car, result(cdr)); } /** * Cons variations for use with the reduce and reduceRight functions. */ -template inline const list lcons(const list& cdr, const T& car) { +template inline const list lcons(const list& cdr, const T& car) noexcept { return cons(car, cdr); } -template inline const list rcons(const T& car, const list& cdr) { +template inline const list rcons(const T& car, const list& cdr) noexcept { return cons(car, cdr); } /** * Construct a list of one value. */ -template inline const list mklist(const T& car) { +template inline const list mklist(const T& car) noexcept { return list (car, result(list ())); } /** * Construct a list of two values. */ -template inline const list mklist(const T& a, const T& b) { +template inline const list mklist(const T& a, const T& b) noexcept { return cons(a, mklist(b)); } /** * Construct a list of three values. */ -template inline const list mklist(const T& a, const T& b, const T& c) { +template inline const list mklist(const T& a, const T& b, const T& c) noexcept { return cons(a, cons(b, mklist(c))); } /** * Construct a list of four values. */ -template inline const list mklist(const T& a, const T& b, const T& c, const T& d) { +template inline const list mklist(const T& a, const T& b, const T& c, const T& d) noexcept { return cons(a, cons(b, cons(c, mklist(d)))); } /** * Construct a list of five values. */ -template inline const list mklist(const T& a, const T& b, const T& c, const T& d, const T& e) { +template inline const list mklist(const T& a, const T& b, const T& c, const T& d, const T& e) noexcept { return cons(a, cons(b, cons(c, cons(d, mklist(e))))); } /** * Construct a list of six values. */ -template inline const list mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) { +template inline const list mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) noexcept { return cons(a, cons(b, cons(c, cons(d, cons(e, mklist(f)))))); } /** * Returns the car of a list. */ -template inline const T car(const list& p) { +template inline const T car(const list& p) noexcept { // Abort if trying to access the car of a nil list assertOrFail(!isNil(p.cdr)); return p.car; @@ -302,105 +301,105 @@ template inline const T car(const list& p) { /** * Returns the cdr of a list. */ -template inline const list cdr(const list& p) { +template inline const list cdr(const list& p) noexcept { return p.cdr(); } /** * Returns the car of the cdr (the 2nd element) of a list. */ -template inline const T cadr(const list& p) { +template inline const T cadr(const list& p) noexcept { return car(cdr(p)); } /** * Returns the 3rd element of a list. */ -template inline const T caddr(const list& p) { +template inline const T caddr(const list& p) noexcept { return car(cdr(cdr(p))); } /** * Returns the 4th element of a list. */ -template inline const T cadddr(const list& p) { +template inline const T cadddr(const list& p) noexcept { return car(cdr(cdr(cdr(p)))); } /** * Returns the 5th element of a list. */ -template inline const T caddddr(const list& p) { +template inline const T caddddr(const list& p) noexcept { return car(cdr(cdr(cdr(cdr(p))))); } /** * Returns the 6th element of a list. */ -template inline const T cadddddr(const list& p) { +template inline const T cadddddr(const list& p) noexcept { return car(cdr(cdr(cdr(cdr(cdr(p)))))); } /** * Returns the 7th element of a list. */ -template inline const T caddddddr(const list& p) { +template inline const T caddddddr(const list& p) noexcept { return car(cdr(cdr(cdr(cdr(cdr(cdr(p))))))); } /** * Returns the 8th element of a list. */ -template inline const T cadddddddr(const list& p) { +template inline const T cadddddddr(const list& p) noexcept { return car(cdr(cdr(cdr(cdr(cdr(cdr(cdr(p)))))))); } /** * Returns a list of elements from the 3rd to the end of a list. */ -template inline const list cddr(const list& p) { +template inline const list cddr(const list& p) noexcept { return cdr(cdr(p)); } /** * Returns a list of elements from the 4th to the end of a list. */ -template inline const list cdddr(const list& p) { +template inline const list cdddr(const list& p) noexcept { return cdr(cdr(cdr(p))); } /** * Returns a list of elements from the 5th to the end of a list. */ -template inline const list cddddr(const list& p) { +template inline const list cddddr(const list& p) noexcept { return cdr(cdr(cdr(cdr(p)))); } /** * Returns a list of elements from the 6th to the end of a list. */ -template inline const list cdddddr(const list& p) { +template inline const list cdddddr(const list& p) noexcept { return cdr(cdr(cdr(cdr(cdr(p))))); } /** * Returns a list of elements from the 7th to the end of a list. */ -template inline const list cddddddr(const list& p) { +template inline const list cddddddr(const list& p) noexcept { return cdr(cdr(cdr(cdr(cdr(cdr(p)))))); } /** * Returns a list of elements from the 8th to the end of a list. */ -template inline const list cdddddddr(const list& p) { +template inline const list cdddddddr(const list& p) noexcept { return cdr(cdr(cdr(cdr(cdr(cdr(cdr(p))))))); } /** * Returns the length of a list. */ -template inline const size_t length(const list& p) { +template inline const size_t length(const list& p) noexcept { const lambda&)> lengthRef = [&lengthRef](const size_t c, const list& p) -> const size_t { if(isNil(p)) return c; @@ -412,7 +411,7 @@ template inline const size_t length(const list& p) { /** * Appends a list and a lambda function returning a list. */ -template inline const list append(const list&a, const lambda()>& fb) { +template inline const list append(const list&a, const lambda()>& fb) noexcept { if(isNil(a)) return fb(); return cons(car(a), [a, fb]() { return append(cdr(a), fb); }); @@ -421,25 +420,25 @@ template inline const list append(const list&a, const lambda inline const list append(const list&a, const list& b) { +template inline const list append(const list&a, const list& b) noexcept { return append(a, result(b)); } /** * Append a value to a list. */ -template inline const list operator+(const list& l, const T& v) { +template inline const list operator+(const list& l, const T& v) noexcept { return append(l, mklist(v)); } -template const list inline operator+(const list& l, const V& v) { +template const list inline operator+(const list& l, const V& v) noexcept { return append(l, mklist(v)); } /** - * Map a lambda function on a list. + * Run a map lambda function on a list. */ -template inline const list map(const lambda& f, const list& p) { +template inline const list map(const lambda& f, const list& p) noexcept { if(isNil(p)) return list (); return cons(f(car(p)), map(f, cdr(p))); @@ -448,7 +447,7 @@ template inline const list map(const lambda inline const R reduce(const lambda& f, const R& initial, const list& p) { +template inline const R reduce(const lambda& f, const R& initial, const list& p) noexcept { const lambda&p)> reduceAccumulate = [f, &reduceAccumulate](const R& acc, const list& p) -> R { if(isNil(p)) return acc; @@ -457,7 +456,7 @@ template inline const R reduce(const lambda inline const R reduceRight(const lambda& f, const R& initial, const list& p) { +template inline const R reduceRight(const lambda& f, const R& initial, const list& p) noexcept { const lambda&p, const R&)> reduceRightAccumulate = [f, &reduceRightAccumulate](const list& p, const R& acc) -> R { if(isNil(p)) return acc; @@ -469,7 +468,7 @@ template inline const R reduceRight(const lambda inline const list filter(const lambda& f, const list& p) { +template inline const list filter(const lambda& f, const list& p) noexcept { if(isNil(p)) return list (); if(f(car(p))) { @@ -482,7 +481,7 @@ template inline const list filter(const lambda inline const list member(const T& t, const list& p) { +template inline const list member(const T& t, const list& p) noexcept { if(isNil(p)) return list (); if(t == car(p)) @@ -493,20 +492,20 @@ template inline const list member(const T& t, const list& p) { /** * Reverse a list. */ -template inline const list reverseIter(const list& acc, const list& p) { +template inline const list reverseIter(const list& acc, const list& p) noexcept { if(isNil(p)) return acc; return reverseIter(cons(car(p), acc), cdr(p)); } -template inline const list reverse(const list& p) { +template inline const list reverse(const list& p) noexcept { return reverseIter(list (), p); } /** * Returns a sequence of values between the given bounds. */ -template inline const list seq(const T& start, const T& end) { +template inline const list seq(const T& start, const T& end) noexcept { if(start == end) return mklist(start); if(start < end) @@ -517,27 +516,62 @@ template inline const list seq(const T& start, const T& end) { /** * Returns the i-th element of a list. */ -template inline const T listRef(const list& l, const size_t i) { - if (i == 0) +template inline const T listRef(const list& l, const size_t i) noexcept { + if(i == 0) return car(l); return listRef(cdr(l), i - 1); } +/** + * Returns the tail of a list, ommiting the first k elements. + */ +template inline const list listTail(const list& l, const size_t k) noexcept { + if(k == 0) + return l; + if(isNil(l)) + return l; + return listTail(cdr(l), k - 1); +} + +/** + * Substitute elements in a list. + */ +template inline const list subst(const T& o, const T& n, const list& p) noexcept { + if(isNil(p)) + return p; + if(o == car(p)) + return cons(n, subst(o, n, cdr(p))); + return cons(car(p), subst(o, n, cdr(p))); +} + /** * Returns the first pair matching a key from a list of key value pairs. */ -template inline const list assoc(const T& k, const list >& p) { +template inline const list assoc(const T& k, const list >& p) noexcept { if(isNil(p)) - return list (); + return list(); if(k == car(car(p))) return car(p); return assoc(k, cdr(p)); } +/** + * Returns the first pair matching a key from a list of key value pairs. + * Requires T to support isList and cast to list. + */ +template inline const list assoc(const T& k, const list& p) noexcept { + if(isNil(p)) + return list(); + const T c = car(p); + if(isList(c) && k == car(c)) + return c; + return assoc(k, cdr(p)); +} + /** * Returns a list of lists containing elements from two input lists. */ -template inline const list > zip(const list& a, const list& b) { +template inline const list > zip(const list& a, const list& b) noexcept { if (isNil(a) || isNil(b)) return list >(); return cons >(mklist(car(a), car(b)), zip(cdr(a), cdr(b))); @@ -546,22 +580,70 @@ template inline const list > zip(const list& a, const lis /** * Converts a list of key value pairs to a list containing the list of keys and the list of values. */ -template inline const list unzipKeys(const list >& l) { +template inline const list unzipKeys(const list >& l) noexcept { if (isNil(l)) return list(); return cons(car(car(l)), unzipKeys(cdr(l))); } -template inline const list unzipValues(const list >& l) { +template inline const list unzipValues(const list >& l) noexcept { if (isNil(l)) return list(); return cons(cadr(car(l)), unzipValues(cdr(l))); } -template inline const list > unzip(const list >& l) { +template inline const list > unzip(const list >& l) noexcept { return mklist >(unzipKeys(l), unzipValues(l)); } +/** + * Delete assocs matching a key from a list of assocs. + */ +template inline const list > delAssoc(const T& k, const list >& p) noexcept { + if(isNil(p)) + return p; + if(k == car(car(p))) + return delAssoc(k, cdr(p)); + return cons >(car(p), delAssoc(k, cdr(p))); +} + +/** + * Delete assocs matching a key from a list of assocs. + * Requires T to support isList, isAssoc, and cast to list. + */ +template inline const list delAssoc(const T& k, const list& p) noexcept { + if(isNil(p)) + return p; + const T c = car(p); + if(isList(c) && k == car(c)) + return delAssoc(k, cdr(p)); + return cons(c, delAssoc(k, cdr(p))); +} + +/** + * Substitute assocs with matching keys in a list of assocs. + */ +template inline const list > substAssoc(const T& k, const list& n, const list >& p, const bool add = false) noexcept { + if(isNil(p)) + return add? mklist >(n) : p; + if(k == car(car(p))) + return cons >(n, substAssoc(k, n, cdr(p), false)); + return cons >(car(p), substAssoc(k, n, cdr(p), add)); +} + +/** + * Substitute assocs with matching keys in a list of assocs. + * Requires T to support isList, isAssoc, and cast to list. + */ +template inline const list substAssoc(const T& k, const list& n, const list& p, const bool add = false) noexcept { + if(isNil(p)) + return add? mklist(n) : p; + const T c = car(p); + if(isList(c) && k == car(c)) + return cons(n, substAssoc(k, n, cdr(p), false)); + return cons(c, substAssoc(k, n, cdr(p), add)); +} + } #endif /* tuscany_list_hpp */ diff --git a/sca-cpp/trunk/kernel/stream.hpp b/sca-cpp/trunk/kernel/stream.hpp index e59e6a4ef5..a4f4d3c950 100644 --- a/sca-cpp/trunk/kernel/stream.hpp +++ b/sca-cpp/trunk/kernel/stream.hpp @@ -83,7 +83,7 @@ inline ostream& operator<<(ostream& os, const long unsigned int v) { } inline ostream& operator<<(ostream& os, const double v) { - return os.vprintf("%.10g", v); + return os.vprintf("%.16g", v); } inline ostream& operator<<(ostream& os, const void* const v) { diff --git a/sca-cpp/trunk/kernel/tree.hpp b/sca-cpp/trunk/kernel/tree.hpp index 44af09fa64..d350879ce7 100644 --- a/sca-cpp/trunk/kernel/tree.hpp +++ b/sca-cpp/trunk/kernel/tree.hpp @@ -31,54 +31,172 @@ #include "function.hpp" #include "list.hpp" #include "monad.hpp" -#include "value.hpp" namespace tuscany { /** - * Make a tree from a leaf and two branches. + * Delete assocs matching a path of keys in a tree of assocs. + * The path can be a complete or partial path to an assoc. + * Requires T to support isList, isAssoc, and cast to list. */ -template inline const list mktree(const T& e, const list& left, const list& right) { +template inline const list treeDelAssoc(const list& k, const list& l) noexcept { + if (isNil(k) || isNil(l)) + return l; + const list lv = l; + + // If list is an assoc and matches, skip it + if (isAssoc(lv)) { + if (car(lv) == car(k) && isNil(cdr(k))) + return list(); + } + + // If list element is not an assoc, lookup children and rest of the list + const T a = car(lv); + if (!isAssoc(a)) { + if (!isList(a)) + return cons(a, treeDelAssoc(k, cdr(lv))); + const list da = treeDelAssoc(k, a); + return isNil(da)? treeDelAssoc(k, cdr(lv)) : cons(da, treeDelAssoc(k, cdr(lv))); + } + + // If we found a match, skip it and lookup children and rest of the list + if (car(a) == car(k)) { + if (isNil(cdr(k))) + return treeDelAssoc(k, cdr(lv)); + return cons(cons(car(a), treeDelAssoc(cdr(k), cdr(a))), treeDelAssoc(k, cdr(lv))); + } + + // No match, lookup children and rest of the list + if (isNil(cdr(a))) + return cons(a, treeDelAssoc(k, cdr(lv))); + if (!isList(cadr(a))) + return cons(cons(car(a), cons(cadr(a), treeDelAssoc(k, cddr(a)))), treeDelAssoc(k, cdr(lv))); + const list da = treeDelAssoc(k, cadr(a)); + if (isNil(da)) + return cons(cons(car(a), treeDelAssoc(k, cddr(a))), treeDelAssoc(k, cdr(lv))); + return cons(cons(car(a), cons(da, treeDelAssoc(k, cddr(a)))), treeDelAssoc(k, cdr(lv))); +} + +/** + * Substitute assocs matching a path of keys in a tree of assocs. + * The path can be a complete or partial path to an assoc. + * Requires T to support isList, isAssoc, and cast to list. + */ +template inline const list treeSubstAssoc(const list& k, const list& n, const list& lv) noexcept { + if (isNil(k) || isNil(lv)) + return lv; + + // If list is an assoc and matches, substitute it + if (isAssoc(lv)) { + if (car(lv) == car(k) && isNil(cdr(k))) + return n; + } + + // If list element is not an assoc, lookup children and rest of the list + const T a = car(lv); + if (!isAssoc(a)) { + if (!isList(a)) + return cons(a, treeSubstAssoc(k, n, cdr(lv))); + return cons(treeSubstAssoc(k, n, a), treeSubstAssoc(k, n, cdr(lv))); + } + + // If we found a match, substitute it and lookup children and rest of the list + if (car(a) == car(k)) { + if (isNil(cdr(k))) + return cons(n, treeSubstAssoc(k, n, cdr(lv))); + return cons(cons(car(a), treeSubstAssoc(cdr(k), n, cdr(a))), treeSubstAssoc(k, n, cdr(lv))); + } + + // No match, lookup children and rest of the list + if (isNil(cdr(a))) + return cons(a, treeSubstAssoc(k, n, cdr(lv))); + if (!isList(cadr(a))) + return cons(cons(car(a), cons(cadr(a), treeSubstAssoc(k, n, cddr(a)))), treeSubstAssoc(k, n, cdr(lv))); + return cons(cons(car(a), cons(treeSubstAssoc(k, n, cadr(a)), treeSubstAssoc(k, n, cddr(a)))), treeSubstAssoc(k, n, cdr(lv))); +} + +/** + * Select assocs matching a path of keys in a tree of assocs. + * The path can be a complete or partial path to an assoc. + * Requires T to support isList, isAssoc, and cast to list. + */ +template inline const list treeSelectAssoc(const list& k, const list& lv) noexcept { + if (isNil(k) || isNil(lv)) + return list(); + + // If list is an assoc and matches, select it + if (isAssoc(lv)) { + if (car(lv) == car(k) && isNil(cdr(k))) + return mklist(lv); + } + + // If list element is not an assoc, lookup children and rest of the list + const T a = car(lv); + if (!isAssoc(a)) { + if (!isList(a)) + return treeSelectAssoc(k, cdr(lv)); + return append(treeSelectAssoc(k, a), treeSelectAssoc(k, cdr(lv))); + } + + // If we found a match, select it and lookup children and rest of the list + if (car(a) == car(k)) { + if (isNil(cdr(k))) + return cons(a, treeSelectAssoc(k, cdr(lv))); + return append(treeSelectAssoc(cdr(k), cdr(a)), treeSelectAssoc(k, cdr(lv))); + } + + // No match, lookup children and rest of the list + if (isNil(cdr(a))) + return treeSelectAssoc(k, cdr(lv)); + if (!isList(cadr(a))) + return append(treeSelectAssoc(k, cddr(a)), treeSelectAssoc(k, cdr(lv))); + return append(append(treeSelectAssoc(k, cadr(a)), treeSelectAssoc(k, cddr(a))), treeSelectAssoc(k, cdr(lv))); +} + +/** + * Make a rooted binary tree from a leaf and two branches. + */ +template inline const list mkrbtree(const T& e, const list& left, const list& right) { return mklist(e, left, right); } /** - * Find a leaf with the given key in a tree. + * Find a leaf with the given key in a rooted binary tree. */ -template inline const list assoctree(const T& k, const list& tree) { +template inline const list rbtreeAssoc(const T& k, const list& tree) { if (isNil(tree)) return tree; if (k == car(car(tree))) return car(tree); if (k < car(car(tree))) - return assoctree(k, cadr(tree)); - return assoctree(k, caddr(tree)); + return rbtreeAssoc(k, cadr(tree)); + return rbtreeAssoc(k, caddr(tree)); } /** - * Construct a new tree from a leaf and a tree. + * Construct a new rooted binary tree from a leaf and a tree. */ -template inline const list constree(const T& e, const list& tree) { +template inline const list rbtreeCons(const T& e, const list& tree) { if (isNil(tree)) - return mktree(e, list(), list()); + return mkrbtree(e, list(), list()); if (e == car(tree)) return tree; if (e < car(tree)) - return mktree(car(tree), constree(e, cadr(tree)), caddr(tree)); - return mktree(car(tree), cadr(tree), constree(e, caddr(tree))); + return mkrbtree(car(tree), rbtreeCons(e, cadr(tree)), caddr(tree)); + return mkrbtree(car(tree), cadr(tree), rbtreeCons(e, caddr(tree))); } /** - * Make a tree from an unordered list of leaves. + * Make a rooted binary tree from an unordered list of leaves. */ -template inline const list mktree(const list& l) { +template inline const list mkrbtree(const list& l) { if (isNil(l)) return l; - return constree(car(l), mktree(cdr(l))); + return rbtreeCons(car(l), mkrbtree(cdr(l))); } /** - * Convert a tree to an ordered list of leaves. + * Convert a rooted binary tree to an ordered list of leaves. */ template inline const list flatten(const list& tree) { if (isNil(tree)) @@ -87,28 +205,28 @@ template inline const list flatten(const list& tree) { } /** - * Sort a list. + * Sort a list, using a rooted binary tree. */ template inline const list sort(const list& l) { - return flatten(mktree(l)); + return flatten(mkrbtree(l)); } /** - * Make a balanced tree from an ordered list of leaves. + * Make a balanced rooted binary tree from an ordered list of leaves. */ -template inline const list btreeHelper(const list& elements, const size_t n) { +template inline const list brbtreeHelper(const list& elements, const size_t n) { if (n == 0) return cons(list(), elements); const size_t leftSize = (n - 1) / 2; { - const list leftResult = btreeHelper(elements, leftSize); { + const list leftResult = brbtreeHelper(elements, leftSize); { const list leftTree = car(leftResult); const list nonLeftElements = cdr(leftResult); const size_t rightSize = n - (leftSize + 1); { const T thisEntry = car(nonLeftElements); - const list rightResult = btreeHelper(cdr(nonLeftElements), rightSize); { + const list rightResult = brbtreeHelper(cdr(nonLeftElements), rightSize); { const list rightTree = car(rightResult); const list remainingElements = cdr(rightResult); { - return cons(mktree(thisEntry, leftTree, rightTree), remainingElements); + return cons(mkrbtree(thisEntry, leftTree, rightTree), remainingElements); } } } @@ -116,8 +234,8 @@ template inline const list btreeHelper(const list& elements, c } } -template inline const list mkbtree(const list& elements) { - return car(btreeHelper(elements, length(elements))); +template inline const list mkbrbtree(const list& elements) { + return car(brbtreeHelper(elements, length(elements))); } } diff --git a/sca-cpp/trunk/kernel/value.hpp b/sca-cpp/trunk/kernel/value.hpp index 60fb29070c..d5ce34084a 100644 --- a/sca-cpp/trunk/kernel/value.hpp +++ b/sca-cpp/trunk/kernel/value.hpp @@ -27,6 +27,7 @@ */ #include +#include #include #include @@ -184,12 +185,6 @@ public: debug_watchValue(); } - inline value(const list >& l) noexcept : type(value::List), lst(new (gc_new >()) list(listOfValues(l))) { - debug_inc(countValues); - debug_inc(countVValues); - debug_watchValue(); - } - inline value(const double d) noexcept : type(value::Number), num(d) { debug_inc(countValues); debug_inc(countVValues); @@ -249,7 +244,8 @@ public: case value::String: return (v.type == value::Symbol || v.type == value::String) && str == v.str; case value::Number: - return v.type == value::Number && num == v.num; + // Handle double floating point rounding + return v.type == value::Number && fabs(num - v.num) < 5e-16; case value::Bool: return v.type == value::Bool && boo == v.boo; case value::Ptr: @@ -363,33 +359,23 @@ public: } inline operator const list() const noexcept { + switch(type) { + case value::List: + return *lst; + default: + return nilListValue; + } return *lst; } - inline operator const list >() const noexcept { - return listOfListOfValues(*lst); - } - inline operator const lvvlambda() const noexcept { return func; } private: - inline const list listOfValues(const list >& l) const noexcept { - if (isNil(l)) - return nilListValue; - return cons(car(l), listOfValues(cdr(l))); - } - - inline const list > listOfListOfValues(const list& l) const noexcept { - if (isNil(l)) - return list >(); - return cons >(car(l).type == value::List? list(car(l)) : nilPairValue, listOfListOfValues(cdr(l))); - } - friend ostream& operator<<(ostream&, const value&) noexcept; friend const value::ValueType type(const value& v) noexcept; - friend const bool setvalue(value& target, const value& v); + friend const bool setvalue(value& target, const value& v) noexcept; #ifdef WANT_MAINTAINER_WATCH friend const string watchValue(const value& v); @@ -565,6 +551,13 @@ inline const bool isTaggedList(const value& exp, const value& tag) noexcept { return false; } +/** + * Returns true if a value is an assoc. + */ +inline const bool isAssoc(const value& exp) noexcept { + return isList(exp) && !isNil((list)exp) && isSymbol(car(exp)); +} + /** * Make a list of values from a list of other things. */ @@ -583,6 +576,24 @@ template inline const list convertValues(const list& l) no return cons(car(l), convertValues(cdr(l))); } +/** + * Convert a list of lists of values to a list of values. + */ +inline const list listOfValues(const list >& l) noexcept { + if (isNil(l)) + return nilListValue; + return cons(car(l), listOfValues(cdr(l))); +} + +/** + * Convert a list of values to a list of lists of values. + */ +inline const list > listOfListOfValues(const list& l) noexcept { + if (isNil(l)) + return list >(); + return cons >(type(car(l)) == value::List? list(car(l)) : nilPairValue, listOfListOfValues(cdr(l))); +} + /** * Convert a path string value to a list of values. */ @@ -638,7 +649,7 @@ inline const value mkrand() noexcept { /** * Set a value. Use with moderation. */ -inline const bool setvalue(value& target, const value& v) { +inline const bool setvalue(value& target, const value& v) noexcept { if (&target == &v) return true; #ifdef WANT_MAINTAINER_WATCH diff --git a/sca-cpp/trunk/modules/atom/atom.hpp b/sca-cpp/trunk/modules/atom/atom.hpp index 2f6e688bcb..259769e2cb 100644 --- a/sca-cpp/trunk/modules/atom/atom.hpp +++ b/sca-cpp/trunk/modules/atom/atom.hpp @@ -45,23 +45,24 @@ const value entry("entry"); * Convert a list of elements to a list of element values representing an ATOM entry. */ const list entryElementValues(const list& e) { - const list lt = filter(selector(mklist(element, "title")), e); + const list lt = elementChildren("title", e); const list t = nilListValue + element + value("title") + (isNil(lt)? value(emptyString) : elementValue(car(lt))); - const list li = filter(selector(mklist(element, "id")), e); + const list li = elementChildren("id", e); const list i = nilListValue + element + value("id") + (isNil(li)? value(emptyString) : elementValue(car(li))); - const list la = filter(selector(mklist(element, "author")), e); - const list lan = isNil(la)? nilListValue : filter(selector(mklist(element, "name")), car(la)); - const list lae = isNil(la)? nilListValue : filter(selector(mklist(element, "email")), car(la)); + const list la = elementChildren("author", e); + const list lan = isNil(la)? nilListValue : elementChildren("name", car(la)); + const list lae = isNil(la)? nilListValue : elementChildren("email", car(la)); const list laa = isNil(lan)? lae : lan; const list a = isNil(laa)? nilListValue : mklist(nilListValue + element + value("author") + elementValue(car(laa))); - const list lu = filter(selector(mklist(element, "updated")), e); + const list lu = elementChildren("updated", e); const list u = isNil(lu)? nilListValue : mklist(nilListValue + element + value("updated") + elementValue(car(lu))); - const list lc = filter(selector(mklist(element, "content")), e); - const list c = isNil(lc)? nilListValue : mklist(nilListValue + element + value("content") + elementValue(car(lc))); + const list lc = elementChildren("content", e); + const list c = isNil(lc)? nilListValue : isAttribute(elementValue(car(lc)))? nilListValue : + mklist(nilListValue + element + value("content") + elementValue(car(lc))); return append(append(append(nilListValue + element + entry + value(t) + value(i), a), u), c); } @@ -110,9 +111,9 @@ const failable > readATOMFeed(const list& ilist) { const list f = content(xml::readElements(ilist)); if (isNil(f)) return mkfailure >("Empty feed"); - const list t = filter(selector(mklist(element, "title")), car(f)); - const list i = filter(selector(mklist(element, "id")), car(f)); - const list e = filter(selector(mklist(element, entry)), car(f)); + const list t = elementChildren("title", car(f)); + const list i = elementChildren("id", car(f)); + const list e = elementChildren(entry, car(f)); return mklist(append(nilListValue + element + feed + value(nilListValue + element + value("title") + elementValue(car(t))) + value(nilListValue + element + value("id") + elementValue(car(i))), @@ -182,9 +183,9 @@ const failable > writeATOMEntry(const list& l) { */ template const failable writeATOMFeed(const lambda& reduce, const R& initial, const list& ll) { const list l = isNil(ll)? ll : (list)car(ll); - const list lt = filter(selector(mklist(element, "title")), l); + const list lt = elementChildren("title", l); const value t = isNil(lt)? value(emptyString) : elementValue(car(lt)); - const list li = filter(selector(mklist(element, "id")), l); + const list li = elementChildren("id", l); const value i = isNil(li)? value(emptyString) : elementValue(car(li)); const list f = nilListValue + element + feed + (nilListValue + attribute + "xmlns" + "http://www.w3.org/2005/Atom") @@ -192,7 +193,7 @@ template const failable writeATOMFeed(const lambda le = filter(selector(mklist(element, entry)), l); + const list le = elementChildren(entry, l); if (isNil(le)) return xml::writeElements(reduce, initial, mklist(f)); diff --git a/sca-cpp/trunk/modules/http/http.hpp b/sca-cpp/trunk/modules/http/http.hpp index 1153f61840..cd0eb6c04b 100644 --- a/sca-cpp/trunk/modules/http/http.hpp +++ b/sca-cpp/trunk/modules/http/http.hpp @@ -87,7 +87,6 @@ public: return; if (h.h == NULL) return; - debug(h.h, "http::~CURLSession::cleanup::h"); curl_easy_cleanup(h.h); } @@ -943,7 +942,7 @@ const failable recv(char* const c, const size_t l, const CURLSession& cs /** * Converts a list of key value pairs to a query string. */ -ostringstream& queryString(const list > args, ostringstream& os) { +ostringstream& queryString(const list& args, ostringstream& os) { if (isNil(args)) return os; const list arg = car(args); @@ -956,7 +955,7 @@ ostringstream& queryString(const list > args, ostringstream& os) { return queryString(cdr(args), os); } -const string queryString(const list > args) { +const string queryString(const list& args) { ostringstream os; return str(queryString(args, os)); } diff --git a/sca-cpp/trunk/modules/http/httpd.hpp b/sca-cpp/trunk/modules/http/httpd.hpp index e090c2fc35..255f0aa31b 100644 --- a/sca-cpp/trunk/modules/http/httpd.hpp +++ b/sca-cpp/trunk/modules/http/httpd.hpp @@ -330,13 +330,13 @@ const string unescape(const string& uri) { /** * Unescape a list of key of value pairs representing query args. */ -const list unescapeArg(const list a) { - return mklist(car(a), unescape(cadr(a))); +const value unescapeArg(const value& a) { + return mklist(car(a), unescape(cadr(a))); } -const list > unescapeArgs(const list > args) { +const list unescapeArgs(const list& args) { debug(args, "httpd::unescape::args"); - const list > uargs = map, list>(unescapeArg, args); + const list uargs = map(unescapeArg, args); debug(uargs, "httpd::unescape::result"); return uargs; } @@ -344,7 +344,7 @@ const list > unescapeArgs(const list > args) { /** * Returns a list of key value pairs from the args in a query string. */ -const list queryArg(const string& s) { +const value queryArg(const string& s) { debug(s, "httpd::queryArg::string"); const list t = tokenize("=", s); if (isNil(cdr(t))) @@ -359,27 +359,27 @@ const string fixupQueryArgs(const string& a) { return join("&", t); } -const list > queryArgs(const string& a) { - return map>(queryArg, tokenize("&", fixupQueryArgs(a))); +const list queryArgs(const string& a) { + return map(queryArg, tokenize("&", fixupQueryArgs(a))); } /** * Returns a list of key value pairs from the args in an HTTP request. */ -const list > queryArgs(const request_rec* const r) { +const list queryArgs(const request_rec* const r) { if (r->args == NULL) - return list >(); + return nilListValue; return queryArgs(r->args); } /** * Converts the args received in a POST to a list of key value pairs. */ -const list > postArgs(const list& a) { +const list postArgs(const list& a) { if (isNil(a)) - return list >(); + return nilListValue; const list l = car(a); - return cons(l, postArgs(cdr(a))); + return cons(l, postArgs(cdr(a))); } /** @@ -397,7 +397,7 @@ const int setupReadPolicy(request_rec* const r) { } /** - * Read the content of a POST or PUT. + * Read the content of an HTTP request. */ const list read(request_rec* const r) { char b[1024]; diff --git a/sca-cpp/trunk/modules/http/mod-openauth.cpp b/sca-cpp/trunk/modules/http/mod-openauth.cpp index 797e8c10b5..1b70f27744 100644 --- a/sca-cpp/trunk/modules/http/mod-openauth.cpp +++ b/sca-cpp/trunk/modules/http/mod-openauth.cpp @@ -178,7 +178,7 @@ const failable userInfoFromSession(const string& realm, request_rec* cons * Return the user info from a form auth session cookie. */ const failable userInfoFromCookie(const value& sid, const string& realm, request_rec* const r) { - const list> info = httpd::queryArgs(sid); + const list info = httpd::queryArgs(sid); debug(info, "modopenauth::userInfoFromCookie::info"); const list user = assoc(realm + "-user", info); if(isNil(user)) @@ -212,7 +212,7 @@ const failable userInfoFromHeader(const char* header, const string& realm /** * Handle an authenticated request. */ -const failable authenticated(const list >& info, request_rec* const r) { +const failable authenticated(const list& info, request_rec* const r) { debug(info, "modopenauth::authenticated::info"); // Store user info in the request @@ -248,7 +248,7 @@ static int checkAuthn(request_rec* const r) { debug(atype, "modopenauth::checkAuthn::auth_type"); // Get the request args - const list > args = httpd::queryArgs(r); + const list args = httpd::queryArgs(r); // Get session id from the request const maybe sid = sessionID(r, "TuscanyOpenAuth"); diff --git a/sca-cpp/trunk/modules/http/openauth.hpp b/sca-cpp/trunk/modules/http/openauth.hpp index dcf405d487..1c49c4254c 100644 --- a/sca-cpp/trunk/modules/http/openauth.hpp +++ b/sca-cpp/trunk/modules/http/openauth.hpp @@ -92,9 +92,9 @@ const string cookie(const string& key, const string& sid, const string& domain) * Redirect to the configured login page. */ const failable login(const string& page, const value& ref, const value& attempt, request_rec* const r) { - const list > rarg = ref == string("/")? list >() : mklist >(mklist("openauth_referrer", httpd::escape(httpd::url(isNil(ref)? r->uri : ref, r)))); - const list > aarg = isNil(attempt)? list >() : mklist >(mklist("openauth_attempt", attempt)); - const list > largs = append >(rarg, aarg); + const list rarg = ref == string("/")? nilListValue : mklist(mklist("openauth_referrer", httpd::escape(httpd::url(isNil(ref)? r->uri : ref, r)))); + const list aarg = isNil(attempt)? nilListValue : mklist(mklist("openauth_attempt", attempt)); + const list largs = append(rarg, aarg); const string loc = isNil(largs)? httpd::url(page, r) : httpd::url(page, r) + string("?") + http::queryString(largs); debug(loc, "openauth::login::uri"); return httpd::externalRedirect(loc, r); diff --git a/sca-cpp/trunk/modules/json/json.hpp b/sca-cpp/trunk/modules/json/json.hpp index b3545476a1..497624070b 100644 --- a/sca-cpp/trunk/modules/json/json.hpp +++ b/sca-cpp/trunk/modules/json/json.hpp @@ -389,13 +389,13 @@ inline const string funcName(const string& f) { * Returns a list of param values other than the id and method args from a list * of key value pairs. */ -inline const list queryParams(const list >& a) { +inline const list queryParams(const list& a) { if (isNil(a)) return nilListValue; const list p = car(a); if (car(p) == value("id") || car(p) == value("method")) return queryParams(cdr(a)); - return cons(cadr(p), queryParams(cdr(a))); + return cons(cadr(p), queryParams(cdr(a))); } } diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp index c9d8607144..a7238804f8 100644 --- a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp +++ b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp @@ -64,7 +64,7 @@ public: gc_mutable_ref ca; gc_mutable_ref cert; gc_mutable_ref key; - gc_mutable_ref > > appkeys; + gc_mutable_ref > appkeys; gc_mutable_ref > mcaddrs; gc_mutable_ref mc; gc_mutable_ref > cs; @@ -96,7 +96,7 @@ public: const char* const dir; bool enabled; gc_mutable_ref login; - gc_mutable_ref > > scopeattrs; + gc_mutable_ref > scopeattrs; gc_mutable_ref > apcs; }; @@ -139,7 +139,7 @@ const failable userInfo(const value& sid, const memcache::MemCached& mc) /** * Handle an authenticated request. */ -const failable authenticated(const list >& userinfo, const bool check, request_rec* const r, const list >& scopeattrs, const list& apcs) { +const failable authenticated(const list& userinfo, const bool check, request_rec* const r, const list& scopeattrs, const list& apcs) { debug(userinfo, "modoauth2::authenticated::userinfo"); if (isNil(scopeattrs)) { @@ -179,7 +179,7 @@ const failable authenticated(const list >& userinfo, const bool * Convert a query string containing oauth args to an authorization header. */ const string header(const string& qs, const string& redir, const string& verif) { - const list > args = httpd::queryArgs(qs); + const list args = httpd::queryArgs(qs); ostringstream hdr; hdr << "Authorization: OAuth " << "oauth_nonce=\"" << string(cadr(assoc("oauth_nonce", args))) << "\", "; @@ -220,7 +220,7 @@ const list sign(const string& verb, const string& uri, const list /** * Handle an authorize request. */ -const failable authorize(const list >& args, request_rec* const r, const list >& appkeys, const memcache::MemCached& mc) { +const failable authorize(const list& args, request_rec* const r, const list& appkeys, const memcache::MemCached& mc) { // Extract authorize, access_token, client ID and info URIs const list ref = assoc("openauth_referrer", args); if (isNil(ref) || isNil(cdr(ref))) @@ -242,7 +242,7 @@ const failable authorize(const list >& args, request_rec* const return mkfailure("Missing oauth1_info parameter"); // Build the redirect URI - const list > redirargs = mklist >(tok, cid, info, ref); + const list redirargs = mklist(tok, cid, info, ref); const string redir = httpd::url("/oauth1/access_token/", r) + string("?") + http::queryString(redirargs); debug(redir, "modoauth1::authorize::redir"); @@ -253,7 +253,7 @@ const failable authorize(const list >& args, request_rec* const list appkey = cadr(app); // Build and sign the request token URI - const string requri = httpd::unescape(cadr(req)) + string("&") + http::queryString(mklist >(mklist("oauth_callback", httpd::escape(redir)))); + const string requri = httpd::unescape(cadr(req)) + string("&") + http::queryString(mklist(mklist("oauth_callback", httpd::escape(redir)))); const list srequri = sign("POST", requri, appkey, emptyString, emptyString); debug(srequri, "modoauth1::authorize::srequri"); @@ -267,7 +267,7 @@ const failable authorize(const list >& args, request_rec* const const string res(pres); free(pres); debug(res, "modoauth1::authorize::res"); - const list > resargs = httpd::queryArgs(res); + const list resargs = httpd::queryArgs(res); // Retrieve the request token const list conf = assoc("oauth_callback_confirmed", resargs); @@ -286,7 +286,7 @@ const failable authorize(const list >& args, request_rec* const return mkfailure(prc); // Redirect to the authorize URI - const string authuri = httpd::unescape(cadr(auth)) + string("?") + http::queryString(mklist >(tv)); + const string authuri = httpd::unescape(cadr(auth)) + string("?") + http::queryString(mklist(tv)); debug(authuri, "modoauth1::authorize::authuri"); return httpd::externalRedirect(authuri, r); } @@ -343,7 +343,7 @@ const failable > profileUserInfo(const value& cid, const string& inf /** * Handle an access_token request. */ -const failable accessToken(const list >& args, request_rec* r, const list >& appkeys, const list >& scopeattrs, const list& apcs, const memcache::MemCached& mc) { +const failable accessToken(const list& args, request_rec* r, const list& appkeys, const list& scopeattrs, const list& apcs, const memcache::MemCached& mc) { // Extract access_token URI, client ID and verification code const list ref = assoc("openauth_referrer", args); @@ -377,7 +377,7 @@ const failable accessToken(const list >& args, request_rec* r, return mkfailure(sv); // Build and sign access token request URI - const string tokuri = httpd::unescape(cadr(tok)) + string("?") + http::queryString(mklist >(vv)); + const string tokuri = httpd::unescape(cadr(tok)) + string("?") + http::queryString(mklist(vv)); const list stokuri = sign("POST", tokuri, appkey, cadr(tv), content(sv)); debug(stokuri, "modoauth1::access_token::stokuri"); @@ -391,7 +391,7 @@ const failable accessToken(const list >& args, request_rec* r, const string tokres(ptokres); free(ptokres); debug(tokres, "modoauth1::access_token::res"); - const list > tokresargs = httpd::queryArgs(tokres); + const list tokresargs = httpd::queryArgs(tokres); // Retrieve the access token const list atv = assoc("oauth_token", tokresargs); @@ -475,7 +475,7 @@ static int checkAuthn(request_rec *r) { } // Get the request args - const list > args = httpd::queryArgs(r); + const list args = httpd::queryArgs(r); // Handle OAuth authorize request step if (string(r->uri) == "/oauth1/authorize/") { @@ -515,7 +515,7 @@ int postConfigMerge(const ServerConf& mainsc, server_rec* const s) { debug(httpd::serverName(s), "modoauth1::postConfigMerge::serverName"); // Merge configuration from main server - if (isNil((list >)sc.appkeys)) + if (isNil((list)sc.appkeys)) sc.appkeys = mainsc.appkeys; if (isNil((list)sc.mcaddrs)) sc.mcaddrs = mainsc.mcaddrs; @@ -575,7 +575,7 @@ void childInit(apr_pool_t* const p, server_rec* const s) { char* const confAppKey(cmd_parms* cmd, unused void *c, char *arg1, char* arg2, char* arg3) { const gc_scoped_pool sp(cmd->pool); ServerConf& sc = httpd::serverConf(cmd, &mod_tuscany_oauth1); - sc.appkeys = cons >(mklist(arg1, mklist(arg2, arg3)), (list >)sc.appkeys); + sc.appkeys = cons(mklist(arg1, mklist(arg2, arg3)), (list)sc.appkeys); return NULL; } char* confMemcached(cmd_parms *cmd, unused void *c, char *arg) { @@ -617,7 +617,7 @@ char* confCertKeyFile(cmd_parms *cmd, unused void *c, char *arg) { char* confScopeAttr(cmd_parms *cmd, void* c, char* arg1, char* arg2) { const gc_scoped_pool sp(cmd->pool); DirConf& dc = httpd::dirConf(c); - dc.scopeattrs = cons >(mklist(arg1, arg2), (list >)dc.scopeattrs); + dc.scopeattrs = cons(mklist(arg1, arg2), (list)dc.scopeattrs); return NULL; } char* confAuthnProvider(cmd_parms *cmd, void *c, char* arg) { diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp index bedf83325f..5bc212a681 100644 --- a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp +++ b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp @@ -58,7 +58,7 @@ public: gc_mutable_ref ca; gc_mutable_ref cert; gc_mutable_ref key; - gc_mutable_ref > > appkeys; + gc_mutable_ref > appkeys; gc_mutable_ref > mcaddrs; gc_mutable_ref mc; gc_mutable_ref > cs; @@ -90,7 +90,7 @@ public: const char* const dir; bool enabled; gc_mutable_ref login; - gc_mutable_ref > > scopeattrs; + gc_mutable_ref > scopeattrs; gc_mutable_ref > apcs; }; @@ -133,7 +133,7 @@ const failable userInfo(const value& sid, const memcache::MemCached& mc) /** * Handle an authenticated request. */ -const failable authenticated(const list >& userinfo, const bool check, request_rec* const r, const list >& scopeattrs, const list& apcs) { +const failable authenticated(const list& userinfo, const bool check, request_rec* const r, const list& scopeattrs, const list& apcs) { debug(userinfo, "modoauth2::authenticated::userinfo"); if (isNil(scopeattrs)) { @@ -172,7 +172,7 @@ const failable authenticated(const list >& userinfo, const bool /** * Handle an authorize request. */ -const failable authorize(const list >& args, request_rec* const r, const list >& appkeys) { +const failable authorize(const list& args, request_rec* const r, const list& appkeys) { // Extract authorize, access_token, client ID and info URIs const list ref = assoc("openauth_referrer", args); if (isNil(ref) || isNil(cdr(ref))) @@ -199,7 +199,7 @@ const failable authorize(const list >& args, request_rec* const debug(redir, "modoauth2::authorize::redir"); // Build the state URI - const list > stargs = mklist >(tok, cid, info, ref); + const list stargs = mklist(tok, cid, info, ref); const string state = http::queryString(stargs); debug(state, "modoauth2::authorize::state"); @@ -211,7 +211,7 @@ const failable authorize(const list >& args, request_rec* const // Redirect to the authorize URI const list adisplay = (isNil(display) || isNil(cdr(display)))? nilListValue : mklist("display", cadr(display)); - const list > aargs = mklist >(mklist("response_type", "code"), mklist("client_id", car(appkey)), mklist("scope", cadr(scope)), adisplay, mklist("redirect_uri", httpd::escape(redir)), mklist("state", httpd::escape(state))); + const list aargs = mklist(mklist("response_type", "code"), mklist("client_id", car(appkey)), mklist("scope", cadr(scope)), adisplay, mklist("redirect_uri", httpd::escape(redir)), mklist("state", httpd::escape(state))); const string uri = httpd::unescape(cadr(auth)) + string("?") + http::queryString(aargs); debug(uri, "modoauth2::authorize::uri"); return httpd::externalRedirect(uri, r); @@ -229,13 +229,13 @@ const failable > profileUserInfo(const value& cid, const list /** * Handle an access_token request. */ -const failable accessToken(const list >& args, request_rec* r, const list >& appkeys, const http::CURLSession& cs, const list >& scopeattrs, const list& apcs, const memcache::MemCached& mc) { +const failable accessToken(const list& args, request_rec* r, const list& appkeys, const http::CURLSession& cs, const list& scopeattrs, const list& apcs, const memcache::MemCached& mc) { // Extract access_token URI, client ID and authorization code parameters const list state = assoc("state", args); if (isNil(state) || isNil(cdr(state))) return mkfailure("Missing state parameter"); - const list >& stargs = httpd::queryArgs(httpd::unescape(cadr(state))); + const list& stargs = httpd::queryArgs(httpd::unescape(cadr(state))); const list ref = assoc("openauth_referrer", stargs); if (isNil(ref) || isNil(cdr(ref))) return mkfailure("Missing openauth_referrer parameter"); @@ -263,7 +263,7 @@ const failable accessToken(const list >& args, request_rec* r, debug(redir, "modoauth2::access_token::redir"); // Request access token - const list > targs = mklist >(mklist("client_id", car(appkey)), mklist("redirect_uri", httpd::escape(redir)), mklist("client_secret", cadr(appkey)), code, mklist("grant_type", "authorization_code")); + const list targs = mklist(mklist("client_id", car(appkey)), mklist("redirect_uri", httpd::escape(redir)), mklist("client_secret", cadr(appkey)), code, mklist("grant_type", "authorization_code")); const string tqs = http::queryString(targs); debug(tqs, "modoauth2::access_token::tokenqs"); const string turi = httpd::unescape(cadr(tok)); @@ -285,7 +285,7 @@ const failable accessToken(const list >& args, request_rec* r, // Request user info // TODO Make this step configurable - const list > iargs = mklist >(tv); + const list iargs = mklist(tv); const string iuri = httpd::unescape(cadr(info)) + string("?") + http::queryString(iargs); debug(iuri, "modoauth2::access_token::infouri"); const failable profres = http::get(iuri, cs); @@ -350,7 +350,7 @@ static int checkAuthn(request_rec *r) { } // Get the request args - const list > args = httpd::queryArgs(r); + const list args = httpd::queryArgs(r); // Handle OAuth authorize request step if (string(r->uri) == "/oauth2/authorize/") { @@ -390,7 +390,7 @@ int postConfigMerge(const ServerConf& mainsc, server_rec* const s) { debug(httpd::serverName(s), "modoauth2::postConfigMerge::serverName"); // Merge configuration from main server - if (isNil((list >)sc.appkeys)) + if (isNil((list)sc.appkeys)) sc.appkeys = mainsc.appkeys; if (isNil((list)sc.mcaddrs)) sc.mcaddrs = mainsc.mcaddrs; @@ -450,7 +450,7 @@ void childInit(apr_pool_t* const p, server_rec* const s) { char* confAppKey(cmd_parms *cmd, unused void *c, char *arg1, char* arg2, char* arg3) { const gc_scoped_pool sp(cmd->pool); ServerConf& sc = httpd::serverConf(cmd, &mod_tuscany_oauth2); - sc.appkeys = cons >(mklist(arg1, mklist(arg2, arg3)), (list >)sc.appkeys); + sc.appkeys = cons(mklist(arg1, mklist(arg2, arg3)), (list)sc.appkeys); return NULL; } char* confMemcached(cmd_parms *cmd, unused void *c, char *arg) { @@ -492,7 +492,7 @@ char* confCertKeyFile(cmd_parms *cmd, unused void *c, char *arg) { char* confScopeAttr(cmd_parms *cmd, void* c, char* arg1, char* arg2) { const gc_scoped_pool sp(cmd->pool); DirConf& dc = httpd::dirConf(c); - dc.scopeattrs = cons >(mklist(arg1, arg2), (list >)dc.scopeattrs); + dc.scopeattrs = cons(mklist(arg1, arg2), (list)dc.scopeattrs); return NULL; } char* confAuthnProvider(cmd_parms *cmd, void *c, char* arg) { diff --git a/sca-cpp/trunk/modules/rss/rss.hpp b/sca-cpp/trunk/modules/rss/rss.hpp index 7fba736065..348d50e8f3 100644 --- a/sca-cpp/trunk/modules/rss/rss.hpp +++ b/sca-cpp/trunk/modules/rss/rss.hpp @@ -45,15 +45,16 @@ const value entry("entry"); * Convert a list of elements to a list of element values representing an RSS entry. */ const list entryElementValues(const list& e) { - const list lt = filter(selector(mklist(element, "title")), e); + const list lt = elementChildren("title", e); const value t = isNil(lt)? value(emptyString) : elementValue(car(lt)); - const list li = filter(selector(mklist(element, "link")), e); + const list li = elementChildren("link", e); const value i = isNil(li)? value(emptyString) : elementValue(car(li)); - const list ld = filter(selector(mklist(element, "description")), e); + const list ld = elementChildren("description", e); return append(nilListValue + element + entry + value(nilListValue + element + value("title") + t) + value(nilListValue + element + value("id") + i), - isNil(ld)? nilListValue : mklist(value(nilListValue + element + value("content") + elementValue(car(ld))))); + isNil(ld)? nilListValue : isAttribute(elementValue(car(ld)))? nilListValue : + mklist(value(nilListValue + element + value("content") + elementValue(car(ld))))); } /** @@ -91,10 +92,10 @@ const failable > readRSSFeed(const list& ilist) { const list f = content(xml::readElements(ilist)); if (isNil(f)) return mkfailure >("Empty feed"); - const list c = filter(selector(mklist(element, "channel")), car(f)); - const list t = filter(selector(mklist(element, "title")), car(c)); - const list i = filter(selector(mklist(element, "link")), car(c)); - const list e = filter(selector(mklist(element, "item")), car(c)); + const list c = elementChildren("channel", car(f)); + const list t = elementChildren("title", car(c)); + const list i = elementChildren("link", car(c)); + const list e = elementChildren("item", car(c)); return mklist(append(nilListValue + element + feed + value(nilListValue + element + value("title") + elementValue(car(t))) + value(nilListValue + element + value("id") + elementValue(car(i))), @@ -150,9 +151,9 @@ const failable > writeRSSEntry(const list& l) { */ template const failable writeRSSFeed(const lambda& reduce, const R& initial, const list& ll) { const list l = isNil(ll)? ll : (list)car(ll); - const list lt = filter(selector(mklist(element, "title")), l); + const list lt = elementChildren("title", l); const value t = isNil(lt)? value(emptyString) : elementValue(car(lt)); - const list li = filter(selector(mklist(element, "id")), l); + const list li = elementChildren("id", l); const value i = isNil(li)? value(emptyString) : elementValue(car(li)); const list c = nilListValue + (nilListValue + element + "title" + t) @@ -160,7 +161,7 @@ template const failable writeRSSFeed(const lambda le = filter(selector(mklist(element, entry)), l); + const list le = elementChildren(entry, l); if (isNil(le)) { const list fe = nilListValue + element + "rss" + (nilListValue + attribute + "version" + "2.0") diff --git a/sca-cpp/trunk/modules/scdl/scdl-test.cpp b/sca-cpp/trunk/modules/scdl/scdl-test.cpp index 9daacb5559..2c098d3c53 100644 --- a/sca-cpp/trunk/modules/scdl/scdl-test.cpp +++ b/sca-cpp/trunk/modules/scdl/scdl-test.cpp @@ -53,8 +53,8 @@ const bool testComponents() { const value catalog = named(string("Catalog"), c); assert(name(catalog) == string("Catalog")); - const list t = mkbtree(sort(nameToElementAssoc(c))); - assert(assoctree("Catalog", t) == mklist("Catalog" , cadr(c))); + const list t = mkrbtree(sort(nameToElementAssoc(c))); + assert(rbtreeAssoc("Catalog", t) == mklist("Catalog" , cadr(c))); return true; } @@ -89,8 +89,8 @@ const bool testReferences() { assert(uri(binding) == nilValue); assert(bindingType(binding) == "binding.jsonrpc"); - const list t = mkbtree(sort(referenceToTargetAssoc(references(store)))); - assert(assoctree("shoppingCart", t) == mklist(string("shoppingCart"), string("ShoppingCart/Cart"))); + const list t = mkrbtree(sort(referenceToTargetAssoc(references(store)))); + assert(rbtreeAssoc("shoppingCart", t) == mklist(string("shoppingCart"), string("ShoppingCart/Cart"))); return true; } diff --git a/sca-cpp/trunk/modules/scheme/primitive.hpp b/sca-cpp/trunk/modules/scheme/primitive.hpp index 2e0c4f62dd..4815e9a497 100644 --- a/sca-cpp/trunk/modules/scheme/primitive.hpp +++ b/sca-cpp/trunk/modules/scheme/primitive.hpp @@ -26,9 +26,12 @@ * Script evaluator primitive functions. */ +#include + #include "stream.hpp" #include "function.hpp" #include "list.hpp" +#include "tree.hpp" #include "value.hpp" #include "parallel.hpp" @@ -90,10 +93,30 @@ inline const value listProc(const list& args) { } inline const value assocProc(const list& args) { - return assoc(car(args), (list >)cadr(args)); + return assoc(car(args), (list)cadr(args)); +} + +inline const value delAssocProc(const list& args) { + return delAssoc(car(args), (list)cadr(args)); +} + +inline const value substAssocProc(const list& args) { + return substAssoc(car(args), (list)cadr(args), (list)caddr(args)); +} + +inline const value treeDelAssocProc(const list& args) { + return treeDelAssoc((list)car(args), (list)cadr(args)); +} + +inline const value treeSubstAssocProc(const list& args) { + return treeSubstAssoc((list)car(args), (list)cadr(args), (list)caddr(args)); } -inline const value nulProc(const list& args) { +inline const value treeSelectAssocProc(const list& args) { + return treeSelectAssoc((list)car(args), (list)cadr(args)); +} + +inline const value nullProc(const list& args) { const value v(car(args)); if (isNil(v)) return true; @@ -106,6 +129,14 @@ inline const value equalProc(const list& args) { return (bool)(car(args) == cadr(args)); } +inline const value greaterProc(const list& args) { + return (bool)(car(args) > cadr(args)); +} + +inline const value lesserProc(const list& args) { + return (bool)(car(args) < cadr(args)); +} + inline const value addProc(const list& args) { if (isNil(cdr(args))) return (double)car(args); @@ -126,6 +157,10 @@ inline const value divProc(const list& args) { return (double)car(args) / (double)cadr(args); } +inline const value sqrtProc(const list& args) { + return (double)sqrt((double)car(args)); +} + inline const value displayProc(const list& args) { if (isNil(args)) { displayStream() << endl; @@ -216,14 +251,22 @@ inline const list primitiveProcedureNames() { + "cdr" + "cons" + "list" - + "nul" + + "null?" + "=" + "equal?" + + "<" + + ">" + "+" + "-" + "*" + "/" + + "sqrt" + "assoc" + + "del-assoc" + + "subst-assoc" + + "tree-select-assoc" + + "tree-del-assoc" + + "tree-subst-assoc" + "cadr" + "caddr" + "cadddr" @@ -242,14 +285,22 @@ inline const list primitiveProcedureObjects() { + primitiveProcedure(cdrProc) + primitiveProcedure(consProc) + primitiveProcedure(listProc) - + primitiveProcedure(nulProc) + + primitiveProcedure(nullProc) + primitiveProcedure(equalProc) + primitiveProcedure(equalProc) + + primitiveProcedure(lesserProc) + + primitiveProcedure(greaterProc) + primitiveProcedure(addProc) + primitiveProcedure(subProc) + primitiveProcedure(mulProc) + primitiveProcedure(divProc) + + primitiveProcedure(sqrtProc) + primitiveProcedure(assocProc) + + primitiveProcedure(delAssocProc) + + primitiveProcedure(substAssocProc) + + primitiveProcedure(treeSelectAssocProc) + + primitiveProcedure(treeDelAssocProc) + + primitiveProcedure(treeSubstAssocProc) + primitiveProcedure(cadrProc) + primitiveProcedure(caddrProc) + primitiveProcedure(cadddrProc) diff --git a/sca-cpp/trunk/modules/scheme/test.scm b/sca-cpp/trunk/modules/scheme/test.scm index 4bbff6e5c2..41d6296ba3 100644 --- a/sca-cpp/trunk/modules/scheme/test.scm +++ b/sca-cpp/trunk/modules/scheme/test.scm @@ -22,7 +22,7 @@ ; ATOMPub test case (define (get id) - (if (nul id) + (if (null? id) '((feed (title "Sample Feed") (id "123456789") (entry (((title "Item") (id "111") (content (item (name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99)))) ((title "Item") (id "222") (content (item (name "Orange") (currencyCode "USD") (currencySymbol "$") (price 3.55)))) diff --git a/sca-cpp/trunk/patches/jansson-2.4.patch b/sca-cpp/trunk/patches/jansson-2.4.patch index 006d69d8c3..69a195d46f 100644 --- a/sca-cpp/trunk/patches/jansson-2.4.patch +++ b/sca-cpp/trunk/patches/jansson-2.4.patch @@ -5,7 +5,7 @@ size_t length; - ret = snprintf(buffer, size, "%.17g", value); -+ ret = snprintf(buffer, size, "%g", value); ++ ret = snprintf(buffer, size, "%.16g", value); if(ret < 0) return -1; diff --git a/sca-cpp/trunk/samples/store-constdb/shopping-cart.scm b/sca-cpp/trunk/samples/store-constdb/shopping-cart.scm index e653f1e33c..3dff67e99c 100644 --- a/sca-cpp/trunk/samples/store-constdb/shopping-cart.scm +++ b/sca-cpp/trunk/samples/store-constdb/shopping-cart.scm @@ -23,7 +23,7 @@ ; Return an empty cart if not found (define (getcart id cache) (define cart (cache "get" (list id))) - (if (nul cart) + (if (null? cart) (list) cart) ) @@ -39,7 +39,7 @@ ; Find an item in the cart (define (find id cart) - (if (nul cart) + (if (null? cart) (list (list 'entry (list 'title "Item") (list 'id "0"))) (if (= id (cadr (caddr (car cart)))) (list (car cart)) @@ -48,7 +48,7 @@ ; Get items from the cart (define (get id cache) - (if (nul id) + (if (null? id) (list (append (list 'feed (list 'title "Your Cart") (list 'id cartId)) (getcart cartId cache))) (find (car id) (getcart cartId cache)) ) @@ -56,7 +56,7 @@ ; Delete items from the cart (define (delete id cache) - (if (nul id) + (if (null? id) (cache "delete" (list cartId)) true ) @@ -69,7 +69,7 @@ ; Sum the prices of a list of items (define (sum items) - (if (nul items) + (if (null? items) 0 (+ (price (car items)) (sum (cdr items)))) ) diff --git a/sca-cpp/trunk/samples/store-cpp/htdocs/test/items-result.txt b/sca-cpp/trunk/samples/store-cpp/htdocs/test/items-result.txt index 0b456ea9d0..56f87d2778 100644 --- a/sca-cpp/trunk/samples/store-cpp/htdocs/test/items-result.txt +++ b/sca-cpp/trunk/samples/store-cpp/htdocs/test/items-result.txt @@ -1,23 +1 @@ -{ - "id": 1, - "result": [ - { - "name": "Apple", - "currencyCode": "USD", - "currencySymbol": "$", - "price": 2.99 - }, - { - "name": "Orange", - "currencyCode": "USD", - "currencySymbol": "$", - "price": 3.55 - }, - { - "name": "Pear", - "currencyCode": "USD", - "currencySymbol": "$", - "price": 1.55 - } - ] -} \ No newline at end of file +{"id":1,"result":[{"name":"Apple","currencyCode":"USD","currencySymbol":"$","price":2.99},{"name":"Orange","currencyCode":"USD","currencySymbol":"$","price":3.55},{"name":"Pear","currencyCode":"USD","currencySymbol":"$","price":1.55}]} \ No newline at end of file diff --git a/sca-cpp/trunk/samples/store-python/htdocs/test/items-result.txt b/sca-cpp/trunk/samples/store-python/htdocs/test/items-result.txt index d6aaf4d44a..788b7cdf89 100644 --- a/sca-cpp/trunk/samples/store-python/htdocs/test/items-result.txt +++ b/sca-cpp/trunk/samples/store-python/htdocs/test/items-result.txt @@ -1,23 +1 @@ -{ - "id": 1, - "result": [ - { - "name": "Mango", - "currencyCode": "USD", - "currencySymbol": "$", - "price": 2.99 - }, - { - "name": "Passion", - "currencyCode": "USD", - "currencySymbol": "$", - "price": 3.55 - }, - { - "name": "Kiwi", - "currencyCode": "USD", - "currencySymbol": "$", - "price": 1.55 - } - ] -} \ No newline at end of file +{"id":1,"result":[{"name":"Mango","currencyCode":"USD","currencySymbol":"$","price":2.99},{"name":"Passion","currencyCode":"USD","currencySymbol":"$","price":3.55},{"name":"Kiwi","currencyCode":"USD","currencySymbol":"$","price":1.55}]} \ No newline at end of file diff --git a/sca-cpp/trunk/samples/store-scheme/shopping-cart.scm b/sca-cpp/trunk/samples/store-scheme/shopping-cart.scm index e653f1e33c..3dff67e99c 100644 --- a/sca-cpp/trunk/samples/store-scheme/shopping-cart.scm +++ b/sca-cpp/trunk/samples/store-scheme/shopping-cart.scm @@ -23,7 +23,7 @@ ; Return an empty cart if not found (define (getcart id cache) (define cart (cache "get" (list id))) - (if (nul cart) + (if (null? cart) (list) cart) ) @@ -39,7 +39,7 @@ ; Find an item in the cart (define (find id cart) - (if (nul cart) + (if (null? cart) (list (list 'entry (list 'title "Item") (list 'id "0"))) (if (= id (cadr (caddr (car cart)))) (list (car cart)) @@ -48,7 +48,7 @@ ; Get items from the cart (define (get id cache) - (if (nul id) + (if (null? id) (list (append (list 'feed (list 'title "Your Cart") (list 'id cartId)) (getcart cartId cache))) (find (car id) (getcart cartId cache)) ) @@ -56,7 +56,7 @@ ; Delete items from the cart (define (delete id cache) - (if (nul id) + (if (null? id) (cache "delete" (list cartId)) true ) @@ -69,7 +69,7 @@ ; Sum the prices of a list of items (define (sum items) - (if (nul items) + (if (null? items) 0 (+ (price (car items)) (sum (cdr items)))) ) diff --git a/sca-cpp/trunk/samples/store-sql/shopping-cart.scm b/sca-cpp/trunk/samples/store-sql/shopping-cart.scm index e653f1e33c..3dff67e99c 100644 --- a/sca-cpp/trunk/samples/store-sql/shopping-cart.scm +++ b/sca-cpp/trunk/samples/store-sql/shopping-cart.scm @@ -23,7 +23,7 @@ ; Return an empty cart if not found (define (getcart id cache) (define cart (cache "get" (list id))) - (if (nul cart) + (if (null? cart) (list) cart) ) @@ -39,7 +39,7 @@ ; Find an item in the cart (define (find id cart) - (if (nul cart) + (if (null? cart) (list (list 'entry (list 'title "Item") (list 'id "0"))) (if (= id (cadr (caddr (car cart)))) (list (car cart)) @@ -48,7 +48,7 @@ ; Get items from the cart (define (get id cache) - (if (nul id) + (if (null? id) (list (append (list 'feed (list 'title "Your Cart") (list 'id cartId)) (getcart cartId cache))) (find (car id) (getcart cartId cache)) ) @@ -56,7 +56,7 @@ ; Delete items from the cart (define (delete id cache) - (if (nul id) + (if (null? id) (cache "delete" (list cartId)) true ) @@ -69,7 +69,7 @@ ; Sum the prices of a list of items (define (sum items) - (if (nul items) + (if (null? items) 0 (+ (price (car items)) (sum (cdr items)))) ) -- cgit v1.2.3