summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-11-15 21:44:59 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-11-15 21:44:59 (GMT)
commitd2e90c02e5ad19a5857e7c7fb87f248182fdb32d (patch)
treee070363aea3eee493b30e378ba39bfd6250f2088
parent8c84c3550ad13ec19b6340bd8e9633aee91156af (diff)
downloaduscxml-d2e90c02e5ad19a5857e7c7fb87f248182fdb32d.zip
uscxml-d2e90c02e5ad19a5857e7c7fb87f248182fdb32d.tar.gz
uscxml-d2e90c02e5ad19a5857e7c7fb87f248182fdb32d.tar.bz2
Fixed file:// handling bug on windows
-rw-r--r--README.md12
-rw-r--r--apps/uscxml-dot.cpp2
-rw-r--r--src/bindings/CMakeLists.txt7
-rw-r--r--src/bindings/swig/java/CMakeLists.txt4
-rw-r--r--src/uscxml/Interpreter.cpp27
-rw-r--r--src/uscxml/Interpreter.h1
-rw-r--r--src/uscxml/URL.cpp28
-rw-r--r--src/uscxml/URL.h4
-rw-r--r--test/src/test-url.cpp112
9 files changed, 142 insertions, 55 deletions
diff --git a/README.md b/README.md
index 67f04f6..ff10818 100644
--- a/README.md
+++ b/README.md
@@ -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