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