Conflicts:
.gitignore .project .travis.yml Examples/Makefile.in Examples/test-suite/director_nspace.i
This commit is contained in:
commit
6dcbbf07db
134 changed files with 10011 additions and 15 deletions
54
Tools/javascript/javascript.cxx
Normal file
54
Tools/javascript/javascript.cxx
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "js_shell.h"
|
||||
|
||||
void print_usage() {
|
||||
std::cout << "javascript [-i] [-jsc|-v8] [-l module] <js-file>" << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
std::string scriptPath = "";
|
||||
|
||||
bool interactive = false;
|
||||
JSShell* shell = 0;
|
||||
|
||||
for (int idx = 1; idx < argc; ++idx) {
|
||||
if(strcmp(argv[idx], "-v8") == 0) {
|
||||
shell = JSShell::Create(JSShell::V8);
|
||||
} else if(strcmp(argv[idx], "-jsc") == 0) {
|
||||
shell = JSShell::Create(JSShell::JSC);
|
||||
} else if(strcmp(argv[idx], "-i") == 0) {
|
||||
interactive = true;
|
||||
} else {
|
||||
scriptPath = argv[idx];
|
||||
}
|
||||
}
|
||||
|
||||
if (shell == 0) {
|
||||
shell = JSShell::Create();
|
||||
}
|
||||
|
||||
bool failed = false;
|
||||
|
||||
if(interactive) {
|
||||
failed = !(shell->RunShell());
|
||||
} else {
|
||||
failed = !(shell->RunScript(scriptPath));
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
delete shell;
|
||||
printf("FAIL: Error during execution of script.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
delete shell;
|
||||
|
||||
return 0;
|
||||
}
|
||||
145
Tools/javascript/js_shell.cxx
Normal file
145
Tools/javascript/js_shell.cxx
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
#include "js_shell.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef __APPLE__
|
||||
#define LIBRARY_EXT ".dylib"
|
||||
#else
|
||||
#define LIBRARY_EXT ".so"
|
||||
#endif
|
||||
#include <dlfcn.h>
|
||||
#define LOAD_LIBRARY(name) dlopen(name, RTLD_LAZY)
|
||||
#define CLOSE_LIBRARY(handle) dlclose(handle)
|
||||
#define LIBRARY_ERROR dlerror
|
||||
#define LIBRARYFILE(name) std::string("lib").append(name).append(LIBRARY_EXT)
|
||||
#else
|
||||
#error "implement dll loading"
|
||||
#endif
|
||||
|
||||
|
||||
JSShell::~JSShell() {
|
||||
|
||||
for(std::vector<HANDLE>::iterator it = loaded_modules.begin();
|
||||
it != loaded_modules.end(); ++it) {
|
||||
HANDLE handle = *it;
|
||||
CLOSE_LIBRARY(handle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: this could be done more intelligent...
|
||||
// - can we achieve source file relative loading?
|
||||
// - better path resolution
|
||||
std::string JSShell::LoadModule(const std::string& name, HANDLE* library) {
|
||||
|
||||
// works only for posix like OSs
|
||||
size_t pathIdx = name.find_last_of("/");
|
||||
|
||||
std::string lib_name;
|
||||
std::string module_name;
|
||||
if (pathIdx == std::string::npos) {
|
||||
module_name = name;
|
||||
lib_name = std::string(name).append(LIBRARY_EXT);
|
||||
} else {
|
||||
std::string path = name.substr(0, pathIdx+1);
|
||||
module_name = name.substr(pathIdx+1);
|
||||
lib_name = path.append(module_name).append(LIBRARY_EXT);
|
||||
}
|
||||
|
||||
HANDLE handle = LOAD_LIBRARY(lib_name.c_str());
|
||||
if(handle == 0) {
|
||||
std::cout << "Could not load library " << lib_name << ":"
|
||||
<< std::endl << LIBRARY_ERROR() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
loaded_modules.push_back(handle);
|
||||
|
||||
*library = handle;
|
||||
|
||||
return module_name;
|
||||
}
|
||||
|
||||
bool JSShell::RunScript(const std::string& scriptPath) {
|
||||
std::string source = ReadFile(scriptPath);
|
||||
if(!InitializeEngine()) return false;
|
||||
|
||||
// Node.js compatibility: make `print` available as `console.log()`
|
||||
ExecuteScript("var console = {}; console.log = print;", "<console>");
|
||||
|
||||
if(!ExecuteScript(source, scriptPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return DisposeEngine();
|
||||
}
|
||||
|
||||
bool JSShell::RunShell() {
|
||||
|
||||
if(!InitializeEngine()) return false;
|
||||
|
||||
static const int kBufferSize = 1024;
|
||||
while (true) {
|
||||
char buffer[kBufferSize];
|
||||
printf("> ");
|
||||
char* str = fgets(buffer, kBufferSize, stdin);
|
||||
if (str == NULL) break;
|
||||
std::string source(str);
|
||||
ExecuteScript(source, "(shell)");
|
||||
}
|
||||
printf("\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string JSShell::ReadFile(const std::string& fileName)
|
||||
{
|
||||
std::string script;
|
||||
|
||||
std::ifstream file(fileName.c_str());
|
||||
if (file.is_open()) {
|
||||
while ( file.good() ) {
|
||||
std::string line;
|
||||
getline(file, line);
|
||||
script.append(line);
|
||||
script.append("\n");
|
||||
}
|
||||
file.close();
|
||||
} else {
|
||||
std::cout << "Unable to open file " << fileName << "." << std::endl;
|
||||
}
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_JSC
|
||||
extern JSShell* JSCShell_Create();
|
||||
#endif
|
||||
#ifdef ENABLE_V8
|
||||
extern JSShell* V8Shell_Create();
|
||||
#endif
|
||||
|
||||
typedef JSShell*(*ShellFactory)();
|
||||
|
||||
static ShellFactory js_shell_factories[2] = {
|
||||
#ifdef ENABLE_JSC
|
||||
JSCShell_Create,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
#ifdef ENABLE_V8
|
||||
V8Shell_Create,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
};
|
||||
|
||||
JSShell *JSShell::Create(Engine engine) {
|
||||
if(js_shell_factories[engine] == 0) {
|
||||
throw "Engine not available.";
|
||||
}
|
||||
return js_shell_factories[engine]();
|
||||
}
|
||||
48
Tools/javascript/js_shell.h
Normal file
48
Tools/javascript/js_shell.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef JS_SHELL_H
|
||||
#define JS_SHELL_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
typedef void* HANDLE;
|
||||
typedef void* MODULE;
|
||||
|
||||
class JSShell {
|
||||
|
||||
public:
|
||||
enum Engine {
|
||||
JSC = 0,
|
||||
V8
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
JSShell() {}
|
||||
|
||||
virtual ~JSShell() = 0;
|
||||
|
||||
static JSShell* Create(Engine engine = JSC);
|
||||
|
||||
std::string LoadModule(const std::string& name, HANDLE* library);
|
||||
|
||||
virtual bool RunScript(const std::string& scriptPath);
|
||||
|
||||
virtual bool RunShell();
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool InitializeEngine() = 0;
|
||||
|
||||
virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath) = 0;
|
||||
|
||||
virtual bool DisposeEngine() = 0;
|
||||
|
||||
static std::string ReadFile(const std::string& fileName);
|
||||
|
||||
protected:
|
||||
|
||||
std::vector<HANDLE> loaded_modules;
|
||||
|
||||
};
|
||||
|
||||
#endif // JS_SHELL_H
|
||||
229
Tools/javascript/jsc_shell.cxx
Normal file
229
Tools/javascript/jsc_shell.cxx
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
#include <JavaScriptCore/JavaScript.h>
|
||||
|
||||
#include "js_shell.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <dlfcn.h>
|
||||
#define LOAD_SYMBOL(handle, name) dlsym(handle, name)
|
||||
#else
|
||||
#error "implement dll loading"
|
||||
#endif
|
||||
|
||||
class JSCShell: public JSShell {
|
||||
|
||||
typedef int (*JSCIntializer)(JSGlobalContextRef context, JSObjectRef *module);
|
||||
|
||||
public:
|
||||
|
||||
JSCShell() {};
|
||||
|
||||
virtual ~JSCShell();
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool InitializeEngine();
|
||||
|
||||
virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath);
|
||||
|
||||
virtual bool DisposeEngine();
|
||||
|
||||
private:
|
||||
|
||||
JSObjectRef Import(const std::string &moduleName);
|
||||
|
||||
static JSValueRef Print(JSContextRef context, JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex);
|
||||
|
||||
static JSValueRef Require(JSContextRef context, JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex);
|
||||
|
||||
static bool RegisterFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback cbFunction);
|
||||
|
||||
static void PrintError(JSContextRef, JSValueRef);
|
||||
|
||||
private:
|
||||
|
||||
JSGlobalContextRef context;
|
||||
};
|
||||
|
||||
JSCShell::~JSCShell() {
|
||||
if(context != 0) {
|
||||
JSGlobalContextRelease(context);
|
||||
context = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool JSCShell::InitializeEngine() {
|
||||
if(context != 0) {
|
||||
JSGlobalContextRelease(context);
|
||||
context = 0;
|
||||
}
|
||||
// TODO: check for initialization errors
|
||||
context = JSGlobalContextCreate(NULL);
|
||||
if(context == 0) return false;
|
||||
JSObjectRef globalObject = JSContextGetGlobalObject(context);
|
||||
|
||||
|
||||
// store this for later use
|
||||
JSClassDefinition __shell_classdef__;
|
||||
JSClassRef __shell_class__ = JSClassCreate(&__shell_classdef__);
|
||||
JSObjectRef __shell__ = JSObjectMake(context, __shell_class__, 0);
|
||||
bool success = JSObjectSetPrivate(__shell__, (void*) (long) this);
|
||||
JSStringRef shellKey = JSStringCreateWithUTF8CString("__shell__");
|
||||
JSObjectSetProperty(context, globalObject, shellKey, __shell__, kJSPropertyAttributeReadOnly, NULL);
|
||||
JSStringRelease(shellKey);
|
||||
|
||||
JSCShell::RegisterFunction(context, globalObject, "print", JSCShell::Print);
|
||||
JSCShell::RegisterFunction(context, globalObject, "require", JSCShell::Require);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JSCShell::ExecuteScript(const std::string& source, const std::string& scriptPath) {
|
||||
JSStringRef jsScript;
|
||||
JSStringRef sourceURL;
|
||||
JSValueRef ex;
|
||||
jsScript = JSStringCreateWithUTF8CString(source.c_str());
|
||||
sourceURL = JSStringCreateWithUTF8CString(scriptPath.c_str());
|
||||
JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, sourceURL, 0, &ex);
|
||||
JSStringRelease(jsScript);
|
||||
if (jsResult == NULL && ex != NULL) {
|
||||
JSCShell::PrintError(context, ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JSCShell::DisposeEngine() {
|
||||
JSGlobalContextRelease(context);
|
||||
context = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
JSValueRef JSCShell::Print(JSContextRef context, JSObjectRef object,
|
||||
JSObjectRef globalobj, size_t argc,
|
||||
const JSValueRef args[], JSValueRef* ex) {
|
||||
if (argc > 0)
|
||||
{
|
||||
JSStringRef string = JSValueToStringCopy(context, args[0], NULL);
|
||||
size_t numChars = JSStringGetMaximumUTF8CStringSize(string);
|
||||
char *stringUTF8 = new char[numChars];
|
||||
JSStringGetUTF8CString(string, stringUTF8, numChars);
|
||||
printf("%s\n", stringUTF8);
|
||||
|
||||
delete[] stringUTF8;
|
||||
}
|
||||
|
||||
return JSValueMakeUndefined(context);
|
||||
}
|
||||
|
||||
// Attention: this feature should not create too high expectations.
|
||||
// It is only capable of loading things relative to the execution directory
|
||||
// and not relative to the parent script.
|
||||
JSValueRef JSCShell::Require(JSContextRef context, JSObjectRef object,
|
||||
JSObjectRef globalObj, size_t argc,
|
||||
const JSValueRef args[], JSValueRef* ex) {
|
||||
JSObjectRef module;
|
||||
|
||||
JSStringRef shellKey = JSStringCreateWithUTF8CString("__shell__");
|
||||
JSValueRef shellAsVal = JSObjectGetProperty(context, globalObj, shellKey, NULL);
|
||||
JSStringRelease(shellKey);
|
||||
JSObjectRef shell = JSValueToObject(context, shellAsVal, 0);
|
||||
JSCShell *_this = (JSCShell*) (long) JSObjectGetPrivate(shell);
|
||||
|
||||
if (argc > 0)
|
||||
{
|
||||
JSStringRef string = JSValueToStringCopy(context, args[0], NULL);
|
||||
size_t numChars = JSStringGetMaximumUTF8CStringSize(string);
|
||||
char *stringUTF8 = new char[numChars];
|
||||
JSStringGetUTF8CString(string, stringUTF8, numChars);
|
||||
|
||||
std::string modulePath(stringUTF8);
|
||||
module = _this->Import(modulePath);
|
||||
|
||||
delete[] stringUTF8;
|
||||
}
|
||||
|
||||
if (module) {
|
||||
return module;
|
||||
} else {
|
||||
printf("Ooops.\n");
|
||||
return JSValueMakeUndefined(context);
|
||||
}
|
||||
}
|
||||
|
||||
JSObjectRef JSCShell::Import(const std::string& module_path) {
|
||||
|
||||
HANDLE library;
|
||||
std::string module_name = LoadModule(module_path, &library);
|
||||
|
||||
if (library == 0) {
|
||||
printf("Could not load module.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string symname = std::string(module_name).append("_initialize");
|
||||
|
||||
JSCIntializer init_function = reinterpret_cast<JSCIntializer>((long) LOAD_SYMBOL(library, symname.c_str()));
|
||||
if(init_function == 0) {
|
||||
printf("Could not find module's initializer function.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
JSObjectRef module;
|
||||
init_function(context, &module);
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
bool JSCShell::RegisterFunction(JSGlobalContextRef context, JSObjectRef object,
|
||||
const char* functionName, JSObjectCallAsFunctionCallback callback) {
|
||||
JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName);
|
||||
JSObjectSetProperty(context, object, js_functionName,
|
||||
JSObjectMakeFunctionWithCallback(context, js_functionName, callback),
|
||||
kJSPropertyAttributeNone, NULL);
|
||||
JSStringRelease(js_functionName);
|
||||
return true;
|
||||
}
|
||||
|
||||
void JSCShell::PrintError(JSContextRef ctx, JSValueRef err) {
|
||||
char *buffer;
|
||||
size_t length;
|
||||
|
||||
JSStringRef string = JSValueToStringCopy(ctx, err, 0);
|
||||
length = JSStringGetLength(string);
|
||||
buffer = new char[length+1];
|
||||
JSStringGetUTF8CString(string, buffer, length+1);
|
||||
std::string errMsg(buffer);
|
||||
JSStringRelease(string);
|
||||
delete[] buffer;
|
||||
|
||||
JSObjectRef errObj = JSValueToObject(ctx, err, 0);
|
||||
|
||||
if(errObj == 0) {
|
||||
std::cerr << errMsg << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
JSStringRef sourceURLKey = JSStringCreateWithUTF8CString("sourceURL");
|
||||
JSStringRef sourceURLStr = JSValueToStringCopy(ctx, JSObjectGetProperty(ctx, errObj, sourceURLKey, 0), 0);
|
||||
length = JSStringGetLength(sourceURLStr);
|
||||
buffer = new char[length+1];
|
||||
JSStringGetUTF8CString(sourceURLStr, buffer, length+1);
|
||||
std::string sourceURL(buffer);
|
||||
delete[] buffer;
|
||||
JSStringRelease(sourceURLStr);
|
||||
JSStringRelease(sourceURLKey);
|
||||
|
||||
JSStringRef lineKey = JSStringCreateWithUTF8CString("line");
|
||||
JSValueRef jsLine = JSObjectGetProperty(ctx, errObj, lineKey, 0);
|
||||
int line = (int) JSValueToNumber(ctx, jsLine, 0);
|
||||
JSStringRelease(lineKey);
|
||||
|
||||
std::cerr << sourceURL << ":" << line << ":" << errMsg << std::endl;
|
||||
}
|
||||
|
||||
JSShell* JSCShell_Create() {
|
||||
return new JSCShell();
|
||||
}
|
||||
310
Tools/javascript/v8_shell.cxx
Executable file
310
Tools/javascript/v8_shell.cxx
Executable file
|
|
@ -0,0 +1,310 @@
|
|||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <v8.h>
|
||||
#include <vector>
|
||||
|
||||
#include "js_shell.h"
|
||||
|
||||
typedef int (*V8ExtensionInitializer) (v8::Handle<v8::Object> module);
|
||||
|
||||
class V8Shell: public JSShell {
|
||||
|
||||
public:
|
||||
V8Shell();
|
||||
|
||||
virtual ~V8Shell();
|
||||
|
||||
virtual bool RunScript(const std::string& scriptPath);
|
||||
|
||||
virtual bool RunShell();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool InitializeEngine();
|
||||
|
||||
virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath);
|
||||
|
||||
virtual bool DisposeEngine();
|
||||
|
||||
private:
|
||||
|
||||
v8::Handle<v8::Value> Import(const std::string& moduleName);
|
||||
|
||||
v8::Persistent<v8::Context> CreateShellContext();
|
||||
|
||||
void ReportException(v8::TryCatch* handler);
|
||||
|
||||
static v8::Handle<v8::Value> Print(const v8::Arguments& args);
|
||||
|
||||
static v8::Handle<v8::Value> Require(const v8::Arguments& args);
|
||||
|
||||
static v8::Handle<v8::Value> Quit(const v8::Arguments& args);
|
||||
|
||||
static v8::Handle<v8::Value> Version(const v8::Arguments& args);
|
||||
|
||||
static const char* ToCString(const v8::String::Utf8Value& value);
|
||||
|
||||
protected:
|
||||
|
||||
v8::Persistent<v8::Context> context;
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <dlfcn.h>
|
||||
#define LOAD_SYMBOL(handle, name) dlsym(handle, name)
|
||||
#else
|
||||
#error "implement dll loading"
|
||||
#endif
|
||||
|
||||
V8Shell::V8Shell()
|
||||
{
|
||||
}
|
||||
|
||||
V8Shell::~V8Shell() {
|
||||
context.Dispose();
|
||||
v8::V8::Dispose();
|
||||
}
|
||||
|
||||
bool V8Shell::RunScript(const std::string& scriptPath) {
|
||||
|
||||
if (!context.IsEmpty()) {
|
||||
context.Dispose();
|
||||
}
|
||||
|
||||
std::string source = ReadFile(scriptPath);
|
||||
|
||||
context = CreateShellContext();
|
||||
if (context.IsEmpty()) {
|
||||
printf("Could not create context.\n");
|
||||
return false;
|
||||
}
|
||||
context->Enter();
|
||||
//v8::Context::Scope context_scope(context);
|
||||
v8::HandleScope scope;
|
||||
|
||||
// Store a pointer to this shell for later use
|
||||
v8::Handle<v8::Object> global = context->Global();
|
||||
v8::Local<v8::External> __shell__ = v8::External::New((void*) (long) this);
|
||||
global->SetHiddenValue(v8::String::New("__shell__"), __shell__);
|
||||
|
||||
// Node.js compatibility: make `print` available as `console.log()`
|
||||
ExecuteScript("var console = {}; console.log = print;", "<console>");
|
||||
|
||||
if(!ExecuteScript(source, scriptPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
context->Exit();
|
||||
context.Dispose();
|
||||
v8::V8::Dispose();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool V8Shell::RunShell() {
|
||||
|
||||
if (!context.IsEmpty()) {
|
||||
context.Dispose();
|
||||
}
|
||||
|
||||
context = CreateShellContext();
|
||||
if (context.IsEmpty()) {
|
||||
printf("Could not create context.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
context->Enter();
|
||||
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
||||
ExecuteScript("var console = {}; console.log = print;", "<console>");
|
||||
|
||||
static const int kBufferSize = 1024;
|
||||
while (true) {
|
||||
char buffer[kBufferSize];
|
||||
printf("> ");
|
||||
char* str = fgets(buffer, kBufferSize, stdin);
|
||||
if (str == NULL) break;
|
||||
std::string source(str);
|
||||
ExecuteScript(source, "(shell)");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
context->Exit();
|
||||
context.Dispose();
|
||||
v8::V8::Dispose();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool V8Shell::InitializeEngine() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool V8Shell::ExecuteScript(const std::string& source, const std::string& name) {
|
||||
v8::HandleScope handle_scope;
|
||||
v8::TryCatch try_catch;
|
||||
v8::Handle<v8::Script> script = v8::Script::Compile(v8::String::New(source.c_str()), v8::String::New(name.c_str()));
|
||||
|
||||
// Stop if script is empty
|
||||
if (script.IsEmpty()) {
|
||||
// Print errors that happened during compilation.
|
||||
ReportException(&try_catch);
|
||||
return false;
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> result = script->Run();
|
||||
|
||||
// Print errors that happened during execution.
|
||||
if (try_catch.HasCaught()) {
|
||||
ReportException(&try_catch);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool V8Shell::DisposeEngine() {
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Persistent<v8::Context> V8Shell::CreateShellContext() {
|
||||
v8::HandleScope scope;
|
||||
|
||||
// Create a template for the global object.
|
||||
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
|
||||
|
||||
// Bind global functions
|
||||
global->Set(v8::String::New("print"), v8::FunctionTemplate::New(V8Shell::Print));
|
||||
global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(V8Shell::Quit));
|
||||
global->Set(v8::String::New("require"), v8::FunctionTemplate::New(V8Shell::Require));
|
||||
global->Set(v8::String::New("version"), v8::FunctionTemplate::New(V8Shell::Version));
|
||||
|
||||
v8::Persistent<v8::Context> _context = v8::Context::New(NULL, global);
|
||||
|
||||
return _context;
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> V8Shell::Import(const std::string& module_path)
|
||||
{
|
||||
v8::HandleScope scope;
|
||||
|
||||
HANDLE library;
|
||||
std::string module_name = LoadModule(module_path, &library);
|
||||
|
||||
std::string symname = std::string(module_name).append("_initialize");
|
||||
|
||||
V8ExtensionInitializer init_function = reinterpret_cast<V8ExtensionInitializer>((long) LOAD_SYMBOL(library, symname.c_str()));
|
||||
|
||||
if(init_function == 0) {
|
||||
printf("Could not find initializer function.");
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> module = v8::Object::New();
|
||||
init_function(module);
|
||||
return scope.Close(module);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> V8Shell::Print(const v8::Arguments& args) {
|
||||
bool first = true;
|
||||
for (int i = 0; i < args.Length(); i++) {
|
||||
v8::HandleScope handle_scope;
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
v8::String::Utf8Value str(args[i]);
|
||||
const char* cstr = V8Shell::ToCString(str);
|
||||
printf("%s", cstr);
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> V8Shell::Require(const v8::Arguments& args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (args.Length() != 1) {
|
||||
printf("Illegal arguments for `require`");
|
||||
};
|
||||
|
||||
v8::String::Utf8Value str(args[0]);
|
||||
const char* cstr = V8Shell::ToCString(str);
|
||||
std::string moduleName(cstr);
|
||||
|
||||
v8::Local<v8::Object> global = v8::Context::GetCurrent()->Global();
|
||||
v8::Local<v8::Value> hidden = global->GetHiddenValue(v8::String::New("__shell__"));
|
||||
v8::Local<v8::External> __shell__ = v8::Local<v8::External>::Cast(hidden);
|
||||
V8Shell* _this = (V8Shell*) (long) __shell__->Value();
|
||||
|
||||
v8::Handle<v8::Value> module = _this->Import(moduleName);
|
||||
|
||||
return scope.Close(module);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> V8Shell::Quit(const v8::Arguments& args) {
|
||||
int exit_code = args[0]->Int32Value();
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
exit(exit_code);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> V8Shell::Version(const v8::Arguments& args) {
|
||||
return v8::String::New(v8::V8::GetVersion());
|
||||
}
|
||||
|
||||
void V8Shell::ReportException(v8::TryCatch* try_catch) {
|
||||
v8::HandleScope handle_scope;
|
||||
v8::String::Utf8Value exception(try_catch->Exception());
|
||||
const char* exception_string = V8Shell::ToCString(exception);
|
||||
v8::Handle<v8::Message> message = try_catch->Message();
|
||||
if (message.IsEmpty()) {
|
||||
// V8 didn't provide any extra information about this error; just
|
||||
// print the exception.
|
||||
printf("%s\n", exception_string);
|
||||
} else {
|
||||
// Print (filename):(line number): (message).
|
||||
v8::String::Utf8Value filename(message->GetScriptResourceName());
|
||||
const char* filename_string = V8Shell::ToCString(filename);
|
||||
int linenum = message->GetLineNumber();
|
||||
printf("%s:%i: %s\n", filename_string, linenum, exception_string);
|
||||
// Print line of source code.
|
||||
v8::String::Utf8Value sourceline(message->GetSourceLine());
|
||||
const char* sourceline_string = V8Shell::ToCString(sourceline);
|
||||
printf("%s\n", sourceline_string);
|
||||
// Print wavy underline (GetUnderline is deprecated).
|
||||
int start = message->GetStartColumn();
|
||||
for (int i = 0; i < start; i++) {
|
||||
printf(" ");
|
||||
}
|
||||
int end = message->GetEndColumn();
|
||||
for (int i = start; i < end; i++) {
|
||||
printf("^");
|
||||
}
|
||||
printf("\n");
|
||||
v8::String::Utf8Value stack_trace(try_catch->StackTrace());
|
||||
if (stack_trace.length() > 0) {
|
||||
const char* stack_trace_string = V8Shell::ToCString(stack_trace);
|
||||
printf("%s\n", stack_trace_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extracts a C string from a V8 Utf8Value.
|
||||
const char* V8Shell::ToCString(const v8::String::Utf8Value& value) {
|
||||
return *value ? *value : "<string conversion failed>";
|
||||
}
|
||||
|
||||
JSShell* V8Shell_Create() {
|
||||
return new V8Shell();
|
||||
}
|
||||
89
Tools/swigconfig.h.cmake
Normal file
89
Tools/swigconfig.h.cmake
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/* Define to 1 if the system has the type `bool'. */
|
||||
#cmakedefine HAVE_BOOL 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#cmakedefine HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `dl' library (-ldl). */
|
||||
#cmakedefine HAVE_LIBDL 1
|
||||
|
||||
/* Define to 1 if you have the `dld' library (-ldld). */
|
||||
#cmakedefine HAVE_LIBDLD 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#cmakedefine HAVE_MEMORY_H 1
|
||||
|
||||
/* Define if popen is available */
|
||||
#cmakedefine HAVE_POPEN 1
|
||||
|
||||
/* Define if rxspencer is available */
|
||||
#cmakedefine HAVE_RXSPENCER 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#cmakedefine HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#cmakedefine HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#cmakedefine HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#cmakedefine HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#cmakedefine HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#cmakedefine HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
#cmakedefine NO_MINUS_C_MINUS_O 1
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#cmakedefine STDC_HEADERS 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "swig"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "http://www.swig.org"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "swig"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "swig @SWIG_VERSION@"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "swig"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "@SWIG_VERSION@"
|
||||
|
||||
/* Compiler that built SWIG */
|
||||
#define SWIG_CXX "@SWIG_CXX@"
|
||||
|
||||
/* Directory for SWIG system-independent libraries */
|
||||
#define SWIG_LIB "/usr/local/share/swig/2.0.0"
|
||||
|
||||
/* Directory for SWIG system-independent libraries (Unix install on native
|
||||
Windows) */
|
||||
#define SWIG_LIB_WIN_UNIX "C:/cygwin/usr/local/share/swig/2.0.0"
|
||||
|
||||
/* Platform that SWIG is built for */
|
||||
#define SWIG_PLATFORM "i686-pc-cygwin"
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "@SWIG_VERSION@"
|
||||
|
||||
/* Default language */
|
||||
#define SWIG_LANG "-tcl"
|
||||
|
||||
/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
|
||||
#if defined(_MSC_VER)
|
||||
# define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
24
Tools/swigprinters.gdb
Normal file
24
Tools/swigprinters.gdb
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
python
|
||||
import sys
|
||||
import os
|
||||
|
||||
try:
|
||||
global SWIG_PRINTER_DIR
|
||||
sys.path.insert(0, SWIG_PRINTER_DIR)
|
||||
except NameError:
|
||||
raise RuntimeError("""
|
||||
---------------------------------------------------------
|
||||
Change ~/.gdbinit to be able to use swig pretty printers:
|
||||
> set python SWIG_PRINTER_DIR = <path/to/swig>/Tools
|
||||
> source <path/to/swig>/Tools/swigprinters.gdb
|
||||
---------------------------------------------------------
|
||||
""")
|
||||
|
||||
from swigprinters import register_swig_printers, enableGdbPrintWorkaround, \
|
||||
setChildrenRecursionLevel
|
||||
|
||||
#enableGdbPrintWorkaround()
|
||||
#setChildrenRecursionLevel(2)
|
||||
register_swig_printers (None)
|
||||
|
||||
end
|
||||
574
Tools/swigprinters.py
Executable file
574
Tools/swigprinters.py
Executable file
|
|
@ -0,0 +1,574 @@
|
|||
import gdb
|
||||
import gdb.types
|
||||
import itertools
|
||||
import re
|
||||
|
||||
log_file = None
|
||||
GDB_FLATTENED_CHILDREN_WORKAROUND = False
|
||||
CHILDREN_MAX_RECURSION_LEVEL = 0
|
||||
|
||||
# workaround: don't cast the following DOHs to it's actual type
|
||||
# to avoid infinite pretty-print loops
|
||||
cast_black_list = {
|
||||
'Hash': set(['parentNode', 'symtab', 'csymtab', 'sym:symtab', 'inherit', 'nextSibling', 'previousSibling'])
|
||||
}
|
||||
|
||||
def print_(msg):
|
||||
global log_file;
|
||||
|
||||
if True:
|
||||
if log_file == None:
|
||||
log_file = open('swig_gdb.log', 'w')
|
||||
log_file.write(msg)
|
||||
|
||||
print(msg)
|
||||
|
||||
class SwigStringPrinter:
|
||||
"""
|
||||
Pretty print Swig String* types.
|
||||
"""
|
||||
|
||||
def __init__ (self, typename, val):
|
||||
self.typename = typename
|
||||
self.val = val
|
||||
|
||||
try:
|
||||
self.t_swigstr_ptr = gdb.lookup_type("struct String").pointer()
|
||||
self.t_doh_base_ptr = gdb.lookup_type("DohBase").pointer()
|
||||
except Exception as err:
|
||||
print_("SwigStringPrinter: Could not retrieve gdb types.\n %s.\n"%(str(err)))
|
||||
|
||||
def display_hint(self):
|
||||
return 'string'
|
||||
|
||||
def to_string(self):
|
||||
ret = "<invalid>"
|
||||
|
||||
# Conversion taken from Swig Internals manual:
|
||||
# http://peregrine.hpc.uwm.edu/Head-node-docs/swig/2.0.4/Devel/internals.html#7
|
||||
# (*(struct String *)(((DohBase *)s)->data)).str
|
||||
|
||||
dohbase = None;
|
||||
str_data = None;
|
||||
char_ptr = None;
|
||||
|
||||
try:
|
||||
dohbase = self.val.reinterpret_cast(self.t_doh_base_ptr).dereference()
|
||||
except Exception as err:
|
||||
print_("SwigStringPrinter: Could not dereference DOHBase*\n");
|
||||
return "<invalid>";
|
||||
|
||||
try:
|
||||
str_data = dohbase['data'].reinterpret_cast(self.t_swigstr_ptr).dereference()
|
||||
except Exception as err:
|
||||
print_("SwigStringPrinter: Could not dereference struct String*\n");
|
||||
return "<invalid>";
|
||||
|
||||
try:
|
||||
char_ptr = str_data['str']
|
||||
except Exception as err:
|
||||
print_("SwigStringPrinter: Could not access field (struct String).str\n");
|
||||
return "<invalid>";
|
||||
|
||||
if char_ptr.is_lazy is True:
|
||||
char_ptr.fetch_lazy ()
|
||||
|
||||
try:
|
||||
ret = char_ptr.string()
|
||||
except Exception as err:
|
||||
print_("SwigStringPrinter: Could not convert const char* to string\n");
|
||||
return "<invalid>";
|
||||
|
||||
return ret
|
||||
|
||||
class SwigIterator:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.t_doh_base_ptr = gdb.lookup_type("DohBase").pointer()
|
||||
self.t_string_ptr = gdb.lookup_type("String").pointer()
|
||||
self.t_node_ptr = gdb.lookup_type("Node").pointer()
|
||||
self.t_hash_ptr = gdb.lookup_type("Hash").pointer()
|
||||
self.t_file_ptr = gdb.lookup_type("File").pointer()
|
||||
self.t_void_ptr = gdb.lookup_type("void").pointer()
|
||||
|
||||
def cast_doh(self, doh, name = None):
|
||||
|
||||
if doh == 0:
|
||||
return doh
|
||||
|
||||
doh = doh.reinterpret_cast(self.t_doh_base_ptr);
|
||||
|
||||
val_base = doh.dereference()
|
||||
val_type = val_base['type'].dereference()
|
||||
val_typestr = val_type['objname'].string()
|
||||
|
||||
if not name == None and val_typestr in cast_black_list:
|
||||
blacklist = cast_black_list[val_typestr]
|
||||
if name in blacklist:
|
||||
return doh
|
||||
|
||||
if "String" == val_typestr:
|
||||
doh = doh.reinterpret_cast(self.t_string_ptr)
|
||||
elif "File" == val_typestr:
|
||||
doh = doh.reinterpret_cast(self.t_file_ptr)
|
||||
# BUG: GDB Pyhton can not handle cyclic references yet
|
||||
# so these casts are deactivated
|
||||
elif "Hash" == val_typestr:
|
||||
doh = doh.reinterpret_cast(self.t_hash_ptr)
|
||||
elif "Node" == val_typestr:
|
||||
doh = doh.reinterpret_cast(self.t_node_ptr)
|
||||
|
||||
return doh
|
||||
|
||||
class SwigListIterator(SwigIterator):
|
||||
|
||||
def __init__(self, val):
|
||||
SwigIterator.__init__(self);
|
||||
|
||||
try:
|
||||
self.valid = False
|
||||
|
||||
self.val = val.reinterpret_cast(self.t_doh_base_ptr)
|
||||
val_base = self.val.dereference()
|
||||
val_type = val_base['type'].dereference()
|
||||
val_typestr = val_type['objname'].string()
|
||||
#print_("SwigListIterator: constructing iterator for value of type %s"%val_typestr)
|
||||
|
||||
self.t_struct_list_ptr = gdb.lookup_type("struct List").pointer()
|
||||
|
||||
doh_base = self.val.dereference()
|
||||
self.l = doh_base['data'].reinterpret_cast(self.t_struct_list_ptr).dereference()
|
||||
|
||||
self.address = 0
|
||||
self._index = 0
|
||||
self.key = 0
|
||||
self.item = 0
|
||||
|
||||
self.address = self.val.dereference().address
|
||||
|
||||
self.is_first = True
|
||||
self.valid = True
|
||||
|
||||
except Exception as err:
|
||||
print_("SwigListIterator: Construction failed.\n %s.\n"%(str(err)))
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def List_first(self):
|
||||
|
||||
self.object = None;
|
||||
self._index = 0
|
||||
self.key = 0
|
||||
self.nitems = int(self.l['nitems'])
|
||||
self.items = self.l['items']
|
||||
|
||||
if self.nitems > 0:
|
||||
self.item = self.items[0]
|
||||
else:
|
||||
self.stop()
|
||||
|
||||
def List_next(self):
|
||||
self._index = self._index + 1
|
||||
if self._index >= self.nitems:
|
||||
self.stop()
|
||||
else:
|
||||
self.item = self.items[self._index]
|
||||
|
||||
def next(self):
|
||||
|
||||
if not self.valid:
|
||||
self.stop()
|
||||
|
||||
if self.is_first:
|
||||
self.is_first = False
|
||||
try:
|
||||
self.List_first()
|
||||
except StopIteration:
|
||||
raise StopIteration
|
||||
except Exception as err:
|
||||
print_("Error during iteration to first node: \n %s \n" %(str(err)))
|
||||
self.stop()
|
||||
else:
|
||||
try:
|
||||
self.List_next()
|
||||
except StopIteration:
|
||||
raise StopIteration
|
||||
except Exception as err:
|
||||
print_("Error during iteration to first node: \n %s \n" %(str(err)))
|
||||
self.stop()
|
||||
|
||||
key_str = "[%d]"%self._index
|
||||
item = 0
|
||||
|
||||
try:
|
||||
item = self.cast_doh(self.item)
|
||||
except Exception as err:
|
||||
print_("SwigListIterator(%s): Exception during casting of value doh:\n %s\n" % (str(self.address), str(err)) )
|
||||
self.stop()
|
||||
|
||||
return (key_str, item)
|
||||
|
||||
def stop(self):
|
||||
self.is_first = True
|
||||
self.item = 0
|
||||
self.key = 0
|
||||
raise StopIteration
|
||||
|
||||
class SwigHashIterator(SwigIterator):
|
||||
|
||||
def __init__(self, val):
|
||||
SwigIterator.__init__(self);
|
||||
|
||||
try:
|
||||
self.valid = False
|
||||
|
||||
self.val = val.reinterpret_cast(self.t_doh_base_ptr)
|
||||
|
||||
self.t_struct_hash_ptr = gdb.lookup_type("struct Hash").pointer()
|
||||
self.t_struct_hash_node_ptr = gdb.lookup_type("struct HashNode").pointer()
|
||||
|
||||
doh_base = self.val.dereference()
|
||||
hash_ = doh_base['data'].reinterpret_cast(self.t_struct_hash_ptr).dereference()
|
||||
self.hashtable = hash_['hashtable']
|
||||
self.hashsize = int(hash_['hashsize'])
|
||||
self.nitems = int(hash_['nitems'])
|
||||
|
||||
self.next_ = 0
|
||||
self.address = 0
|
||||
self.pos = 0;
|
||||
self._current = 0
|
||||
self.item = 0
|
||||
self.key = 0
|
||||
self._index = 0
|
||||
|
||||
self.address = self.val.dereference().address
|
||||
|
||||
self.is_first = True
|
||||
self.valid = True
|
||||
|
||||
except Exception as err:
|
||||
print_("SwigHashIterator: Construction failed.\n %s.\n"%(str(err)))
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def Hash_firstiter(self):
|
||||
self._current = 0;
|
||||
self.item = 0;
|
||||
self.key = 0;
|
||||
self._index = 0;
|
||||
|
||||
while (self._index < self.hashsize) and (self.hashtable[self._index] == 0):
|
||||
self._index = self._index+1;
|
||||
|
||||
if self._index >= self.hashsize:
|
||||
self.stop();
|
||||
|
||||
self._current = self.hashtable[self._index]
|
||||
self._current = self._current.reinterpret_cast(self.t_struct_hash_node_ptr);
|
||||
self.item = self._current['object'];
|
||||
self.key = self._current['key'];
|
||||
|
||||
self._current = self._current['next'];
|
||||
|
||||
|
||||
def Hash_nextiter(self):
|
||||
if self._current == 0:
|
||||
self._index = self._index + 1
|
||||
while (self._index < self.hashsize) and (self.hashtable[self._index] == 0):
|
||||
self._index = self._index + 1
|
||||
|
||||
if self._index >= self.hashsize:
|
||||
self.item = 0;
|
||||
self.key = 0;
|
||||
self._current = 0;
|
||||
self.stop()
|
||||
|
||||
self._current = self.hashtable[self._index];
|
||||
|
||||
self._current = self._current.reinterpret_cast(self.t_struct_hash_node_ptr);
|
||||
self.key = self._current['key'];
|
||||
self.item = self._current['object'];
|
||||
|
||||
self._current = self._current['next'];
|
||||
|
||||
|
||||
def next(self):
|
||||
|
||||
if not self.valid:
|
||||
self.stop()
|
||||
|
||||
if self.is_first:
|
||||
self.is_first = False
|
||||
try:
|
||||
self.Hash_firstiter()
|
||||
except StopIteration:
|
||||
raise StopIteration
|
||||
except Exception as err:
|
||||
print_("Error during iteration to first node: \n %s \n" %(str(err)))
|
||||
self.stop()
|
||||
else:
|
||||
try:
|
||||
self.Hash_nextiter()
|
||||
except StopIteration:
|
||||
raise StopIteration
|
||||
except Exception as err:
|
||||
print_("Error during iteration to first node: \n %s \n" %(str(err)))
|
||||
self.stop()
|
||||
|
||||
key_str = "<err>"
|
||||
item = 0
|
||||
try:
|
||||
string_printer = SwigStringPrinter("String *", self.key)
|
||||
key_str = string_printer.to_string()
|
||||
except Exception as err:
|
||||
print_("SwigHashIterator(%s): Exception during extracting key string:\n %s\n" % (str(self.address), str(err)) )
|
||||
self.stop()
|
||||
|
||||
try:
|
||||
item = self.cast_doh(self.item, key_str)
|
||||
|
||||
except Exception as err:
|
||||
print_("SwigHashIterator(%s): Exception during casting of value doh:\n %s\n" % (str(self.address), str(err)) )
|
||||
self.stop()
|
||||
|
||||
return (key_str, item)
|
||||
|
||||
def stop(self):
|
||||
self.is_first = True
|
||||
raise StopIteration
|
||||
|
||||
class AlternateKeyValueIterator():
|
||||
|
||||
def __init__(self, iterable):
|
||||
self.it = iterable.__iter__()
|
||||
self._next = None
|
||||
self.count = -1
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
if self._next == None:
|
||||
key, value = self.it.next()
|
||||
self._next = value
|
||||
self.count = self.count + 1
|
||||
return ("[%d]"%self.count, key)
|
||||
else:
|
||||
value = self._next
|
||||
self._next = None
|
||||
return ("[%d]"%self.count, value)
|
||||
|
||||
class NopIterator:
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
raise StopIteration
|
||||
|
||||
class SwigListPrinter:
|
||||
"""
|
||||
Pretty print Swig List* types (also ParmList*).
|
||||
"""
|
||||
|
||||
def __init__ (self, typename, val):
|
||||
|
||||
self.typename = typename
|
||||
self.val = val
|
||||
|
||||
it = SwigListIterator(val)
|
||||
self.valid = it.valid
|
||||
self.address = it.address
|
||||
|
||||
|
||||
def display_hint(self):
|
||||
return 'array'
|
||||
|
||||
def to_string(self):
|
||||
return "%s(%s)" % (str(self.typename), str(self.address))
|
||||
|
||||
def children(self):
|
||||
|
||||
if not self.valid:
|
||||
print_("SwigListPrinter: Invalid state.\n")
|
||||
return NopIterator()
|
||||
|
||||
try:
|
||||
it = SwigListIterator(self.val)
|
||||
return it
|
||||
except Exception as err:
|
||||
print_("SwigListPrinter: Error during creation of children iterator. \n %s \n" %(str(err)))
|
||||
raise err
|
||||
|
||||
class SwigHashPrinter:
|
||||
"""
|
||||
Pretty print Swig Hash* types (also Node*).
|
||||
"""
|
||||
|
||||
def __init__ (self, typename, val):
|
||||
|
||||
self.typename = typename
|
||||
self.val = val
|
||||
it = SwigHashIterator(val)
|
||||
self.valid = it.valid
|
||||
self.address = it.address
|
||||
self.level = 0;
|
||||
|
||||
def display_hint(self):
|
||||
return 'map'
|
||||
|
||||
def to_string(self):
|
||||
return "%s(%s)" % (str(self.typename), str(self.address))
|
||||
|
||||
def children(self):
|
||||
global GDB_FLATTENED_CHILDREN_WORKAROUND
|
||||
global CHILDREN_MAX_RECURSION_LEVEL
|
||||
|
||||
if not self.valid:
|
||||
print_("SwigHashPrinter: Invalid state.\n")
|
||||
return NopIterator()
|
||||
|
||||
if self.level > CHILDREN_MAX_RECURSION_LEVEL:
|
||||
return NopIterator()
|
||||
|
||||
try:
|
||||
it = SwigHashIterator(self.val)
|
||||
if GDB_FLATTENED_CHILDREN_WORKAROUND:
|
||||
return AlternateKeyValueIterator(it)
|
||||
return it
|
||||
except Exception as err:
|
||||
print_("SwigHashPrinter: Error during creation of children iterator. \n %s \n" %(str(err)))
|
||||
raise err
|
||||
|
||||
class SwigSimplePrinter:
|
||||
def __init__ (self, typename, val):
|
||||
self.typename = typename
|
||||
self.val = val
|
||||
|
||||
def display_hint(self):
|
||||
return "string"
|
||||
|
||||
def to_string(self):
|
||||
return "%s(%s)"%(self.typename, str(self.val.address))
|
||||
|
||||
class SwigDelegatingPrinter:
|
||||
|
||||
def __init__ (self, typename, val):
|
||||
t_doh_base_ptr = gdb.lookup_type("DohBase").pointer()
|
||||
val_base = val.reinterpret_cast(t_doh_base_ptr).dereference()
|
||||
val_type = val_base['type'].dereference()
|
||||
val_typestr = val_type['objname'].string()
|
||||
self.has_children = False
|
||||
|
||||
if val_typestr == "Hash":
|
||||
self.delegate = SwigHashPrinter(typename, val)
|
||||
self.has_children = True
|
||||
elif val_typestr == "List":
|
||||
self.delegate = SwigListPrinter(typename, val)
|
||||
self.has_children = True
|
||||
elif val_typestr == "String":
|
||||
self.delegate = SwigStringPrinter(typename, val)
|
||||
else:
|
||||
self.delegate = SwigSimplePrinter(typename, val)
|
||||
|
||||
def display_hint(self):
|
||||
return self.delegate.display_hint()
|
||||
|
||||
def to_string(self):
|
||||
return self.delegate.to_string()
|
||||
|
||||
def children(self):
|
||||
if not self.has_children:
|
||||
return NopIterator()
|
||||
|
||||
return self.delegate.children()
|
||||
|
||||
class RxPrinter(object):
|
||||
def __init__(self, name, function):
|
||||
super(RxPrinter, self).__init__()
|
||||
self.name = name
|
||||
self.function = function
|
||||
self.enabled = True
|
||||
|
||||
def invoke(self, value):
|
||||
if not self.enabled:
|
||||
return None
|
||||
return self.function(self.name, value)
|
||||
|
||||
# A pretty-printer that conforms to the "PrettyPrinter" protocol from
|
||||
# gdb.printing. It can also be used directly as an old-style printer.
|
||||
class Printer(object):
|
||||
def __init__(self, name):
|
||||
super(Printer, self).__init__()
|
||||
self.name = name
|
||||
self.subprinters = []
|
||||
self.lookup = {}
|
||||
self.enabled = True
|
||||
self.compiled_rx = re.compile('^([a-zA-Z0-9_: *]+)$')
|
||||
|
||||
def add(self, name, function):
|
||||
if not self.compiled_rx.match(name):
|
||||
raise ValueError, 'error: "%s" does not match' % name
|
||||
|
||||
printer = RxPrinter(name, function)
|
||||
self.subprinters.append(printer)
|
||||
self.lookup[name] = printer
|
||||
print('Added pretty printer for %s. ' % (name))
|
||||
|
||||
def __call__(self, val):
|
||||
typename = str(val.type)
|
||||
if typename in self.lookup:
|
||||
ret = self.lookup[typename].invoke(val)
|
||||
return ret
|
||||
|
||||
# Cannot find a pretty printer. Return None.
|
||||
return None
|
||||
|
||||
swig_printer = None
|
||||
|
||||
def register_swig_printers(obj):
|
||||
global swig_printer
|
||||
|
||||
if obj is None:
|
||||
obj = gdb
|
||||
|
||||
obj.pretty_printers.append(swig_printer)
|
||||
|
||||
def build_swig_printer():
|
||||
global swig_printer
|
||||
|
||||
swig_printer = Printer("swig")
|
||||
swig_printer.add('String *', SwigStringPrinter)
|
||||
swig_printer.add('const String *', SwigStringPrinter)
|
||||
swig_printer.add('SwigType *', SwigStringPrinter)
|
||||
swig_printer.add('Hash *', SwigHashPrinter)
|
||||
swig_printer.add('const Hash *', SwigHashPrinter)
|
||||
swig_printer.add('Node *', SwigHashPrinter)
|
||||
swig_printer.add('const Node *', SwigHashPrinter)
|
||||
swig_printer.add('Parm *', SwigHashPrinter)
|
||||
swig_printer.add('const Parm *', SwigHashPrinter)
|
||||
swig_printer.add('List *', SwigListPrinter)
|
||||
swig_printer.add('const List *', SwigListPrinter)
|
||||
swig_printer.add('ParmList *', SwigDelegatingPrinter)
|
||||
swig_printer.add('const ParmList *', SwigDelegatingPrinter)
|
||||
swig_printer.add('File *', SwigDelegatingPrinter)
|
||||
#swig_printer.add('DOH *', SwigDelegatingPrinter)
|
||||
#swig_printer.add('const DOH *', SwigDelegatingPrinter)
|
||||
|
||||
print_("Loaded swig printers\n");
|
||||
|
||||
def enableGdbPrintWorkaround():
|
||||
global GDB_FLATTENED_CHILDREN_WORKAROUND
|
||||
GDB_FLATTENED_CHILDREN_WORKAROUND = True
|
||||
|
||||
def setChildrenRecursionLevel(level):
|
||||
global CHILDREN_MAX_RECURSION_LEVEL
|
||||
CHILDREN_MAX_RECURSION_LEVEL = level
|
||||
|
||||
build_swig_printer()
|
||||
Loading…
Add table
Add a link
Reference in a new issue