Merge branch 'devel' of https://github.com/Neha03/gsoc2012-javascript into devel
Conflicts: .project COPYRIGHT Doc/Manual/style.css Examples/Makefile.in Examples/test-suite/common.mk Lib/typemaps/strings.swg Makefile.in Source/DOH/fio.c Source/Makefile.am Source/Modules/emit.cxx Source/Modules/javascript.cxx configure.in git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13764 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
360ef44e09
commit
050219d998
136 changed files with 7987 additions and 141 deletions
217
Tools/javascript/javascript.cxx
Normal file
217
Tools/javascript/javascript.cxx
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <JavaScriptCore/JavaScript.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static JSValueRef jsc_printstring(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex);
|
||||
static char* jsccreateStringWithContentsOfFile(const char* fileName);
|
||||
bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, const char* FunctionName,JSObjectCallAsFunctionCallback cbFunction);
|
||||
|
||||
typedef void* HANDLE;
|
||||
typedef int (*JSCIntializer)(JSGlobalContextRef context);
|
||||
|
||||
void jsc_printError(JSContextRef, JSValueRef, const std::string&);
|
||||
|
||||
void print_usage() {
|
||||
std::cout << "javascript [-l module] <js-file>" << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
std::string scriptPath;
|
||||
|
||||
std::vector<std::string> module_names;
|
||||
|
||||
std::vector<HANDLE> loaded_modules;
|
||||
std::vector<JSCIntializer> module_initializers;
|
||||
|
||||
for (int idx = 1; idx < argc; ++idx) {
|
||||
if(strcmp(argv[idx], "-l") == 0) {
|
||||
idx++;
|
||||
if(idx > argc) {
|
||||
print_usage();
|
||||
exit(-1);
|
||||
}
|
||||
std::string module_name(argv[idx]);
|
||||
module_names.push_back(module_name);
|
||||
} else {
|
||||
scriptPath = argv[idx];
|
||||
}
|
||||
}
|
||||
|
||||
for(std::vector<std::string>::iterator it = module_names.begin();
|
||||
it != module_names.end(); ++it) {
|
||||
std::string module_name = *it;
|
||||
std::string lib_name = std::string("lib").append(module_name).append(".so");
|
||||
|
||||
HANDLE handle = dlopen(lib_name.c_str(), RTLD_LAZY);
|
||||
if(handle == 0) {
|
||||
std::cout << "Could not load library " << lib_name << ":"
|
||||
<< std::endl << dlerror() << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string symname;
|
||||
symname.append(module_name).append("_initialize");
|
||||
|
||||
JSCIntializer init_function = reinterpret_cast<JSCIntializer>((long) dlsym(handle, symname.c_str()));
|
||||
if(init_function == 0) {
|
||||
std::cout << "Could not find initializer function in module " << module_name << std::endl;
|
||||
dlclose(handle);
|
||||
continue;
|
||||
}
|
||||
|
||||
loaded_modules.push_back(handle);
|
||||
module_initializers.push_back(init_function);
|
||||
}
|
||||
|
||||
static int failed;
|
||||
|
||||
JSGlobalContextRef context = JSGlobalContextCreate(NULL);
|
||||
JSObjectRef globalObject = JSContextGetGlobalObject(context);
|
||||
|
||||
jsc_registerFunction(context, globalObject, "print", jsc_printstring); // Utility print function
|
||||
|
||||
// Call module initializers
|
||||
for(std::vector<JSCIntializer>::iterator it = module_initializers.begin();
|
||||
it != module_initializers.end(); ++it) {
|
||||
JSCIntializer init_function = *it;
|
||||
init_function(context);
|
||||
}
|
||||
|
||||
// Evaluate the javascript
|
||||
char* scriptContent = jsccreateStringWithContentsOfFile(scriptPath.c_str());
|
||||
JSStringRef jsScript;
|
||||
|
||||
if(!scriptContent) {
|
||||
printf("FAIL: runme script could not be loaded.\n");
|
||||
failed = 1;
|
||||
}
|
||||
else {
|
||||
JSValueRef ex;
|
||||
jsScript = JSStringCreateWithUTF8CString(scriptContent);
|
||||
JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex);
|
||||
|
||||
if (!jsResult && ex) {
|
||||
jsc_printError(context, ex, scriptPath);
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (scriptContent != NULL) {
|
||||
free(scriptContent);
|
||||
}
|
||||
|
||||
JSStringRelease(jsScript);
|
||||
|
||||
JSGlobalContextRelease(context);
|
||||
globalObject = 0;
|
||||
|
||||
for(std::vector<HANDLE>::iterator it = loaded_modules.begin();
|
||||
it != loaded_modules.end(); ++it) {
|
||||
HANDLE handle = *it;
|
||||
dlclose(handle);
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
printf("FAIL: Some tests failed.\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static JSValueRef jsc_printstring(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);
|
||||
}
|
||||
|
||||
static char* jsccreateStringWithContentsOfFile(const char* fileName)
|
||||
{
|
||||
char* buffer;
|
||||
|
||||
size_t buffer_size = 0;
|
||||
size_t buffer_capacity = 1024;
|
||||
buffer = (char*)malloc(buffer_capacity);
|
||||
|
||||
FILE* f = fopen(fileName, "r");
|
||||
if (!f)
|
||||
{
|
||||
fprintf(stderr, "Could not open file: %s\n", fileName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (!feof(f) && !ferror(f))
|
||||
{
|
||||
buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - buffer_size, f);
|
||||
if (buffer_size == buffer_capacity)
|
||||
{
|
||||
// guarantees space for trailing '\0'
|
||||
buffer_capacity *= 2;
|
||||
buffer = (char*)realloc(buffer, buffer_capacity);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
buffer[buffer_size] = '\0';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool jsc_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 jsc_printError(JSContextRef ctx, JSValueRef err, const std::string& sourceUrl)
|
||||
{
|
||||
char *buffer;
|
||||
|
||||
JSStringRef string = JSValueToStringCopy(ctx, err, 0);
|
||||
size_t length = JSStringGetLength(string);
|
||||
|
||||
buffer = (char*) malloc(length+1);
|
||||
JSStringGetUTF8CString(string, buffer, length+1);
|
||||
std::string errMsg(buffer);
|
||||
JSStringRelease(string);
|
||||
free(buffer);
|
||||
|
||||
JSObjectRef errObj = JSValueToObject(ctx, err, 0);
|
||||
|
||||
if(errObj == 0) {
|
||||
return;
|
||||
}
|
||||
// Note: usually you would also retrieve the property "sourceURL"
|
||||
// though, it happened that this was always ""
|
||||
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;
|
||||
|
||||
}
|
||||
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