1 | /***************************************
2 | $Header: /home/amb/cxref/RCS/comment.c 1.21 1999/11/16 18:58:13 amb Exp $
3 |
4 | C Cross Referencing & Documentation tool. Version 1.5c.
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(¤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 |
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 | malloc_comment=Realloc(malloc_comment,strlen(comment)+1);
162 | strcpy(malloc_comment,comment);
163 | current_comment=malloc_comment;
164 | }
165 | else
166 | {
167 | current_comment=NULL;
168 | if(malloc_comment) *malloc_comment=0;
169 | }
170 | }
171 |
172 |
173 | /*++++++++++++++++++++++++++++++++++++++
174 | A function to split out the arguments etc from a comment,
175 | for example the function argument comments are separated using this.
176 |
177 | char* SplitComment Returns the required comment.
178 |
179 | char** original A pointer to the original comment, this is altered in the process.
180 |
181 | char* name The name that is to be cut out from the comment.
182 |
183 | A most clever function that ignores spaces so that 'char* b' and 'char *b' match.
184 | ++++++++++++++++++++++++++++++++++++++*/
185 |
186 | char* SplitComment(char** original,char* name)
187 | {
188 | char* c=NULL;
189 |
190 | if(*original)
191 | {
192 | int l=strlen(name);
193 | c=*original;
194 |
195 | do{
196 | int i,j,failed=0;
197 | char* start=c;
198 |
199 | while(c[0]=='\n')
200 | c++;
201 |
202 | for(i=j=0;i<l;i++,j++)
203 | {
204 | while(name[i]==' ') i++;
205 | while(c[j]==' ') j++;
206 |
207 | if(!c[j] || name[i]!=c[j])
208 | {failed=1;break;}
209 | }
210 |
211 | if(!failed)
212 | {
213 | char* old=*original;
214 | char* end=strstr(c,"\n\n");
215 | *start=0;
216 | if(end)
217 | *original=MallocString(ConcatStrings(2,*original,end));
218 | else
219 | if(start==*original)
220 | *original=NULL;
221 | else
222 | *original=MallocString(*original);
223 | if(end)
224 | *end=0;
225 |
226 | if(end && &c[j+1]>=end)
227 | c=NULL;
228 | else
229 | {
230 | c=CopyString(&c[j+1]);
231 | TidyCommentString(&c,1);
232 | if(!*c)
233 | c=NULL;
234 | }
235 |
236 | Free(old);
237 | break;
238 | }
239 | }
240 | while((c=strstr(c,"\n\n")));
241 | }
242 |
243 | return(c);
244 | }
245 |
246 |
247 | /*++++++++++++++++++++++++++++++++++++++
248 | Tidy up the current comment string by snipping off trailing and leading junk.
249 |
250 | char **string The string that is to be tidied.
251 |
252 | int spaces Indicates that leading and trailing whitespace are to be removed as well.
253 | ++++++++++++++++++++++++++++++++++++++*/
254 |
255 | static void TidyCommentString(char **string,int spaces)
256 | {
257 | int whitespace;
258 | char *to=*string,*from=*string,*str;
259 |
260 | if(!*string)
261 | return;
262 |
263 | /* Remove CR characters. */
264 |
265 | while(*from)
266 | {
267 | if(*from=='\r')
268 | from++;
269 | else
270 | *to++=*from++;
271 | }
272 | *to=0;
273 |
274 | /* Remove leading blank lines. */
275 |
276 | whitespace=1;
277 | str=*string;
278 | do
279 | {
280 | if(*str!='\n')
281 | do
282 | {
283 | if(*str!=' ' && *str!='\t')
284 | whitespace=0;
285 | }
286 | while(whitespace && *str && *++str!='\n');
287 |
288 | if(whitespace)
289 | *string=++str;
290 | else if(spaces)
291 | *string=str;
292 | }
293 | while(whitespace);
294 |
295 | /* Remove trailing blank lines. */
296 |
297 | whitespace=1;
298 | str=*string+strlen(*string)-1;
299 | do
300 | {
301 | if(*str!='\n')
302 | do
303 | {
304 | if(*str!=' ' && *str!='\t')
305 | whitespace=0;
306 | }
307 | while(whitespace && str>*string && *--str!='\n');
308 |
309 | if(whitespace)
310 | *str--=0;
311 | else if(spaces)
312 | *(str+1)=0;
313 | }
314 | while(whitespace);
315 |
316 | /* Replace lines containing just whitespace with empty lines. */
317 |
318 | str=*string;
319 | do
320 | {
321 | char *start;
322 |
323 | whitespace=1;
324 |
325 | while(*str=='\n')
326 | str++;
327 |
328 | start=str;
329 |
330 | while(*str && *++str!='\n')
331 | {
332 | if(*str!=' ' && *str!='\t')
333 | whitespace=0;
334 | }
335 |
336 | if(whitespace)
337 | {
338 | char *copy=start;
339 |
340 | while((*start++=*str++));
341 |
342 | str=copy;
343 | }
344 | }
345 | while(*str);
346 | }
347 |
348 |
349 | /*++++++++++++++++++++++++++++++++++++++
350 | Delete the malloced string for the comment
351 | ++++++++++++++++++++++++++++++++++++++*/
352 |
353 | void DeleteComment(void)
354 | {
355 | current_comment=NULL;
356 | if(malloc_comment)
357 | Free(malloc_comment);
358 | malloc_comment=NULL;
359 | comment_ended=0;
360 | }