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