Logo Search packages:      
Sourcecode: c2man version File versions  Download package

autodoc.c

/*
** $PROJECT:
**
** $VER: autodoc.c 2.2 (25.01.95)
**
** by
**
** Stefan Ruppert , Windthorststra_e 5 , 65439 Flvrsheim , GERMANY
**
** (C) Copyright 1995
** All Rights Reserved !
**
** $HISTORY:
**
** 25.01.95 : 002.002 : changed to patchlevel 33
** 22.01.95 : 000.001 : initial
*/

#include "c2man.h"
#include "manpage.h"
#include "output.h"
#include <ctype.h>

#ifdef DEBUG
#define D(x)  x
#else
#define D(x)
#endif

#define MAX_TAG      10

static const int linelength   = 79;
static const int tablength    =  4;
static const int indentlength =  4;

static int indent      = 4;
static int list_indent = 0;
static int column      = 0;
static int newline     = FALSE;
static int breakline   = FALSE;
static int see_also    = FALSE;
static int fileend     = FALSE;
static int acttable    = -1;
static int tablemaxtag[MAX_TAG];

void autodoc_format(text)
const char *text;
{
    if(see_also)
    {
       if(column + ((text) ? strlen(text) + 2 : 1) > linelength)
       {
           putchar('\n');
           newline = TRUE;
       }
    }

    if(newline)
    {
       int i;
       column = i = indent + list_indent;
       for(; i ; i--)
          putchar(' ');
       newline = FALSE;
    }
}

void autodoc_text(text)
const char *text;
{
    int br = 1;
    autodoc_format(text);

    if(!see_also || (br = strcmp(text,",\n")))
    {
        if(see_also < 2)
        {
           put_string(text);
           column += strlen(text);
        }
    } else if(!br)
    {
        column += 2;
        put_string(", ");
    }
}

void autodoc_char(c)
const int c;
{
    if(c != '\f')
    {
       autodoc_format(NULL);

       if(c == '\t')
       {
          int i = tablength - (column % tablength);
          column += i;
          for(; i ; i--)
             putchar(' ');
       } else
       {
          if(see_also)
          {
             if(c == '(')
                 see_also++;
             else if(c == ')')
                 see_also--;
          }

          putchar(c);
          column++;
       }

       if((newline = (c == '\n')))
           column = 0;
   }
}

void autodoc_comment() { }

void autodoc_header(firstpage, input_files, grouped, name, terse, section)
ManualPage *firstpage;
int input_files;
boolean grouped;
const char *name;
const char *terse;
const char *section;
{
    const char *basename = strrchr(firstpage->sourcefile, '/');
    int len;
    int spc;

    fileend = FALSE;

    if(basename && *basename == '/')
        basename++;

    len =  ((basename) ? strlen(basename) + 1 : 0) + strlen(name);
    spc  = linelength - 2 * len;

    see_also = FALSE;

    if(basename)
    {
       autodoc_text(basename);
       autodoc_char('/');
    }
    autodoc_text(name);

    if(spc > 0)
    {
      while(spc)
      {
         autodoc_char(' ');
         spc--;
      }
       if(basename)
       {
          autodoc_text(basename);
          autodoc_char('/');
       }
       autodoc_text(name);
    } else
    {
       const char *ptr = name;
       len = linelength - 1 - len;

       while(len)
       {
          if(basename && *basename)
          {
             autodoc_char(*basename);
             basename++;
          } else
          {
             if(ptr == name && basename)
                autodoc_char('/');
             else
             {
                autodoc_char(*ptr);
                ptr++;
             }
          }
          len--;
       }
    }

    put_string("\n");
}

void autodoc_dash()       { put_string("-"); }

void autodoc_section(name)
const char *name;
{
    D((fprintf(stderr,"section : %s\n",name)));
    newline = FALSE;
    see_also = FALSE;
    put_string("\n");
    if(!strcmp(name,"DESCRIPTION"))
       name = "FUNCTION";
    else if(!strcmp(name,"PARAMETERS"))
       name = "INPUTS";
    else if(!strcmp(name,"RETURNS"))
       name = "RESULT";
    else if(!strcmp(name,"SEE ALSO"))
       see_also = TRUE;

    put_string("    ");
    autodoc_text(name);
    indent = 8;
    list_indent = 0;
    autodoc_char('\n');
}

void autodoc_sub_section(name)
const char *name;
{
    autodoc_text(name);
    indent = 12;
}

void autodoc_break_line()
{
   breakline = TRUE;
}

void autodoc_blank_line()
{
    autodoc_char('\n');
}

void autodoc_code_start() {  }
void autodoc_code_end()   {  }

void autodoc_code(text)
const char *text;
{
    autodoc_text(text);
}

void autodoc_tag_entry_start()
{
    if(list_indent > 0)
    {
        autodoc_char('\n');
        list_indent -= indentlength;
    }
}
void autodoc_tag_entry_start_extra()
{
    if(list_indent > 0)
    {
        autodoc_char('\n');
        list_indent -= indentlength;
    }
}
void autodoc_tag_entry_end()
{
   list_indent += indentlength;
   autodoc_char('\n');
}
void autodoc_tag_entry_end_extra(text)
const char *text;
{
    put_string("\" \"\t(");
    autodoc_text(text);
    put_string(")\"\n");
    list_indent += indentlength;
}
        
void autodoc_table_start(longestag)
const char *longestag;
{
   if(acttable < MAX_TAG - 1)
   {
      acttable++;
      tablemaxtag[acttable] = strlen(longestag);
   }

   indent += indentlength;
   newline = TRUE;
}

void autodoc_table_entry(name, description)
const char *name;
const char *description;
{
    int i = tablemaxtag[acttable] - strlen(name) + 1;

    autodoc_code(name);
    while(i > 0)
    {
       putchar(' ');
       i--;
    }
    putchar('-');
    putchar(' ');

    if (description)
        output_comment(description);
    else
        autodoc_char('\n');
}

void autodoc_table_end()
{
    if(acttable > -1)
      acttable--;

    autodoc_char('\n');
    indent -= indentlength;
    if(list_indent > 0)
       list_indent -= indentlength;
}

void autodoc_indent()
{
    int i;
    for(i = indent + list_indent; i ; i--)
       autodoc_char(' ');
}

void autodoc_list_start()
{
   indent += indentlength;
   newline = TRUE;
}

void autodoc_list_entry(name)
const char *name;
{
    autodoc_code(name);
}

void autodoc_list_separator() { put_string(" ,"); }
void autodoc_list_end()   { autodoc_char('\n'); autodoc_table_end(); }

void autodoc_include(filename)
const char *filename;
{

}

void autodoc_terse_sep()
{
    autodoc_char(' ');
    autodoc_dash();
    autodoc_char(' ');
}

void autodoc_name(name)
const char *name;
{
   if(name)
      autodoc_text(name);
   else
      autodoc_section("NAME");
}

void autodoc_file_end()
{
   if(!fileend)
      putchar('\f');
   fileend = TRUE;
   newline = FALSE;
}

/* ideally, this should be made aware of embedded autodoc commands */
void autodoc_description(text)
const char *text;
{
    enum { TEXT, PERIOD, CAPITALISE } state = CAPITALISE;
    boolean new_line = TRUE;
    
    /* correct punctuation a bit as it goes out */
    for (;*text;text++)
    {
      int c = *text;

      if (new_line && (c == '-' || c == '*'))
      {
          output->break_line();
          state = CAPITALISE;
      }
      else if (c == '.')
          state = PERIOD;
      else if (isspace(c) && state == PERIOD)
          state = CAPITALISE;
      else if (isalnum(c))
      {   
          if (islower(c) && state == CAPITALISE)      c = toupper(c);
          state = TEXT;
      }
           
      output->character(c);
      new_line = c == '\n';
    }

    /* do a full stop if there wasn't one */
    if (state == TEXT)  output->character('.');
}

/* ideally, this should be made aware of embedded autodoc commands */
void
autodoc_returns(comment)
const char *comment;
{
    enum { TEXT, PERIOD, CAPITALISE } state = CAPITALISE;
    char lastchar = '\n';
    boolean tag_list_started = FALSE;

    /* for each line... */
    while (*comment)
    {
      boolean tagged = FALSE;

      {
          const char *c = comment;

          /* search along until the end of a word */
          while (*c && *c != ':' && !isspace(*c))
            c++;

          /* skip all spaces or tabs after the first word */
          while (*c && *c != '\n')
          {
            if (*c == '\t' || *c == ':')
            {
                tagged = TRUE;
                break;
            }
            else if (!isspace(*c))
                break;

            c++;
          }
      }

      /* is it tagged?; explicitly reject dot commands */
      if (tagged)
      {
          /* output lingering newline if necessary */
          if (lastchar != '\n')
          {
            if (state == TEXT && !ispunct(lastchar))  output->character('.');
            output->character(lastchar = '\n');
          }

          if (!tag_list_started)
          {
            output->tag_list_start();
            tag_list_started = TRUE;
          }

          /* output the taggy bit */
          output->tag_entry_start();
          while (*comment && *comment != ':' && !isspace(*comment))
            output->character(*comment++);
          output->tag_entry_end();

          /* skip any extra tabs or spaces */
          while (*comment == ':' || (isspace(*comment) && *comment != '\n'))
            comment++;

          state = CAPITALISE;
      }

      /* terminate the previous line if necessary */
      if (lastchar != '\n')   output->character(lastchar = '\n');

      /* correct punctuation a bit as the line goes out */
      for (;*comment && *comment != '\n'; comment++)
      {
          char c = *comment;

          if (c == '.')
            state = PERIOD;
          else if (isspace(c) && state == PERIOD)
            state = CAPITALISE;
          else if (isalnum(c))
          {   
            if (islower(c) && state == CAPITALISE && fixup_comments)
                c = toupper(c);
            state = TEXT;
          }

          output->character(lastchar = c);
      }

      /* if it ended in punctuation, just output the nl straight away. */
      if (ispunct(lastchar))
      {
          if (lastchar == '.')      state = CAPITALISE;
          output->character(lastchar = '\n');
      }

      if (*comment)     comment++;
    }

    /* output lingering newline if necessary */
    if (lastchar != '\n')
    {
      if (state == TEXT && !ispunct(lastchar) && fixup_comments)
          output->character('.');
      output->character('\n');
    }

    if (tag_list_started)
      output->tag_list_end();
}


struct Output autodoc_output =
{
    autodoc_comment,
    autodoc_header,
    autodoc_dash,
    autodoc_section,
    autodoc_sub_section,
    autodoc_break_line,
    autodoc_blank_line,
    autodoc_code_start,
    autodoc_code_end,
    autodoc_code,
    dummy,              /* autodoc_tag_list_start */
    dummy,              /* autodoc_tag_list_end */
    autodoc_tag_entry_start,
    autodoc_tag_entry_start_extra,
    autodoc_tag_entry_end,
    autodoc_tag_entry_end_extra,
    autodoc_table_start,
    autodoc_table_entry,
    autodoc_table_end,
    autodoc_indent,
    autodoc_list_start,
    autodoc_code,         /* autodoc_list_entry */
    autodoc_list_separator,
    autodoc_list_end,
    autodoc_include,
    autodoc_file_end,      /* autodoc_file_end */
    autodoc_text,
    autodoc_char,
    NULL,                  /* autodoc_parse_option */
    dummy,                 /* autodoc_print_options */
    autodoc_name,
    autodoc_terse_sep,
    autodoc_text,          /* autodoc_reference */
    autodoc_text,          /* autodoc_emphasized */
    autodoc_description,
    autodoc_returns
};


Generated by  Doxygen 1.6.0   Back to index