1/* ----------------------------------------------------------------------------- 2 * See the LICENSE file for information on copyright, usage and redistribution 3 * of SWIG, and the README file for authors - http://www.swig.org/release.html. 4 * 5 * browser.cxx 6 * 7 * A web-base parse tree browser using SWILL. This is an optional 8 * feature that's normally disabled. 9 * ----------------------------------------------------------------------------- */ 10 11char cvsroot_browser_cxx[] = "$Id: browser.cxx 10003 2007-10-17 21:42:11Z wsfulton $"; 12 13#include "swigmod.h" 14 15#ifdef SWIG_SWILL 16extern "C" { 17#include "swill.h" 18} static FILE *out = 0; 19static Node *view_top = 0; 20 21class Browser:public Dispatcher { 22 void show_checkbox(Node *t, Node *n) { 23 int v = 0; 24 if (Getmeta(n, "visible")) { 25 v = 1; 26 } 27 if (v) { 28 Printf(out, "<a name=\"n%x\"></a>[<a href=\"hide.html?node=0x%x&hn=0x%x#n%x\">-</a>] ", n, t, n, n); 29 } else { 30 Printf(out, "<a name=\"n%x\"></a>[<a href=\"show.html?node=0x%x&hn=0x%x#n%x\">+</a>] ", n, t, n, n); 31 } 32 } 33 void show_attributes(Node *obj) { 34 if (!Getmeta(obj, "visible")) 35 return; 36 String *os = NewString(""); 37 String *k; 38 Iterator ki; 39 ki = First(obj); 40 while (ki.key) { 41 k = ki.key; 42 if ((Cmp(k, "nodeType") == 0) || (Cmp(k, "firstChild") == 0) || (Cmp(k, "lastChild") == 0) || 43 (Cmp(k, "parentNode") == 0) || (Cmp(k, "nextSibling") == 0) || (Cmp(k, "previousSibling") == 0) || (*(Char(k)) == '$')) { 44 /* Do nothing */ 45 } else if (Cmp(k, "parms") == 0) { 46 String *o = NewString(""); 47 Printf(o, "%s", ParmList_protostr(Getattr(obj, k))); 48 Replaceall(o, "&", "&"); 49 Replaceall(o, "<", "<"); 50 Replaceall(o, ">", ">"); 51 Printf(os, "<a href=\"data.html?n=0x%x\">?</a> %-12s - %s\n", Getattr(obj, k), k, o); 52 Delete(o); 53 } else { 54 DOH *o; 55 char *trunc = ""; 56 if (DohIsString(Getattr(obj, k))) { 57 o = Str(Getattr(obj, k)); 58 if (Len(o) > 70) { 59 trunc = "..."; 60 } 61 Replaceall(o, "&", "&"); 62 Replaceall(o, "<", "<"); 63 Printf(os, "<a href=\"data.html?n=0x%x\">?</a> %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj, k), k, o, trunc); 64 Delete(o); 65 } else { 66 Printf(os, "<a href=\"data.html?n=0x%x\">?</a> %-12s - 0x%x\n", Getattr(obj, k), k, Getattr(obj, k)); 67 } 68 } 69 ki = Next(ki); 70 } 71 Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os)); 72 Delete(os); 73 } 74 75public: 76 virtual int emit_one(Node *n) { 77 char *tag = Char(nodeType(n)); 78 char *file = Char(Getfile(n)); 79 int line = Getline(n); 80 char *name = GetChar(n, "name"); 81 82 show_checkbox(view_top, n); 83 Printf(out, "<b><a href=\"index.html?node=0x%x\">%s</a></b>", n, tag); 84 if (name) { 85 Printf(out, " (%s)", name); 86 } 87 Printf(out, ". %s:%d\n", file, line); 88 Printf(out, "<br>"); 89 Dispatcher::emit_one(n); 90 return SWIG_OK; 91 } 92 virtual int emit_children(Node *n) { 93 if (Getmeta(n, "visible")) { 94 Printf(out, "<blockquote>\n"); 95 Dispatcher::emit_children(n); 96 Printf(out, "</blockquote>\n"); 97 } 98 return SWIG_OK; 99 } 100 virtual int defaultHandler(Node *n) { 101 show_attributes(n); 102 return SWIG_OK; 103 } 104 virtual int top(Node *n) { 105 show_attributes(n); 106 emit_children(n); 107 return SWIG_OK; 108 } 109 virtual int includeDirective(Node *n) { 110 show_attributes(n); 111 emit_children(n); 112 return SWIG_OK; 113 } 114 virtual int importDirective(Node *n) { 115 show_attributes(n); 116 emit_children(n); 117 return SWIG_OK; 118 } 119 120 virtual int extendDirective(Node *n) { 121 show_attributes(n); 122 emit_children(n); 123 return SWIG_OK; 124 } 125 virtual int classDeclaration(Node *n) { 126 show_attributes(n); 127 emit_children(n); 128 return SWIG_OK; 129 } 130 131 virtual int templateDeclaration(Node *n) { 132 show_attributes(n); 133 emit_children(n); 134 return SWIG_OK; 135 } 136 137 virtual int enumDeclaration(Node *n) { 138 show_attributes(n); 139 emit_children(n); 140 return SWIG_OK; 141 } 142 virtual int typemapDirective(Node *n) { 143 show_attributes(n); 144 emit_children(n); 145 return SWIG_OK; 146 } 147 virtual int namespaceDeclaration(Node *n) { 148 show_attributes(n); 149 emit_children(n); 150 return SWIG_OK; 151 } 152 virtual int usingDeclaration(Node *n) { 153 show_attributes(n); 154 emit_children(n); 155 return SWIG_OK; 156 } 157 158}; 159 160static int browser_exit = 0; 161static Node *tree_top = 0; 162static Browser *browse = 0; 163 164/* ---------------------------------------------------------------------- 165 * exit_handler() - Force the browser to exit 166 * ---------------------------------------------------------------------- */ 167 168void exit_handler(FILE *f) { 169 browser_exit = 1; 170 Printf(f, "Terminated.\n"); 171} 172 173/* ---------------------------------------------------------------------- 174 * node_handler() - Generate information about a specific node 175 * ---------------------------------------------------------------------- */ 176 177static void display(FILE *f, Node *n) { 178 /* Print standard HTML header */ 179 180 Printf(f, "<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", Swig_package_version()); 181 Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_version()); 182 Printf(f, "[ <a href=\"exit.html\">Exit</a> ]"); 183 Printf(f, " [ <a href=\"index.html?node=0x%x\">Top</a> ]", tree_top); 184 if (n != tree_top) { 185 Printf(f, " [ <a href=\"index.html?node=0x%x\">Up</a> ]", parentNode(n)); 186 } 187 Printf(f, " [ <a href=\"symbol.html\">Symbols</a> ]"); 188 Printf(f, "<br><hr><p>\n"); 189 190 out = f; 191 192 browse->emit_one(n); 193 194 /* Print standard footer */ 195 Printf(f, "<br><hr></BODY></HTML>\n"); 196 197} 198 199void node_handler(FILE *f) { 200 Node *n = 0; 201 if (!swill_getargs("p(node)", &n)) { 202 n = tree_top; 203 } 204 view_top = n; 205 display(f, n); 206} 207 208 209/* ---------------------------------------------------------------------- 210 * hide_handler() - Hide a node 211 * ---------------------------------------------------------------------- */ 212 213void hide_handler(FILE *f) { 214 Node *n = 0; 215 if (!swill_getargs("p(hn)", &n)) { 216 n = 0; 217 } 218 if (n) { 219 Delmeta(n, "visible"); 220 } 221 node_handler(f); 222} 223 224void show_handler(FILE *f) { 225 Node *n = 0; 226 if (!swill_getargs("p(hn)", &n)) { 227 n = 0; 228 } 229 if (n) { 230 Setmeta(n, "visible", "1"); 231 } 232 node_handler(f); 233} 234 235void raw_data(FILE *out, Node *obj) { 236 if (!obj) 237 return; 238 if (DohIsMapping(obj)) { 239 String *k; 240 Iterator ki; 241 String *os = NewString(""); 242 Printf(os, "Hash {\n"); 243 ki = First(obj); 244 while (ki.key) { 245 k = ki.key; 246 DOH *o; 247 const char *trunc = ""; 248 if (DohIsString(Getattr(obj, k))) { 249 o = Str(Getattr(obj, k)); 250 if (Len(o) > 70) { 251 trunc = "..."; 252 } 253 Replaceall(o, "<", "<"); 254 Printf(os, " <a href=\"data.html?n=0x%x\">?</a> %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj, k), k, o, trunc); 255 Delete(o); 256 } else { 257 Printf(os, " <a href=\"data.html?n=0x%x\">?</a> %-12s - 0x%x\n", Getattr(obj, k), k, Getattr(obj, k)); 258 } 259 ki = Next(ki); 260 } 261 Printf(os, "}\n"); 262 Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os)); 263 Delete(os); 264 } else if (DohIsString(obj)) { 265 String *o = Str(obj); 266 Replaceall(o, "<", "<"); 267 Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(o)); 268 Delete(o); 269 } else if (DohIsSequence(obj)) { 270 int i; 271 String *os = NewString(""); 272 Printf(os, "List [\n"); 273 for (i = 0; i < Len(obj); i++) { 274 DOH *o = Getitem(obj, i); 275 const char *trunc = ""; 276 if (DohIsString(o)) { 277 String *s = Str(o); 278 if (Len(s) > 70) { 279 trunc = "..."; 280 } 281 Replaceall(o, "<", "<"); 282 Printf(os, " <a href=\"data.html?n=0x%x\">?</a> [%d] - \"%(escape)-0.70s%s\"\n", o, i, s, trunc); 283 Delete(s); 284 } else { 285 Printf(os, " <a href=\"data.html?n=0x%x\">?</a> [%d] - 0x%x\n", o, i, o); 286 } 287 } 288 Printf(os, "\n]\n"); 289 Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os)); 290 Delete(os); 291 } 292} 293 294void data_handler(FILE *f) { 295 DOH *n = 0; 296 if (!swill_getargs("p(n)", &n)) { 297 n = 0; 298 } 299 Printf(f, "<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", Swig_package_version()); 300 Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_version()); 301 Printf(f, "[ <a href=\"exit.html\">Exit</a> ]"); 302 Printf(f, " [ <a href=\"index.html?node=0x%x\">Top</a> ]", tree_top); 303 Printf(f, "<br><hr><p>\n"); 304 if (n) { 305 raw_data(f, n); 306 } 307 /* Print standard footer */ 308 Printf(f, "<br><hr></BODY></HTML>\n"); 309} 310 311void symbol_handler(FILE *f) { 312 Symtab *sym; 313 char *name = 0; 314 315 Printf(f, "<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", Swig_package_version()); 316 Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_version()); 317 Printf(f, "[ <a href=\"exit.html\">Exit</a> ]"); 318 Printf(f, " [ <a href=\"index.html?node=0x%x\">Top</a> ]", tree_top); 319 Printf(f, " [ <a href=\"symbol.html\">Symbols</a> ]"); 320 Printf(f, "<br><hr><p>\n"); 321 322 if (!swill_getargs("p(sym)|s(name)", &sym, &name)) { 323 sym = Swig_symbol_getscope(""); 324 name = 0; 325 } 326 if (!sym) { 327 Printf(f, "No symbol table specified!\n"); 328 return; 329 } 330 { 331 String *q = Swig_symbol_qualifiedscopename(sym); 332 if (!Len(q)) { 333 Printf(f, "<b>Symbol table: :: (global)</b><br>\n"); 334 } else { 335 Printf(f, "<b>Symbol table: %s</b><br>\n", q); 336 } 337 Delete(q); 338 } 339 340 fprintf(f, "<p><form action=\"symbol.html\" method=GET>\n"); 341 fprintf(f, "Symbol lookup: <input type=text name=name size=40></input><br>\n"); 342 fprintf(f, "<input type=hidden name=sym value=\"0x%x\">\n", sym); 343 fprintf(f, "Submit : <input type=submit></input>\n"); 344 fprintf(f, "</form>"); 345 346 if (name) { 347 Node *n = Swig_symbol_clookup(name, sym); 348 Printf(f, "Symbol '%s':\n", name); 349 Printf(f, "<blockquote>\n"); 350 if (!n) { 351 Printf(f, "Not defined!\n"); 352 } else { 353 raw_data(f, n); 354 } 355 Printf(f, "</blockquote>\n"); 356 } 357 358 Printf(f, "<p><b>Nested scopes</b><br>\n"); 359 Printf(f, "<blockquote><pre>\n"); 360 { 361 Hash *h; 362 h = firstChild(sym); 363 while (h) { 364 Printf(f, "<a href=\"symbol.html?sym=0x%x\">%s</a>\n", h, Getattr(h, "name")); 365 h = nextSibling(h); 366 } 367 } 368 Printf(f, "</pre></blockquote>\n"); 369 370 Printf(f, "<p><b>Symbol table contents</b></br>\n"); 371 raw_data(f, Getattr(sym, "symtab")); 372 Printf(f, "<br><hr></BODY></HTML>\n"); 373 374} 375#endif 376 377void Swig_browser(Node *top, int port) { 378#ifdef SWIG_SWILL 379 int sport; 380 browser_exit = 0; 381 382 /* Initialize the server */ 383 sport = swill_init(port); 384 if (sport < 0) { 385 Printf(stderr, "Couldn't open socket on port %d. Sorry.\n", port); 386 return; 387 } 388 browse = new Browser(); 389 Setmeta(top, "visible", "1"); 390 tree_top = top; 391 392 Printf(stderr, "SWIG: Tree browser listening on port %d\n", sport); 393 394 swill_handle("exit.html", exit_handler, 0); 395 swill_handle("index.html", node_handler, 0); 396 swill_handle("hide.html", hide_handler, 0); 397 swill_handle("show.html", show_handler, 0); 398 swill_handle("data.html", data_handler, 0); 399 swill_handle("symbol.html", symbol_handler, 0); 400 swill_netscape("index.html"); 401 402 while (!browser_exit) { 403 swill_serve(); 404 } 405 Printf(stderr, "Browser terminated.\n"); 406 swill_close(); 407 delete browse; 408 return; 409#else 410 (void) top; 411 (void) port; 412#endif 413} 414