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