import source from 1.3.40
[external/swig.git] / Source / Modules / browser.cxx
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
11 char cvsroot_browser_cxx[] = "$Id: browser.cxx 10003 2007-10-17 21:42:11Z wsfulton $";
12
13 #include "swigmod.h"
14
15 #ifdef SWIG_SWILL
16 extern "C" {
17 #include "swill.h"
18 } static FILE *out = 0;
19 static Node *view_top = 0;
20
21 class 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, "&", "&amp;");
49         Replaceall(o, "<", "&lt;");
50         Replaceall(o, ">", "&gt;");
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, "&", "&amp;");
62           Replaceall(o, "<", "&lt;");
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
75 public:
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
160 static int browser_exit = 0;
161 static Node *tree_top = 0;
162 static Browser *browse = 0;
163
164 /* ----------------------------------------------------------------------
165  * exit_handler()      - Force the browser to exit
166  * ---------------------------------------------------------------------- */
167
168 void 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
177 static 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
199 void 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
213 void 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
224 void 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
235 void 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, "<", "&lt;");
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, "<", "&lt;");
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, "<", "&lt;");
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
294 void 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
311 void 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
377 void 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 }