diff options
-rw-r--r-- | README.md | 12 | ||||
-rw-r--r-- | apps/uscxml-dot.cpp | 2 | ||||
-rw-r--r-- | src/bindings/CMakeLists.txt | 7 | ||||
-rw-r--r-- | src/bindings/swig/java/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/uscxml/Interpreter.cpp | 27 | ||||
-rw-r--r-- | src/uscxml/Interpreter.h | 1 | ||||
-rw-r--r-- | src/uscxml/URL.cpp | 28 | ||||
-rw-r--r-- | src/uscxml/URL.h | 4 | ||||
-rw-r--r-- | test/src/test-url.cpp | 112 |
9 files changed, 142 insertions, 55 deletions
@@ -96,6 +96,10 @@ This will perform a single iteration on the invoked components with a maximum of or return immediately. You will have to call this method every now and then if you are using e.g. the <tt>scenegraph</tt> invoker. +<b>Note:</b> Running the interpreter in its own thread via <tt>start</tt> is not exposed into the +language bindings. Just use the threading concepts native to your language to call <tt>step</tt> or +<tt>interpret</tt> as outlined below. + ### Blocking Interpretation with inline SCXML Interpreter scxml = Interpreter::fromXML("<scxml><final id="exit"/></scxml>"); scxml.interpret(); // blocking @@ -107,11 +111,13 @@ it will call <tt>runOnMainThread</tt> between stable configurations. Interpreter scxml = Interpreter::fromXML("<scxml><final id="exit"/></scxml>"); InterpreterState state; do { - state = interpreter.step(true); // boolean argument causes blocking or not - } while(state > 0) + state = interpreter.step(ms); + } while(state != InterpreterState::USCXML_FINISHED) Using <tt>step</tt>, you can run a single macrostep of the interpreter and interleave -interpretation with the rest of your code. +interpretation with the rest of your code. The <tt>step</tt> function will take an optional integer as +the time in milliseconds it will block and wait if no more events are available, default is to block +indefinitely until an event arrives or the interpreter finished. ### Callbacks for an Interpreter diff --git a/apps/uscxml-dot.cpp b/apps/uscxml-dot.cpp index 11e2994..e79c3f9 100644 --- a/apps/uscxml-dot.cpp +++ b/apps/uscxml-dot.cpp @@ -86,7 +86,7 @@ int main(int argc, char** argv) { try { // current option has to be the interpreter's name URL inputFile(argv[optind]); - Interpreter interpreter = Interpreter::fromURI(inputFile); + Interpreter interpreter = Interpreter::fromURI(inputFile.asString()); optind++; while(optind < argc) { diff --git a/src/bindings/CMakeLists.txt b/src/bindings/CMakeLists.txt index 25c11a1..edddc31 100644 --- a/src/bindings/CMakeLists.txt +++ b/src/bindings/CMakeLists.txt @@ -11,8 +11,9 @@ if (WIN32) LIST(APPEND CMAKE_PROGRAM_PATH "${PROJECT_BINARY_DIR}/../../swig/") endif() - LIST(APPEND CMAKE_PROGRAM_PATH "C:/Program Files/swig") # swig.exe - LIST(APPEND CMAKE_PROGRAM_PATH "C:/Program Files (x86)/swig") # swig.exe + file(GLOB POTENTIAL_SWIG "C:/Program Files/swig*" "C:/Program Files (x86)/swig*") + LIST(APPEND CMAKE_PROGRAM_PATH ${POTENTIAL_SWIG}) # swig.exe + # message(FATAL_ERROR "POTENTIAL_SWIG: ${POTENTIAL_SWIG}") endif() LIST(APPEND CMAKE_PROGRAM_PATH $ENV{SWIG_DIR}) @@ -29,7 +30,7 @@ if (SWIG_FOUND) message(STATUS "SWIG version > 3.0 is recommended, found ${SWIG_VERSION}") endif() else() - message(STATUS "SWIG version 2.0.5 is required, found ${SWIG_VERSION} - skipping java wrapper generation") + message(STATUS "SWIG version 2.0.5 is required, found ${SWIG_VERSION} - skipping wrapper generation") endif() else() message(STATUS "SWIG not found - skipping wrapper generation") diff --git a/src/bindings/swig/java/CMakeLists.txt b/src/bindings/swig/java/CMakeLists.txt index eb51f83..de2a161 100644 --- a/src/bindings/swig/java/CMakeLists.txt +++ b/src/bindings/swig/java/CMakeLists.txt @@ -31,7 +31,9 @@ set_target_properties(uscxmlNativeJava PROPERTIES COMPILE_FLAGS "-DSWIG") swig_link_libraries(uscxmlNativeJava uscxml) -FIND_PROGRAM(ANT_EXECUTABLE ant PATHS $ENV{ANT_HOME}/bin ENV PATH ) +file(GLOB POTENTIAL_ANT "C:/Program Files/apache-ant**/bin" "C:/Program Files (x86)/apache-ant**/bin") + +FIND_PROGRAM(ANT_EXECUTABLE ant PATHS $ENV{ANT_HOME}/bin ${POTENTIAL_ANT} ENV PATH ) if (ANT_EXECUTABLE) set(USCXML_LANGUAGE_BINDINGS "java ${USCXML_LANGUAGE_BINDINGS}") diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 5d9d1cd..dc53906 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -407,13 +407,9 @@ Interpreter Interpreter::fromXML(const std::string& xml) { return fromInputSource(inputSource); } -Interpreter Interpreter::fromURI(const std::string& uri) { - URL url(uri); - return fromURI(url); -} -Interpreter Interpreter::fromURI(const URL& uri) { - URL absUrl = uri; +Interpreter Interpreter::fromURI(const std::string& uri) { + URL absUrl(uri); if (!absUrl.isAbsolute()) { if (!absUrl.toAbsoluteCwd()) { ERROR_COMMUNICATION_THROW("URL is not absolute or does not have file schema"); @@ -426,15 +422,8 @@ Interpreter Interpreter::fromURI(const URL& uri) { Arabica::SAX::InputSource<std::string> inputSource; inputSource.setSystemId(absUrl.asString()); interpreter = fromInputSource(inputSource); -#if 0 - } else if (iequals(absUrl.scheme(), "http")) { - // handle http per arabica - this will not follow redirects - Arabica::SAX::InputSource<std::string> inputSource; - inputSource.setSystemId(absUrl.asString()); - interpreter = fromInputSource(inputSource); -#endif } else { - // use curl for everything else + // use curl for everything !file - even for http as arabica won't follow redirects std::stringstream ss; ss << absUrl; if (absUrl.downloadFailed()) { @@ -547,14 +536,14 @@ InterpreterImpl::~InterpreterImpl() { event.name = "unblock.and.die"; receive(event); - _thread->join(); - delete(_thread); } else { // this can happen with a shared_from_this at an interpretermonitor setInterpreterState(USCXML_DESTROYED); } + _thread->join(); + delete(_thread); } - join(); + if (_sendQueue) delete _sendQueue; @@ -1153,8 +1142,8 @@ bool InterpreterImpl::runOnMainThread(int fps, bool blocking) { return false; if (fps > 0) { - uint64_t nextRun = _lastRunOnMainThread + (1000 / fps); - if (blocking) { + if (blocking && _lastRunOnMainThread > 0) { + uint64_t nextRun = _lastRunOnMainThread + (1000 / fps); while(nextRun > tthread::timeStamp()) { tthread::this_thread::sleep_for(tthread::chrono::milliseconds(nextRun - tthread::timeStamp())); } diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index 70c9c0e..d6da7bd 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -586,7 +586,6 @@ public: const NameSpaceInfo& nameSpaceInfo); static Interpreter fromXML(const std::string& xml); static Interpreter fromURI(const std::string& uri); - static Interpreter fromURI(const URL& uri); static Interpreter fromClone(const Interpreter& other); Interpreter() : _impl() {} // the empty, invalid interpreter diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp index d18b55c..b1297d5 100644 --- a/src/uscxml/URL.cpp +++ b/src/uscxml/URL.cpp @@ -52,6 +52,21 @@ namespace uscxml { +void URL::dump() { + std::cout << ">>>" << asString() << "<<< "; + std::cout << (isAbsolute() ? "absolute" : "relative") << std::endl; + std::cout << "[scheme]" << scheme(); + std::cout << "[host]" << host(); + std::cout << "[port]" << port(); + std::cout << "[path]" << path(); + std::cout << "[file]" << file() << std::endl; + std::cout << "[segmts " << pathComponents().size() << "]: "; + for (int i = 0; i < pathComponents().size(); i++) { + std::cout << pathComponents()[i] << ", "; + } + std::cout << std::endl << std::endl; +} + std::string URL::tmpDir() { // try hard to find a temporary directory const char* tmpDir = NULL; @@ -157,7 +172,12 @@ std::string URL::getResourceDir() { } #endif -URLImpl::URLImpl(const std::string& url) : _handle(NULL), _uri(url), _isDownloaded(false), _hasFailed(false) { +URLImpl::URLImpl(const std::string& url) : _handle(NULL), _isDownloaded(false), _hasFailed(false) { + if (url[0] == '/') { + _uri = Arabica::io::URI("file://" + url); + } else { + _uri = Arabica::io::URI(url); + } std::stringstream ss(_uri.path()); std::string item; while(std::getline(ss, item, '/')) { @@ -472,8 +492,11 @@ const bool URLImpl::toAbsolute(const std::string& baseUrl) { return true; std::string uriStr = _uri.as_string(); +// std::cout << "## bas # " << baseUrl << std::endl; +// std::cout << "## rel # " << _uri.as_string() << std::endl; + #ifdef _WIN32 - if (baseUrl.find("file://") == 0) { + if (baseUrl.find("file://") == 0 && false) { _uri = Arabica::io::URI("file:///" + baseUrl.substr(7), _uri.as_string()); } else { _uri = Arabica::io::URI(baseUrl, _uri.as_string()); @@ -481,6 +504,7 @@ const bool URLImpl::toAbsolute(const std::string& baseUrl) { #else _uri = Arabica::io::URI(baseUrl, _uri.as_string()); #endif +// std::cout << "## abs # " << _uri.as_string() << std::endl; if (!_uri.is_absolute()) return false; diff --git a/src/uscxml/URL.h b/src/uscxml/URL.h index 00c2b30..09d5ed0 100644 --- a/src/uscxml/URL.h +++ b/src/uscxml/URL.h @@ -231,13 +231,15 @@ public: return URL(impl); } + void dump(); + void addMonitor(URLMonitor* monitor) { _impl->addMonitor(monitor); } void removeMonitor(URLMonitor* monitor) { _impl->removeMonitor(monitor); } - + bool downloadFailed() { return _impl->downloadFailed(); } diff --git a/test/src/test-url.cpp b/test/src/test-url.cpp index 5e5f4ea..1ebcac3 100644 --- a/test/src/test-url.cpp +++ b/test/src/test-url.cpp @@ -3,6 +3,8 @@ #include "uscxml/Interpreter.h"
#include "uscxml/server/HTTPServer.h"
+#include "uscxml/config.h"
+
#include <SAX/helpers/InputSourceResolver.hpp>
#include <assert.h>
@@ -42,17 +44,99 @@ bool canResolve(const std::string& url) { }
}
+void testFileURLs() {
+
+ // absolute
+ std::list<URL> absURLs;
+ {
+ // with explicit file schema
+ absURLs.push_back(URL("file:///"));
+ absURLs.push_back(URL("file:/"));
+
+ // platform specific
+ absURLs.push_back(URL("file:/Z:/Windows/workspace/uscxml/bin/com/carmeq/scxml/test-xml-access.xml"));
+ absURLs.push_back(URL("file:/C:/Windows/config.sys"));
+ absURLs.push_back(URL("file:/Macintosh%20HD/fileURLs/text.txt"));
+ absURLs.push_back(URL("file:/fileURLs/text.txt"));
+
+ // usual filesystem paths
+ absURLs.push_back(URL("C:\\Windows\\sradomski\\Desktop\\foo.txt"));
+// absURLs.push_back(URL("C:\\Windows\\Some Spaces\\index.txt"));
+// absURLs.push_back(URL("C:/Windows/Some Spaces/index.txt"));
+// absURLs.push_back(URL("/Users/sradomski/Desktop/"));
+// absURLs.push_back(URL("/Users/sradomski/Desktop/foo.txt"));
+ }
+
+ std::list<URL> absWithHostURLs;
+ {
+ absWithHostURLs.push_back(URL("file://hostname/"));
+ absWithHostURLs.push_back(URL("file://localhost/"));
+ absWithHostURLs.push_back(URL("file://C:/config.sys"));
+ absWithHostURLs.push_back(URL("file://config.sys"));
+ absWithHostURLs.push_back(URL("file://config.sys"));
+ absWithHostURLs.push_back(URL("file://Macintosh%20HD/fileURLs/text.txt"));
+ absWithHostURLs.push_back(URL("file://fileURLs/text.txt"));
+ absWithHostURLs.push_back(URL("file://Desktop/workspace/uscxml/bin/com/carmeq/scxml/test-xml-access.xml"));
+ absWithHostURLs.push_back(URL("file://Windows\\sradomski\\Desktop\\foo.txt"));
+
+ }
+ // relative URLs
+ std::list<URL> relURLs;
+
+ {
+ relURLs.push_back(URL("file"));
+ relURLs.push_back(URL("file:"));
+ relURLs.push_back(URL("file://"));
+
+ // platform specific
+ relURLs.push_back(URL("file:Macintosh%20HD/fileURLs/text.txt"));
+ relURLs.push_back(URL("file:fileURLs/text.txt"));
+ relURLs.push_back(URL("file:Document/Text.foo"));
+
+ // usual filesystem paths
+ relURLs.push_back(URL("Users\\sradomski\\Desktop\\foo.txt"));
+ relURLs.push_back(URL("Document\\Some Spaces\\index.txt"));
+ relURLs.push_back(URL("Document/Some Spaces/index.txt"));
+ relURLs.push_back(URL("Users/sradomski/Desktop/"));
+ relURLs.push_back(URL("Users/sradomski/Desktop/foo.txt"));
+ }
+
+ for (std::list<URL>::iterator absIter = absURLs.begin(); absIter != absURLs.end(); absIter++) {
+ absIter->dump();
+ assert(absIter->isAbsolute());
+ assert(absIter->scheme() == "file");
+ assert(absIter->host() == "");
+ }
+
+ for (std::list<URL>::iterator relIter = relURLs.begin(); relIter != relURLs.end(); relIter++) {
+ assert(!relIter->isAbsolute());
+ }
+
+ for (std::list<URL>::iterator absIter = absURLs.begin(); absIter != absURLs.end(); absIter++) {
+ for (std::list<URL>::iterator relIter = relURLs.begin(); relIter != relURLs.end(); relIter++) {
+ URL relURL(*relIter);
+ relURL.toAbsolute(*absIter);
+ assert(relURL.isAbsolute());
+ }
+ }
+
+}
+
int main(int argc, char** argv) {
#ifdef _WIN32
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
+ // some URLs from http://www-archive.mozilla.org/quality/networking/testing/filetests.html
+
HTTPServer::getInstance(8099, 8100);
std::string exeName = argv[0];
exeName = exeName.substr(exeName.find_last_of("\\/") + 1);
+ testFileURLs();
+
{
try {
URL url("http://asdfasdfasdfasdf.wgferg");
@@ -171,6 +255,7 @@ int main(int argc, char** argv) { content << url;
}
+#ifndef _WIN32
{
URL url("https://raw.github.com/tklab-tud/uscxml/master/test/samples/uscxml/test-ecmascript.scxml");
std::cout << url.asString() << std::endl;
@@ -179,17 +264,8 @@ int main(int argc, char** argv) { std::stringstream content;
content << url;
}
-
- {
- URL url("file:Document/Text.foo");
- std::cout << url.asString() << std::endl;
- assert(!url.isAbsolute());
- assert(iequals(url.scheme(), "file"));
- assert(iequals(url.host(), ""));
- assert(iequals(url.port(), "0"));
- assert(iequals(url.path(), "Document/Text.foo"));
- assert(iequals(url.asString(), "file:Document/Text.foo"));
- }
+#endif
+
{
URL url("test/index.html");
assert(iequals(url.scheme(), ""));
@@ -197,24 +273,12 @@ int main(int argc, char** argv) { assert(iequals(url.scheme(), "file"));
std::cout << url.asString() << std::endl;
}
- {
- URL url("C:\\Document\\Some Spaces\\index.txt");
- assert(url.isAbsolute());
- assert(iequals(url.scheme(), "file"));
- std::cout << url.asString() << std::endl;
- }
+
{
URL url = URL::toLocalFile("this is quite some content!", "txt");
std::cout << url.asLocalFile("txt");
assert(url.isAbsolute());
assert(iequals(url.scheme(), "file"));
}
- {
- URL url("C:\\Document\\Some Spaces\\index.txt");
- assert(iequals(url.pathComponents()[0], "C:"));
- assert(iequals(url.pathComponents()[1], "Document"));
- assert(iequals(url.pathComponents()[2], "Some Spaces"));
- assert(iequals(url.pathComponents()[3], "index.txt"));
- }
}
\ No newline at end of file |