mirror of https://github.com/swig/swig
423 lines
11 KiB
C++
423 lines
11 KiB
C++
/* -----------------------------------------------------------------------------
|
|
* browser.cxx
|
|
*
|
|
* A web-base parse tree browser using SWILL. This is an optional
|
|
* feature that's normally disabled.
|
|
*
|
|
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
|
*
|
|
* Copyright (C) 2002. The University of Chicago
|
|
* See the file LICENSE for information on usage and redistribution.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
char cvsroot_browser_cxx[] = "$Header$";
|
|
|
|
#include "swigmod.h"
|
|
|
|
#ifdef SWIG_SWILL
|
|
extern "C" {
|
|
#include "swill.h"
|
|
}
|
|
|
|
static FILE *out = 0;
|
|
static Node *view_top = 0;
|
|
|
|
class Browser : public Dispatcher {
|
|
void show_checkbox(Node *t, Node *n) {
|
|
int v = 0;
|
|
if (Getmeta(n,"visible")) {
|
|
v = 1;
|
|
}
|
|
if (v) {
|
|
Printf(out,"<a name=\"n%x\"></a>[<a href=\"hide.html?node=0x%x&hn=0x%x#n%x\">-</a>] ", n, t, n,n);
|
|
} else {
|
|
Printf(out,"<a name=\"n%x\"></a>[<a href=\"show.html?node=0x%x&hn=0x%x#n%x\">+</a>] ", n, t, n,n);
|
|
}
|
|
}
|
|
void show_attributes(Node *obj) {
|
|
if (!Getmeta(obj,"visible")) return;
|
|
String *os = NewString("");
|
|
String *k;
|
|
Iterator ki;
|
|
ki = First(obj);
|
|
while (ki.key) {
|
|
k = ki.key;
|
|
if ((Cmp(k,"nodeType") == 0) || (Cmp(k,"firstChild") == 0) || (Cmp(k,"lastChild") == 0) ||
|
|
(Cmp(k,"parentNode") == 0) || (Cmp(k,"nextSibling") == 0) ||
|
|
(Cmp(k,"previousSibling") == 0) || (*(Char(k)) == '$')) {
|
|
/* Do nothing */
|
|
} else if (Cmp(k,"parms") == 0) {
|
|
String *o = NewString("");
|
|
Printf(o,"%s", ParmList_protostr(Getattr(obj,k)));
|
|
Replaceall(o,"&","&");
|
|
Replaceall(o,"<","<");
|
|
Replaceall(o,">",">");
|
|
Printf(os,"<a href=\"data.html?n=0x%x\">?</a> %-12s - %s\n", Getattr(obj,k), k, o);
|
|
Delete(o);
|
|
} else {
|
|
DOH *o;
|
|
char *trunc = "";
|
|
if (DohIsString(Getattr(obj,k))) {
|
|
o = Str(Getattr(obj,k));
|
|
if (Len(o) > 70) {
|
|
trunc = "...";
|
|
}
|
|
Replaceall(o,"&","&");
|
|
Replaceall(o,"<","<");
|
|
Printf(os,"<a href=\"data.html?n=0x%x\">?</a> %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj,k), k, o, trunc);
|
|
Delete(o);
|
|
} else {
|
|
Printf(os,"<a href=\"data.html?n=0x%x\">?</a> %-12s - 0x%x\n", Getattr(obj,k), k, Getattr(obj,k));
|
|
}
|
|
}
|
|
ki = Next(ki);
|
|
}
|
|
Printf(out,"<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os));
|
|
Delete(os);
|
|
}
|
|
|
|
public:
|
|
virtual int emit_one(Node *n) {
|
|
char *tag = Char(nodeType(n));
|
|
char *file = Char(Getfile(n));
|
|
int line = Getline(n);
|
|
char *name = GetChar(n,"name");
|
|
|
|
show_checkbox(view_top, n);
|
|
Printf(out,"<b><a href=\"index.html?node=0x%x\">%s</a></b>", n, tag);
|
|
if (name) {
|
|
Printf(out," (%s)", name);
|
|
}
|
|
Printf(out,". %s:%d\n", file, line);
|
|
Printf(out,"<br>");
|
|
Dispatcher::emit_one(n);
|
|
return SWIG_OK;
|
|
}
|
|
virtual int emit_children(Node *n) {
|
|
if (Getmeta(n,"visible")) {
|
|
Printf(out,"<blockquote>\n");
|
|
Dispatcher::emit_children(n);
|
|
Printf(out,"</blockquote>\n");
|
|
}
|
|
return SWIG_OK;
|
|
}
|
|
virtual int defaultHandler(Node *n) {
|
|
show_attributes(n);
|
|
return SWIG_OK;
|
|
}
|
|
virtual int top(Node *n) {
|
|
show_attributes(n);
|
|
emit_children(n);
|
|
return SWIG_OK;
|
|
}
|
|
virtual int includeDirective(Node *n) {
|
|
show_attributes(n);
|
|
emit_children(n);
|
|
return SWIG_OK;
|
|
}
|
|
virtual int importDirective(Node *n) {
|
|
show_attributes(n);
|
|
emit_children(n);
|
|
return SWIG_OK;
|
|
}
|
|
|
|
virtual int extendDirective(Node *n) {
|
|
show_attributes(n);
|
|
emit_children(n);
|
|
return SWIG_OK;
|
|
}
|
|
virtual int classDeclaration(Node *n) {
|
|
show_attributes(n);
|
|
emit_children(n);
|
|
return SWIG_OK;
|
|
}
|
|
|
|
virtual int templateDeclaration(Node *n) {
|
|
show_attributes(n);
|
|
emit_children(n);
|
|
return SWIG_OK;
|
|
}
|
|
|
|
virtual int enumDeclaration(Node *n) {
|
|
show_attributes(n);
|
|
emit_children(n);
|
|
return SWIG_OK;
|
|
}
|
|
virtual int typemapDirective(Node *n) {
|
|
show_attributes(n);
|
|
emit_children(n);
|
|
return SWIG_OK;
|
|
}
|
|
virtual int namespaceDeclaration(Node *n) {
|
|
show_attributes(n);
|
|
emit_children(n);
|
|
return SWIG_OK;
|
|
}
|
|
virtual int usingDeclaration(Node *n) {
|
|
show_attributes(n);
|
|
emit_children(n);
|
|
return SWIG_OK;
|
|
}
|
|
|
|
};
|
|
|
|
static int browser_exit = 0;
|
|
static Node *tree_top = 0;
|
|
static Browser *browse = 0;
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* exit_handler() - Force the browser to exit
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
void exit_handler(FILE *f) {
|
|
browser_exit = 1;
|
|
Printf(f,"Terminated.\n");
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* node_handler() - Generate information about a specific node
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
static void display(FILE *f, Node *n) {
|
|
/* Print standard HTML header */
|
|
|
|
Printf(f,"<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", PACKAGE_VERSION);
|
|
Printf(f,"<b>SWIG-%s</b><br>\n", PACKAGE_VERSION);
|
|
Printf(f,"[ <a href=\"exit.html\">Exit</a> ]");
|
|
Printf(f," [ <a href=\"index.html?node=0x%x\">Top</a> ]", tree_top);
|
|
if (n != tree_top) {
|
|
Printf(f," [ <a href=\"index.html?node=0x%x\">Up</a> ]", parentNode(n));
|
|
}
|
|
Printf(f," [ <a href=\"symbol.html\">Symbols</a> ]");
|
|
Printf(f,"<br><hr><p>\n");
|
|
|
|
out = f;
|
|
|
|
browse->emit_one(n);
|
|
|
|
/* Print standard footer */
|
|
Printf(f,"<br><hr></BODY></HTML>\n");
|
|
|
|
}
|
|
|
|
void node_handler(FILE *f) {
|
|
Node *n = 0;
|
|
if (!swill_getargs("p(node)", &n)) {
|
|
n = tree_top;
|
|
}
|
|
view_top = n;
|
|
display(f,n);
|
|
}
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* hide_handler() - Hide a node
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
void hide_handler(FILE *f) {
|
|
Node *n = 0;
|
|
if (!swill_getargs("p(hn)", &n)) {
|
|
n = 0;
|
|
}
|
|
if (n) {
|
|
Delmeta(n,"visible");
|
|
}
|
|
node_handler(f);
|
|
}
|
|
|
|
void show_handler(FILE *f) {
|
|
Node *n = 0;
|
|
if (!swill_getargs("p(hn)", &n)) {
|
|
n = 0;
|
|
}
|
|
if (n) {
|
|
Setmeta(n,"visible","1");
|
|
}
|
|
node_handler(f);
|
|
}
|
|
|
|
void raw_data(FILE *out, Node *obj) {
|
|
if (!obj) return;
|
|
if (DohIsMapping(obj)) {
|
|
String *k;
|
|
Iterator ki;
|
|
String *os = NewString("");
|
|
Printf(os,"Hash {\n");
|
|
ki = First(obj);
|
|
while (ki.key) {
|
|
k = ki.key;
|
|
DOH *o;
|
|
const char *trunc = "";
|
|
if (DohIsString(Getattr(obj,k))) {
|
|
o = Str(Getattr(obj,k));
|
|
if (Len(o) > 70) {
|
|
trunc = "...";
|
|
}
|
|
Replaceall(o,"<","<");
|
|
Printf(os," <a href=\"data.html?n=0x%x\">?</a> %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj,k), k, o, trunc);
|
|
Delete(o);
|
|
} else {
|
|
Printf(os," <a href=\"data.html?n=0x%x\">?</a> %-12s - 0x%x\n", Getattr(obj,k), k, Getattr(obj,k));
|
|
}
|
|
ki = Next(ki);
|
|
}
|
|
Printf(os,"}\n");
|
|
Printf(out,"<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os));
|
|
Delete(os);
|
|
} else if (DohIsString(obj)) {
|
|
String *o = Str(obj);
|
|
Replaceall(o,"<","<");
|
|
Printf(out,"<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(o));
|
|
Delete(o);
|
|
} else if (DohIsSequence(obj)) {
|
|
int i;
|
|
String *os = NewString("");
|
|
Printf(os,"List [\n");
|
|
for (i = 0; i < Len(obj); i++) {
|
|
DOH *o = Getitem(obj,i);
|
|
const char *trunc = "";
|
|
if (DohIsString(o)) {
|
|
String *s = Str(o);
|
|
if (Len(s) > 70) {
|
|
trunc = "...";
|
|
}
|
|
Replaceall(o,"<","<");
|
|
Printf(os," <a href=\"data.html?n=0x%x\">?</a> [%d] - \"%(escape)-0.70s%s\"\n", o,i,s, trunc);
|
|
Delete(s);
|
|
} else {
|
|
Printf(os," <a href=\"data.html?n=0x%x\">?</a> [%d] - 0x%x\n", o, i, o);
|
|
}
|
|
}
|
|
Printf(os,"\n]\n");
|
|
Printf(out,"<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os));
|
|
Delete(os);
|
|
}
|
|
}
|
|
|
|
void data_handler(FILE *f) {
|
|
DOH *n = 0;
|
|
if (!swill_getargs("p(n)", &n)) {
|
|
n = 0;
|
|
}
|
|
Printf(f,"<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", PACKAGE_VERSION);
|
|
Printf(f,"<b>SWIG-%s</b><br>\n", PACKAGE_VERSION);
|
|
Printf(f,"[ <a href=\"exit.html\">Exit</a> ]");
|
|
Printf(f," [ <a href=\"index.html?node=0x%x\">Top</a> ]", tree_top);
|
|
Printf(f,"<br><hr><p>\n");
|
|
if (n) {
|
|
raw_data(f,n);
|
|
}
|
|
/* Print standard footer */
|
|
Printf(f,"<br><hr></BODY></HTML>\n");
|
|
}
|
|
|
|
void symbol_handler(FILE *f) {
|
|
Symtab *sym;
|
|
char *name = 0;
|
|
|
|
Printf(f,"<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", PACKAGE_VERSION);
|
|
Printf(f,"<b>SWIG-%s</b><br>\n", PACKAGE_VERSION);
|
|
Printf(f,"[ <a href=\"exit.html\">Exit</a> ]");
|
|
Printf(f," [ <a href=\"index.html?node=0x%x\">Top</a> ]", tree_top);
|
|
Printf(f," [ <a href=\"symbol.html\">Symbols</a> ]");
|
|
Printf(f,"<br><hr><p>\n");
|
|
|
|
if (!swill_getargs("p(sym)|s(name)", &sym, &name)) {
|
|
sym = Swig_symbol_getscope("");
|
|
name = 0;
|
|
}
|
|
if (!sym) {
|
|
Printf(f,"No symbol table specified!\n");
|
|
return;
|
|
}
|
|
{
|
|
String *q = Swig_symbol_qualifiedscopename(sym);
|
|
if (!Len(q)) {
|
|
Printf(f,"<b>Symbol table: :: (global)</b><br>\n");
|
|
} else {
|
|
Printf(f,"<b>Symbol table: %s</b><br>\n", q);
|
|
}
|
|
Delete(q);
|
|
}
|
|
|
|
fprintf(f,"<p><form action=\"symbol.html\" method=GET>\n");
|
|
fprintf(f,"Symbol lookup: <input type=text name=name size=40></input><br>\n");
|
|
fprintf(f,"<input type=hidden name=sym value=\"0x%x\">\n", sym);
|
|
fprintf(f,"Submit : <input type=submit></input>\n");
|
|
fprintf(f,"</form>");
|
|
|
|
if (name) {
|
|
Node *n = Swig_symbol_clookup(name,sym);
|
|
Printf(f,"Symbol '%s':\n", name);
|
|
Printf(f,"<blockquote>\n");
|
|
if (!n) {
|
|
Printf(f,"Not defined!\n");
|
|
} else {
|
|
raw_data(f,n);
|
|
}
|
|
Printf(f,"</blockquote>\n");
|
|
}
|
|
|
|
Printf(f,"<p><b>Nested scopes</b><br>\n");
|
|
Printf(f,"<blockquote><pre>\n");
|
|
{
|
|
Hash *h;
|
|
h = firstChild(sym);
|
|
while (h) {
|
|
Printf(f,"<a href=\"symbol.html?sym=0x%x\">%s</a>\n", h, Getattr(h,"name"));
|
|
h = nextSibling(h);
|
|
}
|
|
}
|
|
Printf(f,"</pre></blockquote>\n");
|
|
|
|
Printf(f,"<p><b>Symbol table contents</b></br>\n");
|
|
raw_data(f,Getattr(sym,"symtab"));
|
|
Printf(f,"<br><hr></BODY></HTML>\n");
|
|
|
|
}
|
|
#endif
|
|
|
|
void
|
|
Swig_browser(Node *top, int port) {
|
|
#ifdef SWIG_SWILL
|
|
int sport;
|
|
browser_exit = 0;
|
|
|
|
/* Initialize the server */
|
|
sport = swill_init(port);
|
|
if (sport < 0) {
|
|
Printf(stderr,"Couldn't open socket on port %d. Sorry.\n", port);
|
|
return;
|
|
}
|
|
browse = new Browser();
|
|
Setmeta(top,"visible","1");
|
|
tree_top = top;
|
|
|
|
Printf(stderr,"SWIG: Tree browser listening on port %d\n", sport);
|
|
|
|
swill_handle("exit.html", exit_handler,0);
|
|
swill_handle("index.html", node_handler, 0);
|
|
swill_handle("hide.html", hide_handler,0);
|
|
swill_handle("show.html", show_handler,0);
|
|
swill_handle("data.html", data_handler,0);
|
|
swill_handle("symbol.html", symbol_handler, 0);
|
|
swill_netscape("index.html");
|
|
|
|
while (!browser_exit) {
|
|
swill_serve();
|
|
}
|
|
Printf(stderr,"Browser terminated.\n");
|
|
swill_close();
|
|
delete browse;
|
|
return;
|
|
#else
|
|
(void)top;
|
|
(void)port;
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
|