1    | /***************************************
2    |   $Header: /home/amb/cxref/src/RCS/comment.c 1.22 2003/01/17 19:07:56 amb Exp $
3    | 
4    |   C Cross Referencing & Documentation tool. Version 1.5e.
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.
52   | 
53   |   int flag A flag to indicate the type of comment that it is.
54   |            if flag==0 then it is a comment of some sort.
55   |            If flag==1 then it is the end of a file (/ * * comment * * /) comment
56   |            if flag==2 then it is the end of the other special comment (/ * + comment + * /).
57   |            if flag==3 then it is the end of a normal comment (/ * comment * /).
58   |   ++++++++++++++++++++++++++++++++++++++*/
59   | 
60   | void SeenComment(char* c,int flag)
61   | {
62   |  switch(flag)
63   |    {
64   |    case 1:
65   | #if DEBUG
66   |     printf("#Comment.c# Seen comment /**\n%s\n**/\n",current_comment);
67   | #endif
68   |     TidyCommentString(&current_comment,0);
69   |     if(!CurFile->comment && !strcmp(CurFile->name,parse_file))
70   |        SeenFileComment(current_comment);
71   |     current_comment=NULL;
72   |     if(malloc_comment) *malloc_comment=0;
73   |     comment_ended=1;
74   |     break;
75   | 
76   |    case 2:
77   | #if DEBUG
78   |     printf("#Comment.c# Seen comment /*+\n%s\n+*/\n",current_comment);
79   | #endif
80   |     TidyCommentString(&current_comment,0);
81   |     if(SeenFuncIntComment(current_comment))
82   |       {
83   |        current_comment=NULL;
84   |        if(malloc_comment) *malloc_comment=0;
85   |       }
86   |     comment_ended=1;
87   |     break;
88   | 
89   |    case 3:
90   | #if DEBUG
91   |     printf("#Comment.c# Seen comment /*\n%s\n*/\n",current_comment);
92   | #endif
93   |     TidyCommentString(&current_comment,!option_verbatim_comments);
94   |     if(!CurFile->comment && !strcmp(CurFile->name,parse_file))
95   |       {
96   |        SeenFileComment(current_comment);
97   |        current_comment=NULL;
98   |        if(malloc_comment) *malloc_comment=0;
99   |       }
100  |     comment_ended=1;
101  |     break;
102  | 
103  |    default:
104  |     if(comment_ended)
105  |       {
106  |        comment_ended=0;
107  |        current_comment=NULL;
108  |        if(malloc_comment) *malloc_comment=0;
109  |       }
110  | 
111  |     if(malloc_comment==NULL)
112  |       {
113  |        malloc_comment=Malloc(strlen(c)+1);
114  |        strcpy(malloc_comment,c);
115  |       }
116  |     else
117  |       {
118  |        malloc_comment=Realloc(malloc_comment,strlen(c)+strlen(malloc_comment)+1);
119  |        strcat(malloc_comment,c);
120  |       }
121  | 
122  |     current_comment=malloc_comment;
123  |    }
124  | }
125  | 
126  | 
127  | /*++++++++++++++++++++++++++++++++++++++
128  |   Provide the current (latest) comment.
129  | 
130  |   char* GetCurrentComment Returns the current (latest) comment.
131  |   ++++++++++++++++++++++++++++++++++++++*/
132  | 
133  | char* GetCurrentComment(void)
134  | {
135  |  char* comment=current_comment;
136  | 
137  | #if DEBUG
138  |  printf("#Comment.c# GetCurrentComment returns <<<%s>>>\n",comment);
139  | #endif
140  | 
141  |  current_comment=NULL;
142  | 
143  |  return(comment);
144  | }
145  | 
146  | 
147  | /*++++++++++++++++++++++++++++++++++++++
148  |   Set the current (latest) comment.
149  | 
150  |   char* comment The comment.
151  |   ++++++++++++++++++++++++++++++++++++++*/
152  | 
153  | void SetCurrentComment(char* comment)
154  | {
155  | #if DEBUG
156  |  printf("#Comment.c# SetCurrentComment set to <<<%s>>>\n",comment);
157  | #endif
158  | 
159  |  if(comment)
160  |    {
161  |     if(malloc_comment!=comment)
162  |       {
163  |        malloc_comment=Realloc(malloc_comment,strlen(comment)+1);
164  |        strcpy(malloc_comment,comment);
165  |       }
166  |     current_comment=malloc_comment;
167  |    }
168  |  else
169  |    {
170  |     current_comment=NULL;
171  |     if(malloc_comment) *malloc_comment=0;
172  |    }
173  | }
174  | 
175  | 
176  | /*++++++++++++++++++++++++++++++++++++++
177  |   A function to split out the arguments etc from a comment,
178  |   for example the function argument comments are separated using this.
179  | 
180  |   char* SplitComment Returns the required comment.
181  | 
182  |   char** original A pointer to the original comment, this is altered in the process.
183  | 
184  |   char* name The name that is to be cut out from the comment.
185  | 
186  |   A most clever function that ignores spaces so that 'char* b' and 'char *b' match.
187  |   ++++++++++++++++++++++++++++++++++++++*/
188  | 
189  | char* SplitComment(char** original,char* name)
190  | {
191  |  char* c=NULL;
192  | 
193  |  if(*original)
194  |    {
195  |     int l=strlen(name);
196  |     c=*original;
197  | 
198  |     do{
199  |        int i,j,failed=0;
200  |        char* start=c;
201  | 
202  |        while(c[0]=='\n')
203  |           c++;
204  | 
205  |        for(i=j=0;i<l;i++,j++)
206  |          {
207  |           while(name[i]==' ') i++;
208  |           while(c[j]==' ') j++;
209  | 
210  |           if(!c[j] || name[i]!=c[j])
211  |             {failed=1;break;}
212  |          }
213  | 
214  |        if(!failed)
215  |          {
216  |           char* old=*original;
217  |           char* end=strstr(c,"\n\n");
218  |           *start=0;
219  |           if(end)
220  |              *original=MallocString(ConcatStrings(2,*original,end));
221  |           else
222  |              if(start==*original)
223  |                 *original=NULL;
224  |              else
225  |                 *original=MallocString(*original);
226  |           if(end)
227  |              *end=0;
228  | 
229  |           if(end && &c[j+1]>=end)
230  |              c=NULL;
231  |           else
232  |             {
233  |              c=CopyString(&c[j+1]);
234  |              TidyCommentString(&c,1);
235  |              if(!*c)
236  |                 c=NULL;
237  |             }
238  | 
239  |           Free(old);
240  |           break;
241  |          }
242  |       }
243  |     while((c=strstr(c,"\n\n")));
244  |    }
245  | 
246  |  return(c);
247  | }
248  | 
249  | 
250  | /*++++++++++++++++++++++++++++++++++++++
251  |   Tidy up the current comment string by snipping off trailing and leading junk.
252  | 
253  |   char **string The string that is to be tidied.
254  | 
255  |   int spaces Indicates that leading and trailing whitespace are to be removed as well.
256  |   ++++++++++++++++++++++++++++++++++++++*/
257  | 
258  | static void TidyCommentString(char **string,int spaces)
259  | {
260  |  int whitespace;
261  |  char *to=*string,*from=*string,*str;
262  | 
263  |  if(!*string)
264  |     return;
265  | 
266  |  /* Remove CR characters. */
267  | 
268  |  while(*from)
269  |    {
270  |     if(*from=='\r')
271  |        from++;
272  |     else
273  |        *to++=*from++;
274  |    }
275  |  *to=0;
276  | 
277  |  /* Remove leading blank lines. */
278  | 
279  |  whitespace=1;
280  |  str=*string;
281  |  do
282  |    {
283  |     if(*str!='\n')
284  |        do
285  |          {
286  |           if(*str!=' ' && *str!='\t')
287  |              whitespace=0;
288  |          }
289  |        while(whitespace && *str && *++str!='\n');
290  | 
291  |     if(whitespace)
292  |        *string=++str;
293  |     else if(spaces)
294  |        *string=str;
295  |    }
296  |  while(whitespace);
297  | 
298  |  /* Remove trailing blank lines. */
299  | 
300  |  whitespace=1;
301  |  str=*string+strlen(*string)-1;
302  |  do
303  |    {
304  |     if(*str!='\n')
305  |        do
306  |          {
307  |           if(*str!=' ' && *str!='\t')
308  |              whitespace=0;
309  |          }
310  |        while(whitespace && str>*string && *--str!='\n');
311  | 
312  |     if(whitespace)
313  |        *str--=0;
314  |     else if(spaces)
315  |        *(str+1)=0;
316  |    }
317  |  while(whitespace);
318  | 
319  |  /* Replace lines containing just whitespace with empty lines. */
320  | 
321  |  str=*string;
322  |  do
323  |    {
324  |     char *start;
325  | 
326  |     whitespace=1;
327  | 
328  |     while(*str=='\n')
329  |        str++;
330  | 
331  |     start=str;
332  | 
333  |     while(*str && *++str!='\n')
334  |        {
335  |         if(*str!=' ' && *str!='\t')
336  |            whitespace=0;
337  |        }
338  | 
339  |     if(whitespace)
340  |       {
341  |        char *copy=start;
342  | 
343  |        while((*start++=*str++));
344  | 
345  |        str=copy;
346  |       }
347  |    }
348  |  while(*str);
349  | }
350  | 
351  | 
352  | /*++++++++++++++++++++++++++++++++++++++
353  |   Delete the malloced string for the comment
354  |   ++++++++++++++++++++++++++++++++++++++*/
355  | 
356  | void DeleteComment(void)
357  | {
358  |  current_comment=NULL;
359  |  if(malloc_comment)
360  |     Free(malloc_comment);
361  |  malloc_comment=NULL;
362  |  comment_ended=0;
363  | }