    1    | /***************************************
    2    |   $Header: /home/amb/cxref/RCS/comment.c 1.20 1998/12/22 14:26:26 amb Exp $
    3    |
    4    |   C Cross Referencing & Documentation tool. Version 1.5.
    5    |
    6    |   Collects the comments from the parser.
    7    |   ******************/ /******************
    8    |   Written by Andrew M. Bishop
    9    |
    10   |   This file Copyright 1995,96,97,98 Andrew M. Bishop
    11   |   It may be distributed under the GNU Public License, version 2, or
    12   |   any higher version.  See section COPYING of the GNU Public license
    13   |   for conditions under which this file may be redistributed.
    14   |   ***************************************/
    15   |
    16   | /*+ Turn on the debugging in this file. +*/
    17   | #define DEBUG 0
    18   |
    19   | #include <stdlib.h>
    20   | #include <stdio.h>
    21   | #include <string.h>
    22   |
    23   | #include "memory.h"
    24   | #include "datatype.h"
    25   | #include "cxref.h"
    26   |
    27   | static void TidyCommentString(char **string,int spaces);
    28   |
    29   | /*+ The option to insert the comments verbatim into the output. +*/
    30   | extern int option_verbatim_comments;
    31   |
    32   | /*+ The file that is currently being processed. +*/
    33   | extern File CurFile;
    34   |
    35   | /*+ The name of the current file. +*/
    36   | extern char* parse_file;
    37   |
    38   | /*+ The current (latest) comment. +*/
    39   | static char* current_comment=NULL;
    40   |
    41   | /*+ The malloced string for the current comment. +*/
    42   | static char* malloc_comment=NULL;
    43   |
    44   | /*+ The status of the current comment. +*/
    45   | static int comment_ended=0;
    46   |
    47   |
    48   | /*++++++++++++++++++++++++++++++++++++++
    49   |   Function that is called when a comment or part of one is seen. The comment is built up until an end of comment is signaled.
    50   |
    51   |   char* c The comment text. If c==0 then it is a file (/ * * comment * * /) comment
    52   |                             if c==1 then it is the other special comment (/ * + comment + * /).
    53   |                             if c==2 then it is a normal comment (/ * comment * /).
    54   |                             if c==3 then it is not a comment.
    55   |   ++++++++++++++++++++++++++++++++++++++*/
    56   |
    57   | void SeenComment(char* c)
    58   | {
    59   |  switch((int)c)
    60   |    {
    61   |    case 0:
    62   | #if DEBUG
    63   |     printf("#Comment.c# Seen comment /**\n%s\n**/\n",current_comment);
    64   | #endif
    65   |     TidyCommentString(&current_comment,0);
    66   |     if(!CurFile->comment && !strcmp(CurFile->name,parse_file))
    67   |        SeenFileComment(current_comment);
    68   |     current_comment=NULL;
    69   |     if(malloc_comment) *malloc_comment=0;
    70   |     comment_ended=1;
    71   |     break;
    72   |
    73   |    case 1:
    74   | #if DEBUG
    75   |     printf("#Comment.c# Seen comment /*+\n%s\n+*/\n",current_comment);
    76   | #endif
    77   |     TidyCommentString(&current_comment,0);
    78   |     if(SeenFuncIntComment(current_comment))
    79   |       {
    80   |        current_comment=NULL;
    81   |        if(malloc_comment) *malloc_comment=0;
    82   |       }
    83   |     comment_ended=1;
    84   |     break;
    85   |
    86   |    case 2:
    87   | #if DEBUG
    88   |     printf("#Comment.c# Seen comment /*\n%s\n*/\n",current_comment);
    89   | #endif
    90   |     TidyCommentString(&current_comment,!option_verbatim_comments);
    91   |     if(!CurFile->comment && !strcmp(CurFile->name,parse_file))
    92   |       {
    93   |        SeenFileComment(current_comment);
    94   |        current_comment=NULL;
    95   |        if(malloc_comment) *malloc_comment=0;
    96   |       }
    97   |     comment_ended=1;
    98   |     break;
    99   |
    100  |    default:
    101  |     if(comment_ended)
    102  |       {
    103  |        comment_ended=0;
    104  |        current_comment=NULL;
    105  |        if(malloc_comment) *malloc_comment=0;
    106  |       }
    107  |
    108  |     if(malloc_comment==NULL)
    109  |       {
    110  |        malloc_comment=Malloc(strlen(c)+1);
    111  |        strcpy(malloc_comment,c);
    112  |       }
    113  |     else
    114  |       {
    115  |        malloc_comment=Realloc(malloc_comment,strlen(c)+strlen(malloc_comment)+1);
    116  |        strcat(malloc_comment,c);
    117  |       }
    118  |
    119  |     current_comment=malloc_comment;
    120  |    }
    121  | }
    122  |
    123  |
    124  | /*++++++++++++++++++++++++++++++++++++++
    125  |   Provide the current (latest) comment.
    126  |
    127  |   char* GetCurrentComment Returns the current (latest) comment.
    128  |   ++++++++++++++++++++++++++++++++++++++*/
    129  |
    130  | char* GetCurrentComment(void)
    131  | {
    132  |  char* comment=current_comment;
    133  |
    134  | #if DEBUG
    135  |  printf("#Comment.c# GetCurrentComment returns <<<%s>>>\n",comment);
    136  | #endif
    137  |
    138  |  current_comment=NULL;
    139  |
    140  |  return(comment);
    141  | }
    142  |
    143  |
    144  | /*++++++++++++++++++++++++++++++++++++++
    145  |   Set the current (latest) comment.
    146  |
    147  |   char* comment The comment.
    148  |   ++++++++++++++++++++++++++++++++++++++*/
    149  |
    150  | void SetCurrentComment(char* comment)
    151  | {
    152  | #if DEBUG
    153  |  printf("#Comment.c# SetCurrentComment set to <<<%s>>>\n",comment);
    154  | #endif
    155  |
    156  |  if(comment)
    157  |    {
    158  |     malloc_comment=Realloc(malloc_comment,strlen(comment)+1);
    159  |     strcpy(malloc_comment,comment);
    160  |     current_comment=malloc_comment;
    161  |    }
    162  |  else
    163  |    {
    164  |     current_comment=NULL;
    165  |     if(malloc_comment) *malloc_comment=0;
    166  |    }
    167  | }
    168  |
    169  |
    170  | /*++++++++++++++++++++++++++++++++++++++
    171  |   A function to split out the arguments etc from a comment,
    172  |   for example the function argument comments are separated using this.
    173  |
    174  |   char* SplitComment Returns the required comment.
    175  |
    176  |   char** original A pointer to the original comment, this is altered in the process.
    177  |
    178  |   char* name The name that is to be cut out from the comment.
    179  |
    180  |   A most clever function that ignores spaces so that 'char* b' and 'char *b' match.
    181  |   ++++++++++++++++++++++++++++++++++++++*/
    182  |
    183  | char* SplitComment(char** original,char* name)
    184  | {
    185  |  char* c=NULL;
    186  |
    187  |  if(*original)
    188  |    {
    189  |     int l=strlen(name);
    190  |     c=*original;
    191  |
    192  |     do{
    193  |        int i,j,failed=0;
    194  |        char* start=c;
    195  |
    196  |        while(c[0]=='\n')
    197  |           c++;
    198  |
    199  |        for(i=j=0;i<l;i++,j++)
    200  |          {
    201  |           while(name[i]==' ') i++;
    202  |           while(c[j]==' ') j++;
    203  |
    204  |           if(!c[j] || name[i]!=c[j])
    205  |             {failed=1;break;}
    206  |          }
    207  |
    208  |        if(!failed)
    209  |          {
    210  |           char* old=*original;
    211  |           char* end=strstr(c,"\n\n");
    212  |           *start=0;
    213  |           if(end)
    214  |              *original=MallocString(ConcatStrings(2,*original,end));
    215  |           else
    216  |              if(start==*original)
    217  |                 *original=NULL;
    218  |              else
    219  |                 *original=MallocString(*original);
    220  |           if(end)
    221  |              *end=0;
    222  |
    223  |           if(end && &c[j+1]>=end)
    224  |              c=NULL;
    225  |           else
    226  |             {
    227  |              c=CopyString(&c[j+1]);
    228  |              TidyCommentString(&c,1);
    229  |              if(!*c)
    230  |                 c=NULL;
    231  |             }
    232  |
    233  |           Free(old);
    234  |           break;
    235  |          }
    236  |       }
    237  |     while((c=strstr(c,"\n\n")));
    238  |    }
    239  |
    240  |  return(c);
    241  | }
    242  |
    243  |
    244  | /*++++++++++++++++++++++++++++++++++++++
    245  |   Tidy up the current comment string by snipping off trailing and leading junk.
    246  |
    247  |   char **string The string that is to be tidied.
    248  |
    249  |   int spaces Indicates that leading and trailing whitespace are to be removed as well.
    250  |   ++++++++++++++++++++++++++++++++++++++*/
    251  |
    252  | static void TidyCommentString(char **string,int spaces)
    253  | {
    254  |  int whitespace;
    255  |  char *to=*string,*from=*string,*str;
    256  |
    257  |  if(!*string)
    258  |     return;
    259  |
    260  |  /* Remove CR characters. */
    261  |
    262  |  while(*from)
    263  |    {
    264  |     if(*from=='\r')
    265  |        from++;
    266  |     else
    267  |        *to++=*from++;
    268  |    }
    269  |  *to=0;
    270  |
    271  |  /* Remove leading blank lines. */
    272  |
    273  |  whitespace=1;
    274  |  str=*string;
    275  |  do
    276  |    {
    277  |     if(*str!='\n')
    278  |        do
    279  |          {
    280  |           if(*str!=' ' && *str!='\t')
    281  |              whitespace=0;
    282  |          }
    283  |        while(whitespace && *str && *++str!='\n');
    284  |
    285  |     if(whitespace)
    286  |        *string=++str;
    287  |     else if(spaces)
    288  |        *string=str;
    289  |    }
    290  |  while(whitespace);
    291  |
    292  |  /* Remove trailing blank lines. */
    293  |
    294  |  whitespace=1;
    295  |  str=*string+strlen(*string)-1;
    296  |  do
    297  |    {
    298  |     if(*str!='\n')
    299  |        do
    300  |          {
    301  |           if(*str!=' ' && *str!='\t')
    302  |              whitespace=0;
    303  |          }
    304  |        while(whitespace && str>*string && *--str!='\n');
    305  |
    306  |     if(whitespace)
    307  |        *str--=0;
    308  |     else if(spaces)
    309  |        *(str+1)=0;
    310  |    }
    311  |  while(whitespace);
    312  |
    313  |  /* Replace lines containing just whitespace with empty lines. */
    314  |
    315  |  str=*string;
    316  |  do
    317  |    {
    318  |     char *start;
    319  |
    320  |     whitespace=1;
    321  |
    322  |     while(*str=='\n')
    323  |        str++;
    324  |
    325  |     start=str;
    326  |
    327  |     while(*str && *++str!='\n')
    328  |        {
    329  |         if(*str!=' ' && *str!='\t')
    330  |            whitespace=0;
    331  |        }
    332  |
    333  |     if(whitespace)
    334  |       {
    335  |        char *copy=start;
    336  |
    337  |        while((*start++=*str++));
    338  |
    339  |        str=copy;
    340  |       }
    341  |    }
    342  |  while(*str);
    343  | }
    344  |
    345  |
    346  | /*++++++++++++++++++++++++++++++++++++++
    347  |   Delete the malloced string for the comment
    348  |   ++++++++++++++++++++++++++++++++++++++*/
    349  |
    350  | void DeleteComment(void)
    351  | {
    352  |  current_comment=NULL;
    353  |  if(malloc_comment)
    354  |     Free(malloc_comment);
    355  |  malloc_comment=NULL;
    356  |  comment_ended=0;
    357  | }