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