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(¤t_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(¤t_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(¤t_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 | }