1 /***************************************
2 $Header: /home/amb/CVS/cxref/src/comment.c,v 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
SeenComment(char * c,int flag)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(¤t_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(¤t_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(¤t_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
GetCurrentComment(void)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
SetCurrentComment(char * comment)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
SplitComment(char ** original,char * name)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
TidyCommentString(char ** string,int spaces)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
DeleteComment(void)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 }
364