]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wxSWIG/SWIG/newdoc.cxx
compilation error fix (trailing comma in an enum)
[wxWidgets.git] / wxPython / wxSWIG / SWIG / newdoc.cxx
CommitLineData
c90f71dd
RD
1/*******************************************************************************
2 * Simplified Wrapper and Interface Generator (SWIG)
3 *
4 * Author : David Beazley
5 *
6 * Department of Computer Science
7 * University of Chicago
8 * 1100 E 58th Street
9 * Chicago, IL 60637
10 * beazley@cs.uchicago.edu
11 *
12 * Please read the file LICENSE for the copyright and terms by which SWIG
13 * can be used and distributed.
14 *******************************************************************************/
15/***********************************************************************
16 * $Header$
17 *
18 * newdoc.cxx
19 *
20 * SWIG Documentation system. (2nd attempt)
21 *
22 * SWIG organizes documentation as a tree structure where each node is a
23 * documentation entry (DocEntry) of some kind. To generate documentation,
24 * we simply traverse the tree and call output methods.
25 *
26 * A sample documentation tree looks something like the following :
27 *
28 * TITLE ----> SECTION 1 ----> func1
29 * ----> func2
30 * ----> func3
31 * ----> class ---> func1
32 * ---> func2
33 * ---> var1
34 * ----> func4
35 *
36 * ----> SECTION 2 ----> func1
37 * ----> var1
38 *
39 * and so on.
40 *
41 * This structure makes it possible to organize C++ classes and more
42 * complicated structures. Hopefully this will provide enough structure
43 * for later versions of SWIG.
44 *
45 *************************************************************************/
46
47#include "internal.h"
48#include <ctype.h>
49
50extern char *get_time();
51static char *last_name = 0;
52
53DocEntry *DocEntry::dead_entries = 0;
54
55// Utility function for converting a string to upper case
56
57static void str_toupper(char *str) {
58 char *c;
59 c = str;
60 while (*c) {
61 *c = toupper(*c);
62 c++;
63 }
64}
65
66// --------------------------------------------------------------------
67// DocEntry::~DocEntry
68//
69// Destroy a documentation entry. Destroys this entry and all of
70// its children.
71// --------------------------------------------------------------------
72
73DocEntry::~DocEntry() {
74 DocEntry *de, *de1;
75
76 if (name) delete name;
77
78 // Now kill all of the children (well, figuratively speaking)
79
80 de = child;
81 while (de) {
82 de1 = de->next;
83 delete de;
84 de = de1;
85 }
86}
87
88// --------------------------------------------------------------------
89// void DocEntry::sort_children()
90//
91// Sort children by name (not height). This function gathers all
92// of the children up into an array of pointers. Then we do an
93// insertion sort on it and place the children back in order.
94// --------------------------------------------------------------------
95
96void DocEntry::sort_children() {
97
98 int count = 0;
99 int i,j;
100 DocEntry *d;
101 DocEntry **list;
102 DocEntry *v;
103
104 if (!child) return; // Nothing to sort
105
106 d = child;
107 while (d) {
108 count++;
109 d = d->next;
110 }
111
112 // allocate a temporary array for sorting everything
113
114 list = new DocEntry *[count+2];
115
116 // Now put pointers into list
117
118 d = child;
119 i = 0;
120 while (d) {
121 list[i] = d;
122 d = d->next;
123 i++;
124 }
125
126 // Do an insertion sort by name
127
128 for (i = 1; i < count; i++) {
129 v = list[i];
130 j = i;
131 while((j > 0) && (strcmp(list[j-1]->name,v->name) > 0)) {
132 list[j] = list[j-1];
133 j--;
134 }
135 list[j] = v;
136 }
137
138 // Now, we're going to reorganize the children in order
139
140 list[count] = 0;
141 child = list[0]; // Our child is the first one in the list
142 d = child;
143 for (i = 0; i < count; i++) {
144 d->next = list[i+1];
145 d = d->next;
146 }
147 delete list;
148}
149
150// --------------------------------------------------------------------
151// void DocEntry::output()
152//
153// Output this entry
154// --------------------------------------------------------------------
155
156void DocEntry::output(Documentation *) {
157 fprintf(stderr,"SWIG (internal) : No output method defined for DocEntry.\n");
158}
159
160// --------------------------------------------------------------------
161// DocEntry::add(DocEntry *de)
162//
163// Adds a new DocEntry as a sibling. Basically we just walk down the
164// linked list and append ourselves to the end. The documentation
165// Entry we're adding may, in fact, have siblings too, but this function
166// Should still work.
167// --------------------------------------------------------------------
168
169void DocEntry::add(DocEntry *de) {
170 DocEntry *d,*d1;
171 d = next;
172 d1 = this;
173 while (d) {
174 d1 = d;
175 d = d->next;
176 }
177 d1->next = de;
178 de->previous = d1; // Set up the previous list member
179}
180
181
182// --------------------------------------------------------------------
183// DocEntry::addchild(DocEntry *de)
184//
185// Adds a new DocEntry as a child. If we're in Ignore mode, the
186// documentation entry is still created, but we simply abandon it.
187// --------------------------------------------------------------------
188
189void DocEntry::addchild(DocEntry *de) {
190 if (!IgnoreDoc) {
191 if (child) child->add(de);
192 else child = de;
193 } else {
194 if (dead_entries) dead_entries->add(de);
195 else dead_entries = de;
196 }
197}
198
199// -------------------------------------------------------------------
200// DocEntry::remove()
201//
202// Removes a documentation entry from the tree and places it on
203// the dead_entries list
204// -------------------------------------------------------------------
205
206void DocEntry::remove() {
207
208 if (previous) {
209 if (next)
210 previous->next = next; // Take out of the linked list
211 else
212 previous->next = 0;
213 } else { // Make sure our parent isn't pointing to us
214 if (parent)
215 parent->child = next;
216 }
217
218 previous = 0;
219 next = 0;
220
221 if (!dead_entries) dead_entries = this;
222 else dead_entries->add(this);
223
224}
225
226// -------------------------------------------------------------------
227// void DocEntry::style(char *name, char *value)
228//
229// Set style parameters of a documentation entry
230// -------------------------------------------------------------------
231
232void DocEntry::style(char *pname, char *) {
233 if (strcmp(pname,"sort") == 0) {
234 sorted = 1;
235 } else if (strcmp(pname,"nosort") == 0) {
236 sorted = 0;
237 } else if (strcmp(pname,"info") == 0) {
238 print_info = 1;
239 } else if (strcmp(pname,"noinfo") == 0) {
240 print_info = 0;
241 } else if (strcmp(pname,"pre") == 0) {
242 format = 0;
243 } else if (strcmp(pname,"format") == 0) {
244 format = 1;
245 }
246}
247
248// -------------------------------------------------------------------
249// void DocEntry::parse_args(int argc, char **argv)
250//
251// Take command line options and process them. This really only
252// applies to the top-level documentation entry.
253// -------------------------------------------------------------------
254
255static char *doc_usage = "\
256Documentation Processing : \n\
257 -Sformat - Reformat comment text\n\
258 -Sinfo - Print C formatting information (the default)\n\
259 -Snoinfo - Omit C formatting information.\n\
260 -Snosort - Print everything in order (the default)\n\
261 -Spre - Assume comments are pre-formatted (the default)\n\
262 -Ssort - Sort documentation alphabetically\n\n";
263
264void DocEntry::parse_args(int argc, char **argv) {
265 int i;
266 for (i = 1; i < argc; i++) {
267 if (argv[i]) {
268 if (strcmp(argv[i],"-Ssort") == 0) {
269 this->style("sort",0);
270 mark_arg(i);
271 } else if (strcmp(argv[i],"-Snosort") == 0) {
272 this->style("nosort",0);
273 mark_arg(i);
274 } else if (strcmp(argv[i],"-Sinfo") == 0) {
275 this->style("info",0);
276 mark_arg(i);
277 } else if (strcmp(argv[i],"-Snoinfo") == 0) {
278 this->style("noinfo",0);
279 mark_arg(i);
280 } else if (strcmp(argv[i],"-Spre") == 0) {
281 this->style("pre",0);
282 mark_arg(i);
283 } else if (strcmp(argv[i],"-Sformat") == 0) {
284 this->style("format",0);
285 mark_arg(i);
286 } else if (strcmp(argv[i],"-help") == 0) {
287 fputs(doc_usage,stderr);
288 }
289 }
290 }
291}
292
293
294// -------------------------------------------------------------------
295// DocTitle::DocTitle(char *title, DocEntry *_parent);
296//
297// Create a new title documentation entry. The name of the entry
298// is the title.
299//
300// The body text is optional, but may be filled in with a description
301// as well.
302// -------------------------------------------------------------------
303
304DocTitle::DocTitle(char *title, DocEntry *_parent) {
305 name = copy_string(title);
306 str_toupper(name);
307 parent = _parent;
308 child = 0;
309 next = 0;
310 previous = 0;
311 usage << title << "\n";
312 counter = 1;
313 is_separator = 1;
314 line_number = ::start_line;
315 end_line = ::line_number;
316 file = copy_string(input_file);
317 if (_parent) {
318 sorted = _parent->sorted;
319 format = _parent->format;
320 print_info = _parent->print_info;
321 } else {
322 sorted = SWIGDEFAULT_SORT;
323 format = SWIGDEFAULT_FORMAT;
324 print_info = SWIGDEFAULT_INFO;
325 }
326 comment_handler->set_entry(this);
327 if (last_name) delete last_name;
328 last_name = 0;
329}
330// --------------------------------------------------------------------
331// DocTitle::output(Documentation *d)
332//
333// Output a title to the Documentation module
334// --------------------------------------------------------------------
335
336void DocTitle::output(Documentation *d) {
337 DocEntry *de;
338
339 d->title(this);
340 if (sorted) {
341 sort_children();
342 }
343
344 // Now output my children
345
346 de = child;
347 while (de) {
348 de->output(d);
349 de = de->next;
350 }
351}
352
353// -------------------------------------------------------------------
354// DocSection::DocSection(char *section, DocEntry *_parent);
355//
356// Create a new documentation section. The name and description is
357// set to the name of the section. The text field is optional
358// but could contain a more complete description.
359//
360// The sorted field indicates whether members of this section are
361// sorted or not.
362// -------------------------------------------------------------------
363
364DocSection::DocSection(char *section, DocEntry *_parent) {
365 name = copy_string(section);
366 str_toupper(name);
367 parent = _parent;
368 child = 0;
369 next = 0;
370 previous = 0;
371 usage << section;
372 counter = 1;
373 is_separator = 1;
374 if (_parent) _parent->addchild(this);
375 line_number = ::start_line;
376 end_line = ::line_number;
377 file = copy_string(input_file);
378 if (_parent) {
379 sorted = _parent->sorted;
380 format = _parent->format;
381 print_info = _parent->print_info;
382 } else {
383 sorted = SWIGDEFAULT_SORT;
384 format = SWIGDEFAULT_FORMAT;
385 print_info = SWIGDEFAULT_INFO;
386 }
387 comment_handler->set_entry(this);
388 if (last_name) delete last_name;
389 last_name = 0;
390}
391
392// --------------------------------------------------------------------
393// DocSection::output(Documentation *d)
394//
395// Output a section to the documentation module
396// --------------------------------------------------------------------
397
398void DocSection::output(Documentation *d) {
399 DocEntry *de;
400
401 // Make a new section
402
403 d->newsection(this,this->parent->counter++); // Make a new section
404
405 // Sort the children if necessary
406
407 if (sorted) {
408 sort_children();
409 }
410
411 // Now output my children
412
413 de = child;
414 while (de) {
415 de->output(d);
416 de = de->next;
417 }
418
419 // End this section
420
421 d->endsection();
422
423}
424
425
426// -------------------------------------------------------------------
427// DocDecl::DocDecl(char *fname, DocEntry *_parent);
428//
429// Create documentation for a function declaration.
430// -------------------------------------------------------------------
431
432DocDecl::DocDecl(char *fname, DocEntry *_parent) {
433 name = copy_string(fname);
434 str_toupper(name);
435 parent = _parent;
436 child = 0;
437 next = 0;
438 previous = 0;
439 is_separator = 0;
440 if (_parent) _parent->addchild(this);
441 line_number = ::start_line;
442 end_line = ::line_number;
443 file = copy_string(input_file);
444 if (_parent) {
445 sorted = _parent->sorted;
446 format = _parent->format;
447 print_info = _parent->print_info;
448 } else {
449 sorted = SWIGDEFAULT_SORT;
450 format = SWIGDEFAULT_FORMAT;
451 print_info = SWIGDEFAULT_INFO;
452 }
453 comment_handler->set_entry(this);
454 if (last_name) delete last_name;
455 last_name = copy_string(name);
456}
457
458
459// --------------------------------------------------------------------
460// DocDecl::DocDecl(DocEntry *de, DocEntry *_parent)
461//
462// Make a new declaration entry, but copy attributes from someone else
463// --------------------------------------------------------------------
464
465DocDecl::DocDecl(DocEntry *de, DocEntry *_parent) {
466 name = copy_string(de->name);
467 usage = de->usage.get();
468 cinfo = de->cinfo.get();
469 text = de->text.get();
470 line_number = de->line_number;
471 end_line = de->end_line;
472 file = copy_string(de->file);
473 print_info = de->print_info;
474 format = de->format;
475 if (_parent) {
476 _parent->addchild(this);
477 }
478}
479
480// --------------------------------------------------------------------
481// DocDecl::output(Documentation *d)
482//
483// Output a function to the documentation module
484// --------------------------------------------------------------------
485
486void DocDecl::output(Documentation *d) {
487 d->print_decl(this);
488}
489
490// -------------------------------------------------------------------
491// DocClass::DocClass(char *classname, DocEntry *_parent);
492//
493// Create a new class section. Classes are created as funny sorts of
494// sections.
495//
496// The sorted field indicates whether members of this section are
497// sorted or not.
498// -------------------------------------------------------------------
499
500DocClass::DocClass(char *classname, DocEntry *_parent) {
501 name = copy_string(classname);
502 str_toupper(name);
503 parent = _parent;
504 child = 0;
505 next = 0;
506 previous = 0;
507 usage << classname<< "\n";
508 counter = 1;
509 is_separator = 1;
510 if (_parent) _parent->addchild(this);
511 line_number = ::start_line;
512 end_line = ::line_number;
513 file = copy_string(input_file);
514 if (_parent) {
515 sorted = _parent->sorted;
516 format = _parent->format;
517 print_info = _parent->print_info;
518 } else {
519 sorted = SWIGDEFAULT_SORT;
520 format = SWIGDEFAULT_FORMAT;
521 print_info = SWIGDEFAULT_INFO;
522 }
523 comment_handler->set_entry(this);
524 if (last_name) delete last_name;
525 last_name = copy_string(name);
526
527}
528
529// --------------------------------------------------------------------
530// DocClass::output(Documentation *d)
531//
532// Output a section to the documentation module
533// --------------------------------------------------------------------
534
535void DocClass::output(Documentation *d) {
536 DocEntry *de;
537
538 // Make a new section
539
540 d->newsection(this,this->parent->counter++); // Make a subsection for this
541
542 // Sort the children if necessary
543
544 if (sorted) {
545 sort_children();
546 }
547
548 // Now output my children
549
550 de = child;
551 while (de) {
552 de->output(d);
553 de = de->next;
554 }
555
556 // End this section
557
558 d->endsection();
559
560 // We now check to see if the next thing is a separator. If not, we'll
561 // emit a separator
562
563 if (next) {
564 if (!next->is_separator)
565 d->separator();
566 }
567}
568
569// -------------------------------------------------------------------
570// DocText::DocText(char *_text, DocEntry *_parent);
571//
572// Create documentation for a function declaration.
573// -------------------------------------------------------------------
574
575DocText::DocText(char *_text, DocEntry *_parent) {
576 if (!last_name)
577 name = copy_string(""); // There is no name for text
578 else
579 name = copy_string(last_name);
580 parent = _parent;
581 child = 0;
582 next = 0;
583 previous = 0;
584 text << _text;
585 is_separator = 0;
586 if (_parent) _parent->addchild(this);
587 if (_parent) {
588 sorted = _parent->sorted;
589 format = _parent->format;
590 print_info = _parent->print_info;
591 } else {
592 sorted = SWIGDEFAULT_SORT;
593 format = SWIGDEFAULT_FORMAT;
594 print_info = SWIGDEFAULT_INFO;
595 }
596}
597
598// --------------------------------------------------------------------
599// DocText::output(Documentation *d)
600//
601// Output a function to the documentation module
602// --------------------------------------------------------------------
603
604void DocText::output(Documentation *d) {
605 d->print_text(this);
606}
607