c90f71dd8c
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
599 lines
14 KiB
C++
599 lines
14 KiB
C++
/*******************************************************************************
|
|
* 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.
|
|
*******************************************************************************/
|
|
|
|
#include "swig.h"
|
|
#include "html.h"
|
|
|
|
/*******************************************************************************
|
|
* $Header$
|
|
*
|
|
* File : html.cxx
|
|
*
|
|
* HTML specific functions for producing documentation.
|
|
*******************************************************************************/
|
|
|
|
#define PRE 0
|
|
#define FORMAT 1
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// HTML::HTML()
|
|
//
|
|
// Constructor. Creates a new HTML documentation module object.
|
|
//
|
|
// Inputs : None
|
|
//
|
|
// Output : HTML Object
|
|
//
|
|
// Side Effects : None
|
|
// -----------------------------------------------------------------------------
|
|
|
|
HTML::HTML() {
|
|
sect_count = 0;
|
|
last_section = 0;
|
|
|
|
// Initialize default tags for various parts of the documentation
|
|
|
|
tag_body = "<BODY BGCOLOR=\"#ffffff\">:</BODY>";
|
|
tag_title = "<H1>:</H1>";
|
|
tag_contents = "<HR><H1>:</H1>";
|
|
tag_section = "<HR><H2>:</H2>";
|
|
tag_subsection = "<H3>:</H3>";
|
|
tag_subsubsection = "<H4>:</H4>";
|
|
tag_usage = "<P><TT><B>:</B></TT>";
|
|
tag_descrip = "<BLOCKQUOTE>:</BLOCKQUOTE>";
|
|
tag_text = "<P>";
|
|
tag_cinfo = "";
|
|
tag_preformat = "<PRE>:</PRE>";
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// char *HTML::start_tag(char *tag)
|
|
//
|
|
// Utility function for returning the first part of an HTML tag variable.
|
|
// A tag must look like this :
|
|
//
|
|
// "<b>:</b>"
|
|
//
|
|
// The start tag for this would be "<b>"
|
|
//
|
|
// Inputs : tag = HTML tag string
|
|
//
|
|
// Output : Staring portion of the tag variable.
|
|
//
|
|
// Side Effects : None.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
char *HTML::start_tag(char *tag) {
|
|
static String stag;
|
|
char *c;
|
|
|
|
stag = "";
|
|
c = tag;
|
|
while ((*c) && (*c != ':')) {
|
|
stag << *c;
|
|
c++;
|
|
}
|
|
return stag.get();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// char *HTML::end_tag(char *tag)
|
|
//
|
|
// Utility for returning an end-tag. The counterpart to start_tag().
|
|
//
|
|
// Inputs : tag = HTML tag string
|
|
//
|
|
// Output : Ending portion of tag variable.
|
|
//
|
|
// Side Effects : None
|
|
// -----------------------------------------------------------------------------
|
|
|
|
char *HTML::end_tag(char *tag) {
|
|
static String etag;
|
|
char *c;
|
|
|
|
etag = "";
|
|
c = tag;
|
|
while ((*c) && (*c != ':')) {
|
|
c++;
|
|
}
|
|
if (*c) {
|
|
c++;
|
|
while (*c) {
|
|
etag << *c;
|
|
c++;
|
|
}
|
|
}
|
|
return etag.get();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void HTML::print_string(char *s, String &str, int mode)
|
|
//
|
|
// Outputs the contents of string s into String str. If mode is 1, we
|
|
// will reformat the text and apply a few common HTML character
|
|
// substitutions.
|
|
//
|
|
// Inputs : s = Documentation text string
|
|
// mode = Formatting mode (0 = preformat, 1 = formatted)
|
|
//
|
|
// Output : str = Output is append to str.
|
|
//
|
|
// Side Effects : None
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void HTML::print_string(char *s, String &str,int mode) {
|
|
char *c;
|
|
c = s;
|
|
while (*c) {
|
|
switch(*c) {
|
|
case '\"':
|
|
str << """;
|
|
break;
|
|
case '&':
|
|
str << "&";
|
|
break;
|
|
case '<':
|
|
if (mode == PRE)
|
|
str << "<";
|
|
else
|
|
str << (char) *c;
|
|
break;
|
|
case '>':
|
|
if (mode == PRE)
|
|
str << ">";
|
|
else
|
|
str << (char) *c;
|
|
break;
|
|
default :
|
|
str << (char ) *c;
|
|
break;
|
|
}
|
|
c++;
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void HTML::print_decl(DocEntry *de)
|
|
//
|
|
// Generates documentation for a declaration.
|
|
//
|
|
// Inputs : de = Documentation entry
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : None
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void HTML::print_decl(DocEntry *de) {
|
|
|
|
char *c;
|
|
c = de->usage.get();
|
|
while ((*c) && ((*c == ' ') || (*c == '\t') || (*c == '\n'))) c++;
|
|
if (c) {
|
|
s_doc << start_tag(tag_usage);
|
|
print_string(c,s_doc,PRE);
|
|
s_doc << end_tag(tag_usage) << "\n";
|
|
} else return;
|
|
|
|
// Only print this if there is information
|
|
|
|
if ((strlen(de->cinfo.get()) && de->print_info) || strlen(de->text.get())) {
|
|
s_doc << start_tag(tag_descrip);
|
|
if (!de->format)
|
|
s_doc << start_tag(tag_preformat);
|
|
}
|
|
|
|
// If there is any C annotation, print that
|
|
if (de->print_info) {
|
|
c = de->cinfo.get();
|
|
if (strlen(c) > 0) {
|
|
s_doc << start_tag(tag_cinfo);
|
|
s_doc << "[ ";
|
|
print_string(c,s_doc,PRE);
|
|
s_doc << " ]" << end_tag(tag_cinfo) << "\n";
|
|
if (de->format) s_doc << "<BR>";
|
|
}
|
|
}
|
|
|
|
c = de->text.get();
|
|
if (strlen(c) > 0) {
|
|
print_string(c,s_doc,de->format);
|
|
}
|
|
|
|
if ((strlen(de->cinfo.get()) && de->print_info) || strlen(de->text.get())) {
|
|
if (!de->format) s_doc << end_tag(tag_preformat);
|
|
s_doc << end_tag(tag_descrip) << "\n";
|
|
}
|
|
|
|
s_doc << "\n";
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void HTML::print_text(DocEntry *de)
|
|
//
|
|
// Generates documentation for a text-block. Strips any leading whitespace.
|
|
//
|
|
// Inputs : de = Documentation entry
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : None
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void HTML::print_text(DocEntry *de) {
|
|
char *c;
|
|
c = de->text.get();
|
|
if (strlen(c) > 0) {
|
|
s_doc << start_tag(tag_text);
|
|
if (!de->format)
|
|
s_doc << start_tag(tag_preformat);
|
|
print_string(c,s_doc,de->format);
|
|
if (!de->format)
|
|
s_doc << end_tag(tag_preformat) << "\n";
|
|
s_doc << end_tag(tag_text) << "\n";
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void HTML::title(DocEntry *de)
|
|
//
|
|
// Generates the title for an HTML document.
|
|
//
|
|
// Inputs : de = Title documentation entry
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : None
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void HTML::title(DocEntry *de) {
|
|
char *c;
|
|
c = de->usage.get();
|
|
if (strlen(c) > 0) {
|
|
s_title << "<HEAD>\n"
|
|
<< "<TITLE>\n";
|
|
print_string(c,s_title,PRE);
|
|
s_title << "</TITLE>\n"
|
|
<< start_tag(tag_body) << "\n";
|
|
|
|
s_title << start_tag(tag_title);
|
|
print_string(c,s_title,PRE);
|
|
s_title << end_tag(tag_title) << "\n";
|
|
}
|
|
|
|
if (!de->format)
|
|
s_title << start_tag(tag_preformat);
|
|
|
|
// If there is any C annotation, print that
|
|
if (de->print_info) {
|
|
c = de->cinfo.get();
|
|
if (strlen(c) > 0) {
|
|
s_title << start_tag(tag_cinfo) << "[ ";
|
|
print_string(c,s_title,de->format);
|
|
s_title << " ]" << end_tag(tag_cinfo);
|
|
if (de->format)
|
|
s_title << "<BR>\n";
|
|
else
|
|
s_title << "\n";
|
|
}
|
|
}
|
|
|
|
c = de->text.get();
|
|
if (strlen(c)) {
|
|
print_string(c,s_title,de->format);
|
|
}
|
|
if (!de->format)
|
|
s_title << end_tag(tag_preformat) << "\n";
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void HTML::newsection(DocEntry *de, int sectnum)
|
|
//
|
|
// Creates a new section. sect_count is used to determine the formatting of
|
|
// the header. Also fills in a table of contents
|
|
//
|
|
// Inputs :
|
|
// de = Documentation Entry
|
|
// sectnum = Section number
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects :
|
|
// Creates a new subsection. Updates HTML table of contents.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void HTML::newsection(DocEntry *de,int sectnum) {
|
|
int i,f;
|
|
char *c;
|
|
|
|
char *tag;
|
|
|
|
sect_num[sect_count] = sectnum;
|
|
sect_count++;
|
|
|
|
f = sect_count + 1;
|
|
if (f > 5) f = 5;
|
|
|
|
// Form table of contents
|
|
// if sect_count > last_section. We need to indent
|
|
// if sect_count < last_section. We need to pop out
|
|
|
|
if (sect_count > last_section) {
|
|
for (i = 0; i < sect_count - last_section; i++)
|
|
contents << "<UL>";
|
|
} else if (sect_count < last_section) {
|
|
for (i = 0; i < last_section - sect_count; i++)
|
|
contents << "</UL>";
|
|
}
|
|
|
|
last_section = sect_count;
|
|
contents << "<LI> <A HREF=\"#s";
|
|
|
|
s_doc << "<A name=\"s";
|
|
for (i = 0; i < sect_count; i++) {
|
|
s_doc << sect_num[i] << "_";
|
|
contents << sect_num[i] << "_";
|
|
}
|
|
|
|
contents << "\">";
|
|
|
|
// Figure out the tag fields
|
|
|
|
switch(f) {
|
|
case 1:
|
|
tag = tag_title;
|
|
break;
|
|
case 2:
|
|
tag = tag_section;
|
|
break;
|
|
case 3:
|
|
tag = tag_subsection;
|
|
break;
|
|
case 4:
|
|
tag = tag_subsubsection;
|
|
break;
|
|
default:
|
|
tag = tag_subsubsection;
|
|
}
|
|
|
|
s_doc << "\">\n"
|
|
<< start_tag(tag);
|
|
|
|
for (i = 0; i < sect_count; i++) {
|
|
s_doc << sect_num[i] << ".";
|
|
contents << sect_num[i] << ".";
|
|
}
|
|
c = de->usage.get();
|
|
s_doc << " ";
|
|
contents << " ";
|
|
print_string(c,s_doc,PRE);
|
|
print_string(c,contents,PRE);
|
|
s_doc << end_tag(tag) << "</A>\n";
|
|
contents << "</A>\n";
|
|
|
|
if (!de->format)
|
|
s_doc << start_tag(tag_preformat);
|
|
|
|
// If there is any C annotation, print that
|
|
if (de->print_info) {
|
|
c = de->cinfo.get();
|
|
if (strlen(c) > 0) {
|
|
s_doc << start_tag(tag_cinfo) << "[ ";
|
|
print_string(c,s_doc,de->format);
|
|
s_doc << " ]" << end_tag(tag_cinfo);
|
|
if (de->format)
|
|
s_doc << "<BR>\n";
|
|
else
|
|
s_doc << "\n";
|
|
}
|
|
}
|
|
|
|
// If there is a description text. Print it
|
|
|
|
c = de->text.get();
|
|
if (strlen(c) > 0) {
|
|
print_string(c,s_doc,de->format);
|
|
s_doc << "\n";
|
|
}
|
|
if (!de->format)
|
|
s_doc << end_tag(tag_preformat) << "\n";
|
|
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void HTML::endsection()
|
|
//
|
|
// Ends a subsection. It is an error to call this without first calling
|
|
// newsection previously.
|
|
//
|
|
// Inputs : None
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : Closes current section and goes back to parent.
|
|
//
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void HTML::endsection() {
|
|
if (sect_count > 0) sect_count--;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void HTML::separator()
|
|
//
|
|
// Prints a separator after the declaration of a C++ class. Currently
|
|
// does nothing in HTML mode.
|
|
//
|
|
// Inputs : None
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : None
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void HTML::separator() {
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void HTML::init(char *filename)
|
|
//
|
|
// Initializes the HTML module and opens up the documentation file.
|
|
//
|
|
// Inputs : filename = Name of documentation file (without a suffix)
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : Opens documentation file.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void HTML::init(char *filename) {
|
|
char f[256];
|
|
|
|
sprintf(f,"%s.html",filename);
|
|
f_doc = fopen(f,"w");
|
|
if (f_doc == NULL) {
|
|
fprintf(stderr,"Unable to open %s\n",f);
|
|
SWIG_exit(1);
|
|
}
|
|
/* Print a HTML banner */
|
|
fprintf(f_doc,"<HTML>\n");
|
|
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void HTML::close(void)
|
|
//
|
|
// Dumps the table of contents and forms the final documentation file. Closes
|
|
// the documentation file upon completion.
|
|
//
|
|
// Inputs : None
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : Closes documentation file.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void HTML::close(void) {
|
|
|
|
int i;
|
|
for (i = 0; i < last_section; i++)
|
|
contents << "</UL>\n";
|
|
|
|
fprintf(f_doc,"%s\n",s_title.get());
|
|
if (last_section) {
|
|
fprintf(f_doc,"%s Contents %s\n",start_tag(tag_contents),end_tag(tag_contents));
|
|
fprintf(f_doc,"%s\n",contents.get());
|
|
}
|
|
fprintf(f_doc,"%s\n",s_doc.get());
|
|
fprintf(f_doc,"%s\n", end_tag(tag_body));
|
|
fprintf(f_doc,"</HTML>\n");
|
|
fclose(f_doc);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void HTML::style(char *name, char *value)
|
|
//
|
|
// Process parameters given with the %style directive. Does nothing if an
|
|
// unrecognized parameter is given.
|
|
//
|
|
// Inputs :
|
|
// name = name of style parameter
|
|
// value = ASCII string with value of parameter.
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : Updates internal style parameters.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void HTML::style(char *name, char *value) {
|
|
if (strcmp(name,"html_title") == 0) {
|
|
if (value)
|
|
tag_title = copy_string(value);
|
|
} else if (strcmp(name,"html_contents") == 0) {
|
|
if (value)
|
|
tag_contents = copy_string(value);
|
|
} else if (strcmp(name,"html_section") == 0) {
|
|
if (value)
|
|
tag_section = copy_string(value);
|
|
} else if (strcmp(name,"html_subsection") == 0) {
|
|
if (value)
|
|
tag_subsection = copy_string(value);
|
|
} else if (strcmp(name,"html_subsubsection") == 0) {
|
|
if (value)
|
|
tag_subsubsection = copy_string(value);
|
|
} else if (strcmp(name,"html_usage") == 0) {
|
|
if (value)
|
|
tag_usage = copy_string(value);
|
|
} else if (strcmp(name,"html_descrip") == 0) {
|
|
if (value)
|
|
tag_descrip = copy_string(value);
|
|
} else if (strcmp(name,"html_text") == 0) {
|
|
if (value)
|
|
tag_text = copy_string(value);
|
|
} else if (strcmp(name,"html_cinfo") == 0) {
|
|
if (value)
|
|
tag_cinfo = copy_string(value);
|
|
} else if (strcmp(name,"html_preformat") == 0) {
|
|
if (value)
|
|
tag_preformat = copy_string(value);
|
|
} else if (strcmp(name,"html_body") == 0) {
|
|
if (value)
|
|
tag_body = copy_string(value);
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void HTML::parse_args(int argc, char **argv)
|
|
//
|
|
// Parse command line options given on the SWIG command line.
|
|
//
|
|
// Inputs :
|
|
// argc = argument count
|
|
// argv = argument array
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : Marks arguments as being parsed.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
static char *html_usage = "\
|
|
HTML Documentation Options (available with -dhtml)\n\
|
|
None available.\n\n";
|
|
|
|
void HTML::parse_args(int argc, char **argv) {
|
|
int i;
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
if (argv[i]) {
|
|
if (strcmp(argv[i],"-help") == 0) {
|
|
fputs(html_usage,stderr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|