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