/******************************************************************************* * 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 = ":"; tag_title = "

:

"; tag_contents = "

:

"; tag_section = "

:

"; tag_subsection = "

:

"; tag_subsubsection = "

:

"; tag_usage = "

:"; tag_descrip = "

:
"; tag_text = "

"; tag_cinfo = ""; tag_preformat = "

:
"; } // ----------------------------------------------------------------------------- // char *HTML::start_tag(char *tag) // // Utility function for returning the first part of an HTML tag variable. // A tag must look like this : // // ":" // // The start tag for this would be "" // // 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 << "
"; } } 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 << "\n" << "\n"; print_string(c,s_title,PRE); s_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 << "
\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 << ""; } last_section = sect_count; 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) << "\n"; contents << "\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 << "
    \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,"\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 << "\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,"\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); } } } }