From cbc3f6e8d682502c1da5d57ef327017f1e30fc86 Mon Sep 17 00:00:00 2001 From: Jez Higgins Date: Sat, 20 Feb 2010 21:56:47 +0000 Subject: [PATCH] still chipping away at function-available --- include/XPath/impl/xpath_function_holder.hpp | 66 +++++++++++-------- .../XPath/impl/xpath_function_resolver.hpp | 9 +-- .../XSLT/impl/xslt_compilation_context.hpp | 21 ++++-- include/XSLT/impl/xslt_functions.hpp | 14 ++-- tests/XPath/execute_test.hpp | 4 +- tests/XPath/match_test.hpp | 4 +- tests/XPath/parse_test.hpp | 4 +- 7 files changed, 69 insertions(+), 53 deletions(-) diff --git a/include/XPath/impl/xpath_function_holder.hpp b/include/XPath/impl/xpath_function_holder.hpp index 2d842434..6466a1e4 100644 --- a/include/XPath/impl/xpath_function_holder.hpp +++ b/include/XPath/impl/xpath_function_holder.hpp @@ -15,7 +15,9 @@ namespace impl template XPathFunction* CreateFn(const std::vector >& argExprs) { return new function_type(argExprs); } -template +} // namespace impl + + template > class StandardXPathFunctionResolver { public: @@ -29,10 +31,13 @@ public: return standardFunction(namespace_uri, name, argExprs); } // resolveFuncton - virtual bool hasFunction(const string_type& namespace_uri, - const string_type& name) const + virtual std::vector > validNames() const { - return findFunction(namespace_uri, name); + std::vector > names; + for(const NamedFunction* fn = FunctionLookupTable; fn->name != 0; ++fn) + names.push_back(std::make_pair(string_adaptor::empty_string(), + string_adaptor::construct_from_utf8(fn->name))); + return names; } // hasFunction static XPathFunction* @@ -69,37 +74,40 @@ template const typename StandardXPathFunctionResolver::NamedFunction StandardXPathFunctionResolver::FunctionLookupTable[] = { // node-set functions - { "position", CreateFn, string_type, string_adaptor> }, - { "last", CreateFn, string_type, string_adaptor> }, - { "count", CreateFn, string_type, string_adaptor> }, - { "local-name", CreateFn, string_type, string_adaptor> }, - { "namespace-uri", CreateFn, string_type, string_adaptor> }, - { "name", CreateFn, string_type, string_adaptor> }, + { "position", impl::CreateFn, string_type, string_adaptor> }, + { "last", impl::CreateFn, string_type, string_adaptor> }, + { "count", impl::CreateFn, string_type, string_adaptor> }, + { "local-name", impl::CreateFn, string_type, string_adaptor> }, + { "namespace-uri", impl::CreateFn, string_type, string_adaptor> }, + { "name", impl::CreateFn, string_type, string_adaptor> }, // string functions - {"string", CreateFn, string_type, string_adaptor> }, - {"concat", CreateFn, string_type, string_adaptor> }, - {"starts-with", CreateFn, string_type, string_adaptor> }, - {"contains", CreateFn, string_type, string_adaptor> }, - {"substring-before", CreateFn, string_type, string_adaptor> }, - {"substring-after", CreateFn, string_type, string_adaptor> }, - {"substring", CreateFn, string_type, string_adaptor> }, - {"string-length", CreateFn, string_type, string_adaptor> }, - {"normalize-space", CreateFn, string_type, string_adaptor> }, - {"translate", CreateFn, string_type, string_adaptor> }, + {"string", impl::CreateFn, string_type, string_adaptor> }, + {"concat", impl::CreateFn, string_type, string_adaptor> }, + {"starts-with", impl::CreateFn, string_type, string_adaptor> }, + {"contains", impl::CreateFn, string_type, string_adaptor> }, + {"substring-before", impl::CreateFn, string_type, string_adaptor> }, + {"substring-after", impl::CreateFn, string_type, string_adaptor> }, + {"substring", impl::CreateFn, string_type, string_adaptor> }, + {"string-length", impl::CreateFn, string_type, string_adaptor> }, + {"normalize-space", impl::CreateFn, string_type, string_adaptor> }, + {"translate", impl::CreateFn, string_type, string_adaptor> }, // boolean functions - {"boolean", CreateFn, string_type, string_adaptor> }, - {"not", CreateFn, string_type, string_adaptor> }, - {"true", CreateFn, string_type, string_adaptor> }, - {"false", CreateFn, string_type, string_adaptor> }, + {"boolean", impl::CreateFn, string_type, string_adaptor> }, + {"not", impl::CreateFn, string_type, string_adaptor> }, + {"true", impl::CreateFn, string_type, string_adaptor> }, + {"false", impl::CreateFn, string_type, string_adaptor> }, // number functions - {"number", CreateFn, string_type, string_adaptor> }, - {"sum", CreateFn, string_type, string_adaptor> }, - {"floor", CreateFn, string_type, string_adaptor> }, - {"ceiling", CreateFn, string_type, string_adaptor> }, - {"round", CreateFn, string_type, string_adaptor> }, + {"number", impl::CreateFn, string_type, string_adaptor> }, + {"sum", impl::CreateFn, string_type, string_adaptor> }, + {"floor", impl::CreateFn, string_type, string_adaptor> }, + {"ceiling", impl::CreateFn, string_type, string_adaptor> }, + {"round", impl::CreateFn, string_type, string_adaptor> }, {0, 0} }; +namespace impl +{ + template class FunctionHolder : public XPathExpression_impl { diff --git a/include/XPath/impl/xpath_function_resolver.hpp b/include/XPath/impl/xpath_function_resolver.hpp index efa73a48..3156f575 100644 --- a/include/XPath/impl/xpath_function_resolver.hpp +++ b/include/XPath/impl/xpath_function_resolver.hpp @@ -26,7 +26,7 @@ public: const string_type& name, const std::vector >& argExprs) const = 0; - virtual bool hasFunction(const string_type& namespace_uri, const string_type& name) const = 0; + virtual std::vector > validNames() const = 0; }; // class FunctionResolver template @@ -59,10 +59,11 @@ public: throw UndefinedFunctionException(string_adaptor().asStdString(error)); } // resolveVariable - virtual bool hasFunction(const string_type&, const string_type&) const + virtual std::vector > validNames() const { - return false; - } // hasFunction + const std::vector > none; + return none; + } // validNames }; // NullFunctionResolver } // namespace XPath diff --git a/include/XSLT/impl/xslt_compilation_context.hpp b/include/XSLT/impl/xslt_compilation_context.hpp index 869ae50a..1f2c4ef5 100644 --- a/include/XSLT/impl/xslt_compilation_context.hpp +++ b/include/XSLT/impl/xslt_compilation_context.hpp @@ -177,6 +177,7 @@ private: if(name == "key") return new KeyFunction(stylesheet_.keys(), parser_.inScopeNamespaces(), argExprs); // format-number + // current if((name == "current") && (current_allowed_)) return new CurrentFunction(argExprs); // unparsed-entity-uri @@ -190,16 +191,24 @@ private: // element-available // function-available if(name == "function-available") - return new FunctionAvailableFunction(argExprs, xpath_); - + return new FunctionAvailableFunction(validNames(), parser_.inScopeNamespaces(), argExprs); + return 0; } // resolveFunction - virtual bool hasFunction(const std::string& /* namespace_uri */, - const std::string& /* name */) const + virtual std::vector > validNames() const { - return false; - } // hasFunction + static const char* functionNames[] = { "document", "key", /* format-number, */ "current", + /* unparsed-entity-uri, */ "generate-id", "system-property", + /* element-available, */ "function-available", 0 }; + + std::vector > names; + + for(int i = 0; functionNames[i] != 0; ++i) + names.push_back(std::make_pair("", functionNames[i])); + + return names; + } // validNames // NamespaceContext virtual std::string namespaceURI(const std::string& prefix) const diff --git a/include/XSLT/impl/xslt_functions.hpp b/include/XSLT/impl/xslt_functions.hpp index 6f945eb6..80be570b 100644 --- a/include/XSLT/impl/xslt_functions.hpp +++ b/include/XSLT/impl/xslt_functions.hpp @@ -223,10 +223,12 @@ class FunctionAvailableFunction : public Arabica::XPath::BooleanXPathFunction baseT; public: - FunctionAvailableFunction(const std::vector >& args, - const Arabica::XPath::XPath& xpath) : + FunctionAvailableFunction(const std::vector >& names, + const std::map& inscopeNamespaces, + const std::vector >& args) : Arabica::XPath::BooleanXPathFunction(1, 1, args), - xpath_(xpath) + functionNames_(names), + namespaces_(inscopeNamespaces) { } // FunctionAvailableFunction @@ -235,13 +237,15 @@ protected: const Arabica::XPath::ExecutionContext& executionContext) const { const std::string functionName = baseT::argAsString(0, context, executionContext); - const std::vector > dummyArgs; return false; } // doEvaluate private: - const Arabica::XPath::XPath& xpath_; + const std::vector > functionNames_; + const std::map namespaces_; + + static Arabica::XPath::StandardXPathFunctionResolver xpathStandardFunctionResolver; }; // class FunctionAvailableFunction } // namespace XSLT diff --git a/tests/XPath/execute_test.hpp b/tests/XPath/execute_test.hpp index b35bf8c3..8b541ded 100644 --- a/tests/XPath/execute_test.hpp +++ b/tests/XPath/execute_test.hpp @@ -77,7 +77,7 @@ public: }; // TestFunction template -class TestFunctionResolver : public Arabica::XPath::FunctionResolver +class TestFunctionResolver : public Arabica::XPath::NullFunctionResolver { //typedef string_adaptorstring_adaptor; public: @@ -90,8 +90,6 @@ public: return new TestFunction(argExprs); return 0; } // resolveFunction - - virtual bool hasFunction(const string_type&, const string_type&) const { return false; } }; // class TestFunctionResolver template diff --git a/tests/XPath/match_test.hpp b/tests/XPath/match_test.hpp index 66f4bda3..6f424792 100644 --- a/tests/XPath/match_test.hpp +++ b/tests/XPath/match_test.hpp @@ -46,7 +46,7 @@ public: }; // TestKeyFunction template -class TestIdKeyFunctionResolver : public Arabica::XPath::FunctionResolver +class TestIdKeyFunctionResolver : public Arabica::XPath::NullFunctionResolver { //typedef string_adaptorstring_adaptor; public: @@ -61,8 +61,6 @@ public: return new TestKeyFunction(argExprs); return 0; } // resolveFunction - - virtual bool hasFunction(const string_type&, const string_type&) const { return false; } }; // class TestFunctionResolver diff --git a/tests/XPath/parse_test.hpp b/tests/XPath/parse_test.hpp index 4c4c56e1..de9fda62 100644 --- a/tests/XPath/parse_test.hpp +++ b/tests/XPath/parse_test.hpp @@ -7,7 +7,7 @@ #include template -class TrueFunctionResolver : public Arabica::XPath::FunctionResolver +class TrueFunctionResolver : public Arabica::XPath::NullFunctionResolver { //typedef string_adaptorstring_adaptor; public: @@ -21,8 +21,6 @@ public: return new Arabica::XPath::impl::TrueFn(argExprs); return 0; } // resolveFunction - - virtual bool hasFunction(const string_type&, const string_type&) const { return false; } }; // class TrueFunctionResolver template