Since I have made several changes to SWIG over the years to accomodate
special cases and other things in wxPython, and since I plan on making several more, I've decided to put the SWIG sources in wxPython's CVS instead of relying on maintaining patches. This effectivly becomes a fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still doesn't have some things I rely on in 1.1, not to mention that my custom patches would all have to be redone, I felt that this is the easier road to take. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15307 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
607
wxPython/wxSWIG/SWIG/newdoc.cxx
Normal file
607
wxPython/wxSWIG/SWIG/newdoc.cxx
Normal file
@@ -0,0 +1,607 @@
|
||||
/*******************************************************************************
|
||||
* Simplified Wrapper and Interface Generator (SWIG)
|
||||
*
|
||||
* Author : David Beazley
|
||||
*
|
||||
* Department of Computer Science
|
||||
* University of Chicago
|
||||
* 1100 E 58th Street
|
||||
* Chicago, IL 60637
|
||||
* beazley@cs.uchicago.edu
|
||||
*
|
||||
* Please read the file LICENSE for the copyright and terms by which SWIG
|
||||
* can be used and distributed.
|
||||
*******************************************************************************/
|
||||
/***********************************************************************
|
||||
* $Header$
|
||||
*
|
||||
* newdoc.cxx
|
||||
*
|
||||
* SWIG Documentation system. (2nd attempt)
|
||||
*
|
||||
* SWIG organizes documentation as a tree structure where each node is a
|
||||
* documentation entry (DocEntry) of some kind. To generate documentation,
|
||||
* we simply traverse the tree and call output methods.
|
||||
*
|
||||
* A sample documentation tree looks something like the following :
|
||||
*
|
||||
* TITLE ----> SECTION 1 ----> func1
|
||||
* ----> func2
|
||||
* ----> func3
|
||||
* ----> class ---> func1
|
||||
* ---> func2
|
||||
* ---> var1
|
||||
* ----> func4
|
||||
*
|
||||
* ----> SECTION 2 ----> func1
|
||||
* ----> var1
|
||||
*
|
||||
* and so on.
|
||||
*
|
||||
* This structure makes it possible to organize C++ classes and more
|
||||
* complicated structures. Hopefully this will provide enough structure
|
||||
* for later versions of SWIG.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
#include "internal.h"
|
||||
#include <ctype.h>
|
||||
|
||||
extern char *get_time();
|
||||
static char *last_name = 0;
|
||||
|
||||
DocEntry *DocEntry::dead_entries = 0;
|
||||
|
||||
// Utility function for converting a string to upper case
|
||||
|
||||
static void str_toupper(char *str) {
|
||||
char *c;
|
||||
c = str;
|
||||
while (*c) {
|
||||
*c = toupper(*c);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// DocEntry::~DocEntry
|
||||
//
|
||||
// Destroy a documentation entry. Destroys this entry and all of
|
||||
// its children.
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
DocEntry::~DocEntry() {
|
||||
DocEntry *de, *de1;
|
||||
|
||||
if (name) delete name;
|
||||
|
||||
// Now kill all of the children (well, figuratively speaking)
|
||||
|
||||
de = child;
|
||||
while (de) {
|
||||
de1 = de->next;
|
||||
delete de;
|
||||
de = de1;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// void DocEntry::sort_children()
|
||||
//
|
||||
// Sort children by name (not height). This function gathers all
|
||||
// of the children up into an array of pointers. Then we do an
|
||||
// insertion sort on it and place the children back in order.
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void DocEntry::sort_children() {
|
||||
|
||||
int count = 0;
|
||||
int i,j;
|
||||
DocEntry *d;
|
||||
DocEntry **list;
|
||||
DocEntry *v;
|
||||
|
||||
if (!child) return; // Nothing to sort
|
||||
|
||||
d = child;
|
||||
while (d) {
|
||||
count++;
|
||||
d = d->next;
|
||||
}
|
||||
|
||||
// allocate a temporary array for sorting everything
|
||||
|
||||
list = new DocEntry *[count+2];
|
||||
|
||||
// Now put pointers into list
|
||||
|
||||
d = child;
|
||||
i = 0;
|
||||
while (d) {
|
||||
list[i] = d;
|
||||
d = d->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
// Do an insertion sort by name
|
||||
|
||||
for (i = 1; i < count; i++) {
|
||||
v = list[i];
|
||||
j = i;
|
||||
while((j > 0) && (strcmp(list[j-1]->name,v->name) > 0)) {
|
||||
list[j] = list[j-1];
|
||||
j--;
|
||||
}
|
||||
list[j] = v;
|
||||
}
|
||||
|
||||
// Now, we're going to reorganize the children in order
|
||||
|
||||
list[count] = 0;
|
||||
child = list[0]; // Our child is the first one in the list
|
||||
d = child;
|
||||
for (i = 0; i < count; i++) {
|
||||
d->next = list[i+1];
|
||||
d = d->next;
|
||||
}
|
||||
delete list;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// void DocEntry::output()
|
||||
//
|
||||
// Output this entry
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void DocEntry::output(Documentation *) {
|
||||
fprintf(stderr,"SWIG (internal) : No output method defined for DocEntry.\n");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// DocEntry::add(DocEntry *de)
|
||||
//
|
||||
// Adds a new DocEntry as a sibling. Basically we just walk down the
|
||||
// linked list and append ourselves to the end. The documentation
|
||||
// Entry we're adding may, in fact, have siblings too, but this function
|
||||
// Should still work.
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void DocEntry::add(DocEntry *de) {
|
||||
DocEntry *d,*d1;
|
||||
d = next;
|
||||
d1 = this;
|
||||
while (d) {
|
||||
d1 = d;
|
||||
d = d->next;
|
||||
}
|
||||
d1->next = de;
|
||||
de->previous = d1; // Set up the previous list member
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// DocEntry::addchild(DocEntry *de)
|
||||
//
|
||||
// Adds a new DocEntry as a child. If we're in Ignore mode, the
|
||||
// documentation entry is still created, but we simply abandon it.
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void DocEntry::addchild(DocEntry *de) {
|
||||
if (!IgnoreDoc) {
|
||||
if (child) child->add(de);
|
||||
else child = de;
|
||||
} else {
|
||||
if (dead_entries) dead_entries->add(de);
|
||||
else dead_entries = de;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// DocEntry::remove()
|
||||
//
|
||||
// Removes a documentation entry from the tree and places it on
|
||||
// the dead_entries list
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
void DocEntry::remove() {
|
||||
|
||||
if (previous) {
|
||||
if (next)
|
||||
previous->next = next; // Take out of the linked list
|
||||
else
|
||||
previous->next = 0;
|
||||
} else { // Make sure our parent isn't pointing to us
|
||||
if (parent)
|
||||
parent->child = next;
|
||||
}
|
||||
|
||||
previous = 0;
|
||||
next = 0;
|
||||
|
||||
if (!dead_entries) dead_entries = this;
|
||||
else dead_entries->add(this);
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// void DocEntry::style(char *name, char *value)
|
||||
//
|
||||
// Set style parameters of a documentation entry
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
void DocEntry::style(char *pname, char *) {
|
||||
if (strcmp(pname,"sort") == 0) {
|
||||
sorted = 1;
|
||||
} else if (strcmp(pname,"nosort") == 0) {
|
||||
sorted = 0;
|
||||
} else if (strcmp(pname,"info") == 0) {
|
||||
print_info = 1;
|
||||
} else if (strcmp(pname,"noinfo") == 0) {
|
||||
print_info = 0;
|
||||
} else if (strcmp(pname,"pre") == 0) {
|
||||
format = 0;
|
||||
} else if (strcmp(pname,"format") == 0) {
|
||||
format = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// void DocEntry::parse_args(int argc, char **argv)
|
||||
//
|
||||
// Take command line options and process them. This really only
|
||||
// applies to the top-level documentation entry.
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
static char *doc_usage = "\
|
||||
Documentation Processing : \n\
|
||||
-Sformat - Reformat comment text\n\
|
||||
-Sinfo - Print C formatting information (the default)\n\
|
||||
-Snoinfo - Omit C formatting information.\n\
|
||||
-Snosort - Print everything in order (the default)\n\
|
||||
-Spre - Assume comments are pre-formatted (the default)\n\
|
||||
-Ssort - Sort documentation alphabetically\n\n";
|
||||
|
||||
void DocEntry::parse_args(int argc, char **argv) {
|
||||
int i;
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (argv[i]) {
|
||||
if (strcmp(argv[i],"-Ssort") == 0) {
|
||||
this->style("sort",0);
|
||||
mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-Snosort") == 0) {
|
||||
this->style("nosort",0);
|
||||
mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-Sinfo") == 0) {
|
||||
this->style("info",0);
|
||||
mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-Snoinfo") == 0) {
|
||||
this->style("noinfo",0);
|
||||
mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-Spre") == 0) {
|
||||
this->style("pre",0);
|
||||
mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-Sformat") == 0) {
|
||||
this->style("format",0);
|
||||
mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-help") == 0) {
|
||||
fputs(doc_usage,stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// DocTitle::DocTitle(char *title, DocEntry *_parent);
|
||||
//
|
||||
// Create a new title documentation entry. The name of the entry
|
||||
// is the title.
|
||||
//
|
||||
// The body text is optional, but may be filled in with a description
|
||||
// as well.
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
DocTitle::DocTitle(char *title, DocEntry *_parent) {
|
||||
name = copy_string(title);
|
||||
str_toupper(name);
|
||||
parent = _parent;
|
||||
child = 0;
|
||||
next = 0;
|
||||
previous = 0;
|
||||
usage << title << "\n";
|
||||
counter = 1;
|
||||
is_separator = 1;
|
||||
line_number = ::start_line;
|
||||
end_line = ::line_number;
|
||||
file = copy_string(input_file);
|
||||
if (_parent) {
|
||||
sorted = _parent->sorted;
|
||||
format = _parent->format;
|
||||
print_info = _parent->print_info;
|
||||
} else {
|
||||
sorted = SWIGDEFAULT_SORT;
|
||||
format = SWIGDEFAULT_FORMAT;
|
||||
print_info = SWIGDEFAULT_INFO;
|
||||
}
|
||||
comment_handler->set_entry(this);
|
||||
if (last_name) delete last_name;
|
||||
last_name = 0;
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
// DocTitle::output(Documentation *d)
|
||||
//
|
||||
// Output a title to the Documentation module
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void DocTitle::output(Documentation *d) {
|
||||
DocEntry *de;
|
||||
|
||||
d->title(this);
|
||||
if (sorted) {
|
||||
sort_children();
|
||||
}
|
||||
|
||||
// Now output my children
|
||||
|
||||
de = child;
|
||||
while (de) {
|
||||
de->output(d);
|
||||
de = de->next;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// DocSection::DocSection(char *section, DocEntry *_parent);
|
||||
//
|
||||
// Create a new documentation section. The name and description is
|
||||
// set to the name of the section. The text field is optional
|
||||
// but could contain a more complete description.
|
||||
//
|
||||
// The sorted field indicates whether members of this section are
|
||||
// sorted or not.
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
DocSection::DocSection(char *section, DocEntry *_parent) {
|
||||
name = copy_string(section);
|
||||
str_toupper(name);
|
||||
parent = _parent;
|
||||
child = 0;
|
||||
next = 0;
|
||||
previous = 0;
|
||||
usage << section;
|
||||
counter = 1;
|
||||
is_separator = 1;
|
||||
if (_parent) _parent->addchild(this);
|
||||
line_number = ::start_line;
|
||||
end_line = ::line_number;
|
||||
file = copy_string(input_file);
|
||||
if (_parent) {
|
||||
sorted = _parent->sorted;
|
||||
format = _parent->format;
|
||||
print_info = _parent->print_info;
|
||||
} else {
|
||||
sorted = SWIGDEFAULT_SORT;
|
||||
format = SWIGDEFAULT_FORMAT;
|
||||
print_info = SWIGDEFAULT_INFO;
|
||||
}
|
||||
comment_handler->set_entry(this);
|
||||
if (last_name) delete last_name;
|
||||
last_name = 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// DocSection::output(Documentation *d)
|
||||
//
|
||||
// Output a section to the documentation module
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void DocSection::output(Documentation *d) {
|
||||
DocEntry *de;
|
||||
|
||||
// Make a new section
|
||||
|
||||
d->newsection(this,this->parent->counter++); // Make a new section
|
||||
|
||||
// Sort the children if necessary
|
||||
|
||||
if (sorted) {
|
||||
sort_children();
|
||||
}
|
||||
|
||||
// Now output my children
|
||||
|
||||
de = child;
|
||||
while (de) {
|
||||
de->output(d);
|
||||
de = de->next;
|
||||
}
|
||||
|
||||
// End this section
|
||||
|
||||
d->endsection();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// DocDecl::DocDecl(char *fname, DocEntry *_parent);
|
||||
//
|
||||
// Create documentation for a function declaration.
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
DocDecl::DocDecl(char *fname, DocEntry *_parent) {
|
||||
name = copy_string(fname);
|
||||
str_toupper(name);
|
||||
parent = _parent;
|
||||
child = 0;
|
||||
next = 0;
|
||||
previous = 0;
|
||||
is_separator = 0;
|
||||
if (_parent) _parent->addchild(this);
|
||||
line_number = ::start_line;
|
||||
end_line = ::line_number;
|
||||
file = copy_string(input_file);
|
||||
if (_parent) {
|
||||
sorted = _parent->sorted;
|
||||
format = _parent->format;
|
||||
print_info = _parent->print_info;
|
||||
} else {
|
||||
sorted = SWIGDEFAULT_SORT;
|
||||
format = SWIGDEFAULT_FORMAT;
|
||||
print_info = SWIGDEFAULT_INFO;
|
||||
}
|
||||
comment_handler->set_entry(this);
|
||||
if (last_name) delete last_name;
|
||||
last_name = copy_string(name);
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// DocDecl::DocDecl(DocEntry *de, DocEntry *_parent)
|
||||
//
|
||||
// Make a new declaration entry, but copy attributes from someone else
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
DocDecl::DocDecl(DocEntry *de, DocEntry *_parent) {
|
||||
name = copy_string(de->name);
|
||||
usage = de->usage.get();
|
||||
cinfo = de->cinfo.get();
|
||||
text = de->text.get();
|
||||
line_number = de->line_number;
|
||||
end_line = de->end_line;
|
||||
file = copy_string(de->file);
|
||||
print_info = de->print_info;
|
||||
format = de->format;
|
||||
if (_parent) {
|
||||
_parent->addchild(this);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// DocDecl::output(Documentation *d)
|
||||
//
|
||||
// Output a function to the documentation module
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void DocDecl::output(Documentation *d) {
|
||||
d->print_decl(this);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// DocClass::DocClass(char *classname, DocEntry *_parent);
|
||||
//
|
||||
// Create a new class section. Classes are created as funny sorts of
|
||||
// sections.
|
||||
//
|
||||
// The sorted field indicates whether members of this section are
|
||||
// sorted or not.
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
DocClass::DocClass(char *classname, DocEntry *_parent) {
|
||||
name = copy_string(classname);
|
||||
str_toupper(name);
|
||||
parent = _parent;
|
||||
child = 0;
|
||||
next = 0;
|
||||
previous = 0;
|
||||
usage << classname<< "\n";
|
||||
counter = 1;
|
||||
is_separator = 1;
|
||||
if (_parent) _parent->addchild(this);
|
||||
line_number = ::start_line;
|
||||
end_line = ::line_number;
|
||||
file = copy_string(input_file);
|
||||
if (_parent) {
|
||||
sorted = _parent->sorted;
|
||||
format = _parent->format;
|
||||
print_info = _parent->print_info;
|
||||
} else {
|
||||
sorted = SWIGDEFAULT_SORT;
|
||||
format = SWIGDEFAULT_FORMAT;
|
||||
print_info = SWIGDEFAULT_INFO;
|
||||
}
|
||||
comment_handler->set_entry(this);
|
||||
if (last_name) delete last_name;
|
||||
last_name = copy_string(name);
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// DocClass::output(Documentation *d)
|
||||
//
|
||||
// Output a section to the documentation module
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void DocClass::output(Documentation *d) {
|
||||
DocEntry *de;
|
||||
|
||||
// Make a new section
|
||||
|
||||
d->newsection(this,this->parent->counter++); // Make a subsection for this
|
||||
|
||||
// Sort the children if necessary
|
||||
|
||||
if (sorted) {
|
||||
sort_children();
|
||||
}
|
||||
|
||||
// Now output my children
|
||||
|
||||
de = child;
|
||||
while (de) {
|
||||
de->output(d);
|
||||
de = de->next;
|
||||
}
|
||||
|
||||
// End this section
|
||||
|
||||
d->endsection();
|
||||
|
||||
// We now check to see if the next thing is a separator. If not, we'll
|
||||
// emit a separator
|
||||
|
||||
if (next) {
|
||||
if (!next->is_separator)
|
||||
d->separator();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// DocText::DocText(char *_text, DocEntry *_parent);
|
||||
//
|
||||
// Create documentation for a function declaration.
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
DocText::DocText(char *_text, DocEntry *_parent) {
|
||||
if (!last_name)
|
||||
name = copy_string(""); // There is no name for text
|
||||
else
|
||||
name = copy_string(last_name);
|
||||
parent = _parent;
|
||||
child = 0;
|
||||
next = 0;
|
||||
previous = 0;
|
||||
text << _text;
|
||||
is_separator = 0;
|
||||
if (_parent) _parent->addchild(this);
|
||||
if (_parent) {
|
||||
sorted = _parent->sorted;
|
||||
format = _parent->format;
|
||||
print_info = _parent->print_info;
|
||||
} else {
|
||||
sorted = SWIGDEFAULT_SORT;
|
||||
format = SWIGDEFAULT_FORMAT;
|
||||
print_info = SWIGDEFAULT_INFO;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// DocText::output(Documentation *d)
|
||||
//
|
||||
// Output a function to the documentation module
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void DocText::output(Documentation *d) {
|
||||
d->print_text(this);
|
||||
}
|
||||
|
Reference in New Issue
Block a user