1 | /*************************************** 2 | C Cross Referencing & Documentation tool. Version 1.6e. 3 | 4 | Writes the HTML output. 5 | ******************/ /****************** 6 | Written by Andrew M. Bishop 7 | 8 | This file Copyright 1995-2013 Andrew M. Bishop 9 | It may be distributed under the GNU Public License, version 2, or 10 | any higher version. See section COPYING of the GNU Public license 11 | for conditions under which this file may be redistributed. 12 | ***************************************/ 13 | 14 | #include <stdlib.h> 15 | #include <stdio.h> 16 | #include <string.h> 17 | #include <sys/types.h> 18 | #include <sys/stat.h> 19 | #include <unistd.h> 20 | 21 | #include "version.h" 22 | #include "memory.h" 23 | #include "datatype.h" 24 | #include "cxref.h" 25 | 26 | /*+ The file extension to use for the output files. +*/ 27 | #define HTML_FILE ".html" 28 | #define HTML_FILE_BACKUP ".html~" 29 | 30 | /*+ The file extension to use for the output source files. +*/ 31 | #define HTML_SRC_FILE ".src.html" 32 | 33 | /*+ The name of the output tex file that contains the appendix. +*/ 34 | #define HTML_APDX ".apdx" 35 | 36 | /*+ The comments are to be inserted verbatim. +*/ 37 | extern int option_verbatim_comments; 38 | 39 | /*+ The type of HTML output to produce. +*/ 40 | extern int option_html; 41 | 42 | /*+ The name of the directory for the output. +*/ 43 | extern char* option_odir; 44 | 45 | /*+ The base name of the file for the output. +*/ 46 | extern char* option_name; 47 | 48 | /*+ The information about the cxref run, +*/ 49 | extern char *run_command, /*+ the command line options. +*/ 50 | *run_cpp_command; /*+ the cpp command and options. +*/ 51 | 52 | /*+ The directories to go back to get to the base output directory. +*/ 53 | static char* goback=NULL; 54 | 55 | /*+ The built-in style sheet. +*/ 56 | extern char *html_cxref_style; 57 | 58 | /* Local functions */ 59 | 60 | static void WriteHTMLFilePart(File file); 61 | static void WriteHTMLInclude(Include inc); 62 | static void WriteHTMLSubInclude(Include inc,int depth); 63 | static void WriteHTMLDefine(Define def); 64 | static void WriteHTMLTypedef(Typedef type); 65 | static void WriteHTMLStructUnion(StructUnion su,int depth); 66 | static void WriteHTMLVariable(Variable var); 67 | static void WriteHTMLFunction(Function func); 68 | 69 | static void WriteHTMLDocument(char* name,int appendix); 70 | static void WriteHTMLPreamble(FILE* f,char* title,int sourcefile); 71 | static void WriteHTMLPostamble(FILE* f,int sourcefile); 72 | 73 | void WriteHTMLSource(char *name); 74 | 75 | static char* html(char* c,int verbatim); 76 | 77 | /*+ The output file for the HTML. +*/ 78 | static FILE* of; 79 | 80 | /*+ The name of the file. +*/ 81 | static char *filename; 82 | 83 | 84 | /*++++++++++++++++++++++++++++++++++++++ 85 | Write an html file for a complete File structure and all components. 86 | 87 | File file The File structure to output. 88 | ++++++++++++++++++++++++++++++++++++++*/ 89 | 90 | void WriteHTMLFile(File file) 91 | { 92 | char* ofile; 93 | int i; 94 | 95 | filename=file->name; 96 | 97 | /* Write the including file. */ 98 | 99 | goback=""; 100 | WriteHTMLDocument(file->name,0); 101 | 102 | /* Open the file */ 103 | 104 | ofile=ConcatStrings(4,option_odir,"/",file->name,HTML_FILE); 105 | 106 | of=fopen(ofile,"w"); 107 | if(!of) 108 | { 109 | struct stat stat_buf; 110 | int i,ofl=strlen(ofile); 111 | 112 | for(i=strlen(option_odir)+1;i<ofl;i++) 113 | if(ofile[i]=='/') 114 | { 115 | ofile[i]=0; 116 | if(stat(ofile,&stat_buf)) 117 | mkdir(ofile,S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); 118 | ofile[i]='/'; 119 | } 120 | 121 | of=fopen(ofile,"w"); 122 | } 123 | 124 | if(!of) 125 | {fprintf(stderr,"cxref: Failed to open the HTML output file '%s'\n",ofile);exit(1);} 126 | 127 | for(goback="",i=strlen(file->name);i>0;i--) 128 | if(file->name[i]=='/') 129 | goback=ConcatStrings(2,goback,"../"); 130 | 131 | /* Write out a header. */ 132 | 133 | WriteHTMLPreamble(of,ConcatStrings(5,"Cross reference for ",file->name," of ",option_name,"."),0); 134 | 135 | /*+ The file structure is broken into its components and they are each written out. +*/ 136 | 137 | WriteHTMLFilePart(file); 138 | 139 | if(file->includes) 140 | { 141 | Include inc =file->includes; 142 | fprintf(of,"\n<hr>\n<h2>Included Files</h2>\n\n"); 143 | do{ 144 | WriteHTMLInclude(inc); 145 | } 146 | while((inc=inc->next)); 147 | } 148 | 149 | if(file->defines) 150 | { 151 | Define def =file->defines; 152 | fprintf(of,"\n<hr>\n<h2>Preprocessor definitions</h2>\n\n"); 153 | do{ 154 | WriteHTMLDefine(def); 155 | } 156 | while((def=def->next)); 157 | } 158 | 159 | if(file->typedefs) 160 | { 161 | Typedef type=file->typedefs; 162 | do{ 163 | WriteHTMLTypedef(type); 164 | } 165 | while((type=type->next)); 166 | } 167 | 168 | if(file->variables) 169 | { 170 | int any_to_mention=0; 171 | Variable var=file->variables; 172 | 173 | do{ 174 | if(var->scope&(GLOBAL|LOCAL|EXTERNAL|EXTERN_F)) 175 | any_to_mention=1; 176 | } 177 | while((var=var->next)); 178 | 179 | if(any_to_mention) 180 | { 181 | int first_ext=1,first_local=1; 182 | Variable var=file->variables; 183 | do{ 184 | if(var->scope&GLOBAL) 185 | WriteHTMLVariable(var); 186 | } 187 | while((var=var->next)); 188 | var=file->variables; 189 | do{ 190 | if(var->scope&(EXTERNAL|EXTERN_F) && !(var->scope&GLOBAL)) 191 | { 192 | if(first_ext) 193 | {fprintf(of,"\n<hr>\n<h2>External Variables</h2>\n\n"); first_ext=0;} 194 | fprintf(of,"<p>\n"); 195 | WriteHTMLVariable(var); 196 | } 197 | } 198 | while((var=var->next)); 199 | var=file->variables; 200 | do{ 201 | if(var->scope&LOCAL) 202 | { 203 | if(first_local) 204 | {fprintf(of,"\n<hr>\n<h2>Local Variables</h2>\n\n"); first_local=0;} 205 | fprintf(of,"<p>\n"); 206 | WriteHTMLVariable(var); 207 | } 208 | } 209 | while((var=var->next)); 210 | } 211 | } 212 | 213 | if(file->functions) 214 | { 215 | Function func=file->functions; 216 | do{ 217 | if(func->scope&(GLOBAL|EXTERNAL)) 218 | WriteHTMLFunction(func); 219 | } 220 | while((func=func->next)); 221 | func=file->functions; 222 | do{ 223 | if(func->scope&LOCAL) 224 | WriteHTMLFunction(func); 225 | } 226 | while((func=func->next)); 227 | } 228 | 229 | WriteHTMLPostamble(of,0); 230 | 231 | fclose(of); 232 | 233 | /* Write out the source file. */ 234 | 235 | if(option_html&16) 236 | WriteHTMLSource(file->name); 237 | 238 | /* Clear the memory in html() */ 239 | 240 | html(NULL,0); html(NULL,0); html(NULL,0); html(NULL,0); 241 | } 242 | 243 | 244 | /*++++++++++++++++++++++++++++++++++++++ 245 | Write a File structure out. 246 | 247 | File file The File to output. 248 | ++++++++++++++++++++++++++++++++++++++*/ 249 | 250 | static void WriteHTMLFilePart(File file) 251 | { 252 | int i; 253 | 254 | if(option_html&16) 255 | fprintf(of,"<h1><a name=\"file\" href=\"%s%s%s\">File %s</a></h1>\n\n",goback,file->name,HTML_SRC_FILE,html(file->name,0)); 256 | else 257 | fprintf(of,"<h1><a name=\"file\">File %s</a></h1>\n\n",html(file->name,0)); 258 | 259 | if(file->comment) 260 | { 261 | if(option_verbatim_comments) 262 | fprintf(of,"<pre>\n%s\n</pre>\n\n",html(file->comment,0)); 263 | else 264 | { 265 | char *rcs1=strstr(file->comment,"$Header"),*rcs2=NULL; 266 | if(rcs1) 267 | { 268 | rcs2=strstr(&rcs1[1],"$"); 269 | if(rcs2) 270 | { 271 | rcs2[0]=0; 272 | fprintf(of,"<p>\n<b>RCS %s</b>\n",html(&rcs1[1],0)); 273 | rcs2[0]='$'; 274 | } 275 | } 276 | if(rcs2) 277 | fprintf(of,"<p>\n<span class=\"cxref-file-comment\">%s</span>\n",html(&rcs2[2],0)); 278 | else 279 | fprintf(of,"<p>\n<span class=\"cxref-file-comment\">%s</span>\n",html(file->comment,0)); 280 | } 281 | } 282 | 283 | if(file->inc_in->n) 284 | { 285 | int i; 286 | 287 | fprintf(of,"<p>\n"); 288 | fprintf(of,"<table>\n"); 289 | for(i=0;i<file->inc_in->n;i++) 290 | { 291 | fprintf(of," <tr>\n"); 292 | if(i==0) 293 | fprintf(of," <td>Included in:\n"); 294 | else 295 | fprintf(of," <td> \n"); 296 | fprintf(of," <td><a href=\"%s%s"HTML_FILE"#file\">%s</a>\n",goback,file->inc_in->s[i],html(file->inc_in->s[i],0)); 297 | fprintf(of," </tr>\n"); 298 | } 299 | fprintf(of,"</table>\n"); 300 | } 301 | 302 | if(file->f_refs->n || file->v_refs->n) 303 | { 304 | fprintf(of,"<p>\n"); 305 | fprintf(of,"<table>\n"); 306 | } 307 | 308 | if(file->f_refs->n) 309 | { 310 | int others=0; 311 | 312 | fprintf(of," <tr>\n"); 313 | fprintf(of," <td>References Functions:\n"); 314 | 315 | for(i=0;i<file->f_refs->n;i++) 316 | if(file->f_refs->s2[i]) 317 | { 318 | if(i!=others) 319 | { 320 | fprintf(of," <tr>\n"); 321 | fprintf(of," <td> \n"); 322 | } 323 | fprintf(of," <td><a href=\"%s%s"HTML_FILE"#func-%s\">%s()</a>\n",goback,file->f_refs->s2[i],file->f_refs->s1[i],html(file->f_refs->s1[i],0)); 324 | fprintf(of," <td><a href=\"%s%s"HTML_FILE"#func-%s\">%s</a>\n",goback,file->f_refs->s2[i],file->f_refs->s1[i],html(file->f_refs->s2[i],0)); 325 | fprintf(of," </tr>\n"); 326 | } 327 | else 328 | others++; 329 | 330 | if(others) 331 | { 332 | if(i==others) 333 | fprintf(of," <td colspan=2><span class=\"cxref-reference-system\">"); 334 | else 335 | { 336 | fprintf(of," </tr>\n"); 337 | fprintf(of," <tr>\n"); 338 | fprintf(of," <td> \n"); 339 | fprintf(of," <td colspan=2><span class=\"cxref-reference-system\">"); 340 | } 341 | for(i=0;i<file->f_refs->n;i++) 342 | if(!file->f_refs->s2[i]) 343 | fprintf(of,--others?" %s(),":" %s()",html(file->f_refs->s1[i],0)); 344 | fprintf(of,"</span>\n"); 345 | fprintf(of," </tr>\n"); 346 | } 347 | } 348 | 349 | if(file->v_refs->n) 350 | { 351 | int others=0; 352 | 353 | fprintf(of," <tr>\n"); 354 | fprintf(of," <td>References Variables:\n"); 355 | 356 | for(i=0;i<file->v_refs->n;i++) 357 | if(file->v_refs->s2[i]) 358 | { 359 | if(i!=others) 360 | { 361 | fprintf(of," <tr>\n"); 362 | fprintf(of," <td> \n"); 363 | } 364 | fprintf(of," <td><a href=\"%s%s"HTML_FILE"#var-%s\">%s</a>\n",goback,file->v_refs->s2[i],file->v_refs->s1[i],html(file->v_refs->s1[i],0)); 365 | fprintf(of," <td><a href=\"%s%s"HTML_FILE"#var-%s\">%s</a>\n",goback,file->v_refs->s2[i],file->v_refs->s1[i],html(file->v_refs->s2[i],0)); 366 | fprintf(of," </tr>\n"); 367 | } 368 | else 369 | others++; 370 | 371 | if(others) 372 | { 373 | if(i==others) 374 | fprintf(of," <td colspan=2><span class=\"cxref-reference-system\">"); 375 | else 376 | { 377 | fprintf(of," </tr>\n"); 378 | fprintf(of," <tr>\n"); 379 | fprintf(of," <td> \n"); 380 | fprintf(of," <td colspan=2><span class=\"cxref-reference-system\">"); 381 | } 382 | for(i=0;i<file->v_refs->n;i++) 383 | if(!file->v_refs->s2[i]) 384 | fprintf(of,--others?" %s,":" %s",html(file->v_refs->s1[i],0)); 385 | fprintf(of,"</span>\n"); 386 | fprintf(of," </tr>\n"); 387 | } 388 | } 389 | 390 | if(file->f_refs->n || file->v_refs->n) 391 | fprintf(of,"</table>\n"); 392 | } 393 | 394 | 395 | /*++++++++++++++++++++++++++++++++++++++ 396 | Write an Include structure out. 397 | 398 | Include inc The Include structure to output. 399 | ++++++++++++++++++++++++++++++++++++++*/ 400 | 401 | static void WriteHTMLInclude(Include inc) 402 | { 403 | if(inc->comment) 404 | fprintf(of,"<p>\n<span class=\"cxref-include-comment\">%s</span>\n<p>\n",html(inc->comment,0)); 405 | 406 | fprintf(of,"<ul class=\"cxref-include\">\n"); 407 | 408 | if(inc->scope==LOCAL) 409 | fprintf(of," <li class=\"cxref-include-local\"><tt><span class=\"cxref-include-local\"><a href=\"%s%s"HTML_FILE"#file\">#include \"%s\"</a></span></tt>\n",goback,inc->name,html(inc->name,0)); 410 | else 411 | fprintf(of," <li class=\"cxref-include-system\"><tt><span class=\"cxref-include-system\">#include <%s></span></tt>\n",html(inc->name,0)); 412 | 413 | if(inc->includes) 414 | WriteHTMLSubInclude(inc->includes,1); 415 | 416 | fprintf(of,"</ul>\n"); 417 | } 418 | 419 | 420 | /*++++++++++++++++++++++++++++++++++++++ 421 | Write an Sub Include structure out. (An include structure that is included from another file.) 422 | 423 | Include inc The Include structure to output. 424 | 425 | int depth The depth of the include hierarchy. 426 | ++++++++++++++++++++++++++++++++++++++*/ 427 | 428 | static void WriteHTMLSubInclude(Include inc,int depth) 429 | { 430 | int i; 431 | 432 | for(i=0;i<depth;i++) 433 | fprintf(of," "); 434 | fprintf(of,"<ul class=\"cxref-include\">\n"); 435 | 436 | while(inc) 437 | { 438 | for(i=0;i<depth;i++) 439 | fprintf(of," "); 440 | if(inc->scope==LOCAL) 441 | fprintf(of," <li class=\"cxref-include-local\"><tt><span class=\"cxref-include-local\"><a href=\"%s%s"HTML_FILE"#file\">#include \"%s\"</a></span></tt>\n",goback,inc->name,html(inc->name,0)); 442 | else 443 | fprintf(of," <li class=\"cxref-include-system\"><tt><span class=\"cxref-include-system\">#include <%s></span></tt>\n",html(inc->name,0)); 444 | 445 | if(inc->includes) 446 | WriteHTMLSubInclude(inc->includes,depth+1); 447 | 448 | inc=inc->next; 449 | } 450 | 451 | for(i=0;i<depth;i++) 452 | fprintf(of," "); 453 | fprintf(of,"</ul>\n"); 454 | } 455 | 456 | 457 | /*++++++++++++++++++++++++++++++++++++++ 458 | Write a Define structure out. 459 | 460 | Define def The Define structure to output. 461 | ++++++++++++++++++++++++++++++++++++++*/ 462 | 463 | static void WriteHTMLDefine(Define def) 464 | { 465 | int i; 466 | int pargs=0; 467 | 468 | if(def->comment) 469 | fprintf(of,"<p>\n<span class=\"cxref-define-comment\">%s</span>\n",html(def->comment,0)); 470 | 471 | if(option_html&16) 472 | fprintf(of,"<p>\n<tt><span class=\"cxref-define\"><a href=\"%s%s%s#line%d\">#define %s</a>",goback,filename,HTML_SRC_FILE,def->lineno,html(def->name,0)); 473 | else 474 | fprintf(of,"<p>\n<tt><span class=\"cxref-define\">#define %s",html(def->name,0)); 475 | 476 | if(def->value) 477 | fprintf(of," %s",html(def->value,0)); 478 | 479 | if(def->args->n) 480 | { 481 | fprintf(of,"( "); 482 | for(i=0;i<def->args->n;i++) 483 | fprintf(of,i?", %s":"%s",html(def->args->s1[i],0)); 484 | fprintf(of," )"); 485 | } 486 | fprintf(of,"</span></tt>\n"); 487 | 488 | for(i=0;i<def->args->n;i++) 489 | if(def->args->s2[i]) 490 | pargs=1; 491 | 492 | if(pargs) 493 | { 494 | fprintf(of,"<br>\n"); 495 | fprintf(of,"<dl>\n"); 496 | for(i=0;i<def->args->n;i++) 497 | { 498 | fprintf(of," <dt><tt><span class=\"cxref-define\">%s</span></tt>\n",html(def->args->s1[i],0)); 499 | fprintf(of," <dd><span class=\"cxref-define-comment\">%s</span>\n",def->args->s2[i]?html(def->args->s2[i],0):""); 500 | } 501 | fprintf(of,"</dl>\n"); 502 | } 503 | } 504 | 505 | 506 | /*++++++++++++++++++++++++++++++++++++++ 507 | Write a Typedef structure out. 508 | 509 | Typedef type The Typedef structure to output. 510 | ++++++++++++++++++++++++++++++++++++++*/ 511 | 512 | static void WriteHTMLTypedef(Typedef type) 513 | { 514 | fprintf(of,"\n<hr>\n<h2>"); 515 | 516 | if(!strncmp("enum",type->name,4)) 517 | fprintf(of,"<a name=\"type-enum-%s\">",&type->name[5]); 518 | else if(!strncmp("union",type->name,5)) 519 | fprintf(of,"<a name=\"type-union-%s\">",&type->name[6]); 520 | else if(!strncmp("struct",type->name,6)) 521 | fprintf(of,"<a name=\"type-struct-%s\">",&type->name[7]); 522 | else 523 | fprintf(of,"<a name=\"type-%s\">",type->name); 524 | 525 | if(type->type) 526 | fprintf(of,"Typedef %s",html(type->name,0)); 527 | else 528 | fprintf(of,"Type %s",html(type->name,0)); 529 | 530 | fprintf(of,"</a></h2>\n\n"); 531 | 532 | if(type->comment) 533 | fprintf(of,"<p>\n<span class=\"cxref-type-comment\">%s</span>\n",html(type->comment,0)); 534 | 535 | if(type->type) 536 | { 537 | if(option_html&16) 538 | fprintf(of,"<p>\n<tt><span class=\"cxref-type\"><a href=\"%s%s%s#line%d\">typedef %s</a></span></tt>\n",goback,filename,HTML_SRC_FILE,type->lineno,html(type->type,0)); 539 | else 540 | fprintf(of,"<p>\n<tt><span class=\"cxref-type\">typedef %s</span></tt>\n",html(type->type,0)); 541 | } 542 | else if(type->sutype) 543 | { 544 | if(option_html&16) 545 | fprintf(of,"<br>\n<tt><span class=\"cxref-type\"><a href=\"%s%s%s#line%d\">%s</a></span></tt>\n",goback,filename,HTML_SRC_FILE,type->lineno,html(type->sutype->name,0)); 546 | else 547 | fprintf(of,"<br>\n<tt><span class=\"cxref-type\">%s</span></tt>\n",html(type->sutype->name,0)); 548 | } 549 | 550 | if(type->sutype) 551 | { 552 | fprintf(of,"<br>\n"); 553 | fprintf(of,"<table>\n"); 554 | WriteHTMLStructUnion(type->sutype,0); 555 | fprintf(of,"</table>\n"); 556 | } 557 | else 558 | if(type->typexref) 559 | { 560 | fprintf(of,"<br>\n"); 561 | fprintf(of,"<table>\n"); 562 | fprintf(of," <tr>\n"); 563 | fprintf(of," <td>See:\n"); 564 | if(type->typexref->type) 565 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"#type-%s\">Typedef %s</a></span>\n",type->typexref->name,html(type->typexref->name,0)); 566 | else if(!strncmp("enum",type->typexref->name,4)) 567 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"#type-enum-%s\">Type %s</a></span>\n",&type->typexref->name[5],html(type->typexref->name,0)); 568 | else if(!strncmp("union",type->typexref->name,5)) 569 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"#type-union-%s\">Type %s</a></span>\n",&type->typexref->name[6],html(type->typexref->name,0)); 570 | else if(!strncmp("struct",type->typexref->name,6)) 571 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"#type-struct-%s\">Type %s</a></span>\n",&type->typexref->name[7],html(type->typexref->name,0)); 572 | fprintf(of," </tr>\n"); 573 | fprintf(of,"</table>\n"); 574 | } 575 | } 576 | 577 | 578 | /*++++++++++++++++++++++++++++++++++++++ 579 | Write a structure / union structure out. 580 | 581 | StructUnion su The structure / union to write. 582 | 583 | int depth The current depth within the structure. 584 | ++++++++++++++++++++++++++++++++++++++*/ 585 | 586 | static void WriteHTMLStructUnion(StructUnion su, int depth) 587 | { 588 | int i; 589 | char* splitsu=NULL; 590 | 591 | splitsu=strstr(su->name,"{...}"); 592 | if(splitsu) splitsu[-1]=0; 593 | 594 | fprintf(of," <tr>\n"); 595 | fprintf(of," <td>"); 596 | for(i=0;i<depth;i++) 597 | fprintf(of," \n"); 598 | if(!depth || su->comps) 599 | fprintf(of,"<tt><span class=\"cxref-type\">%s</span></tt>\n",html(su->name,0)); 600 | else 601 | fprintf(of,"<tt><span class=\"cxref-type\">%s;</span></tt>\n",html(su->name,0)); 602 | fprintf(of," <td>"); 603 | if(depth && su->comment && !su->comps) 604 | fprintf(of,"<span class=\"cxref-type-comment\">%s</span>\n",html(su->comment,0)); 605 | else 606 | fprintf(of," \n"); 607 | fprintf(of," </tr>\n"); 608 | 609 | if(!depth || su->comps) 610 | { 611 | fprintf(of," <tr>\n"); 612 | fprintf(of," <td>"); 613 | for(i=0;i<depth;i++) 614 | fprintf(of," "); 615 | fprintf(of," <tt><span class=\"cxref-type\">{</span></tt>\n"); 616 | fprintf(of," <td> \n"); 617 | fprintf(of," </tr>\n"); 618 | 619 | for(i=0;i<su->n_comp;i++) 620 | WriteHTMLStructUnion(su->comps[i],depth+1); 621 | 622 | fprintf(of," <tr>\n"); 623 | fprintf(of," <td>"); 624 | for(i=0;i<depth;i++) 625 | fprintf(of," "); 626 | fprintf(of," <tt><span class=\"cxref-type\">}</span></tt>\n"); 627 | fprintf(of," <td> \n"); 628 | fprintf(of," </tr>\n"); 629 | 630 | if(splitsu) 631 | { 632 | fprintf(of," <tr>\n"); 633 | fprintf(of," <td>"); 634 | for(i=0;i<depth;i++) 635 | fprintf(of," "); 636 | fprintf(of,"<tt><span class=\"cxref-type\">%s;</span></tt>\n",splitsu[5]?html(&splitsu[6],0):""); 637 | if(depth && su->comment) 638 | fprintf(of," <td><span class=\"cxref-type-comment\">%s</span>\n",html(su->comment,0)); 639 | else 640 | fprintf(of," <td> \n"); 641 | fprintf(of," </tr>\n"); 642 | } 643 | } 644 | 645 | if(splitsu) splitsu[-1]=' '; 646 | } 647 | 648 | 649 | /*++++++++++++++++++++++++++++++++++++++ 650 | Write a Variable structure out. 651 | 652 | Variable var The Variable structure to output. 653 | ++++++++++++++++++++++++++++++++++++++*/ 654 | 655 | static void WriteHTMLVariable(Variable var) 656 | { 657 | int i; 658 | 659 | if(var->scope&GLOBAL) 660 | fprintf(of,"\n<hr>\n<h2><a name=\"var-%s\">Global Variable %s</a></h2>\n\n",var->name,html(var->name,0)); 661 | else 662 | fprintf(of,"<b><a name=\"var-%s\">%s</a></b><br>\n\n",var->name,html(var->name,0)); 663 | 664 | if(var->comment) 665 | fprintf(of,"<p>\n<span class=\"cxref-variable-comment\">%s</span>\n",html(var->comment,0)); 666 | 667 | if(option_html&16 && var->scope&(GLOBAL|LOCAL)) 668 | { 669 | if(var->incfrom) 670 | fprintf(of,"<p>\n<tt><span class=\"cxref-variable\"><a href=\"%s%s%s#line%d\">",goback,var->incfrom,HTML_SRC_FILE,var->lineno); 671 | else 672 | fprintf(of,"<p>\n<tt><span class=\"cxref-variable\"><a href=\"%s%s%s#line%d\">",goback,filename,HTML_SRC_FILE,var->lineno); 673 | } 674 | else 675 | fprintf(of,"<p>\n<tt><span class=\"cxref-variable\">"); 676 | 677 | if(var->scope&LOCAL) 678 | fprintf(of,"static "); 679 | else 680 | if(!(var->scope&GLOBAL) && var->scope&(EXTERNAL|EXTERN_F)) 681 | fprintf(of,"extern "); 682 | 683 | fprintf(of,"%s",html(var->type,0)); 684 | 685 | if(option_html&16 && var->scope&(GLOBAL|LOCAL)) 686 | fprintf(of,"</a></span></tt>\n"); 687 | else 688 | fprintf(of,"</span></tt>\n"); 689 | 690 | if(var->scope&(GLOBAL|LOCAL)) 691 | { 692 | if(var->incfrom || var->visible->n || var->used->n) 693 | { 694 | fprintf(of,"<br>\n"); 695 | fprintf(of,"<table>\n"); 696 | } 697 | 698 | if(var->incfrom) 699 | { 700 | fprintf(of," <tr>\n"); 701 | fprintf(of," <td>Included from\n"); 702 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#var-%s\">%s</a></span>\n",goback,var->incfrom,var->name,html(var->incfrom,0)); 703 | fprintf(of," </tr>\n"); 704 | } 705 | 706 | if(var->visible->n) 707 | { 708 | for(i=0;i<var->visible->n;i++) 709 | { 710 | if(i==0) 711 | { 712 | fprintf(of," <tr>\n"); 713 | fprintf(of," <td>Visible in:\n"); 714 | } 715 | else 716 | { 717 | fprintf(of," <tr>\n"); 718 | fprintf(of," <td> \n"); 719 | } 720 | if(var->visible->s1[i][0]=='$' && !var->visible->s1[i][1]) 721 | { 722 | fprintf(of," <td> \n"); 723 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#file\">%s</a></span>\n",goback,var->visible->s2[i],html(var->visible->s2[i],0)); 724 | } 725 | else 726 | { 727 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s()</a></span>\n",goback,var->visible->s2[i],var->visible->s1[i],html(var->visible->s1[i],0)); 728 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s</a></span>\n",goback,var->visible->s2[i],var->visible->s1[i],html(var->visible->s2[i],0)); 729 | } 730 | fprintf(of," </tr>\n"); 731 | } 732 | } 733 | 734 | if(var->used->n) 735 | { 736 | for(i=0;i<var->used->n;i++) 737 | { 738 | if(i==0) 739 | { 740 | fprintf(of," <tr>\n"); 741 | fprintf(of," <td>Used in:\n"); 742 | } 743 | else 744 | { 745 | fprintf(of," <tr>\n"); 746 | fprintf(of," <td> \n"); 747 | } 748 | if(var->used->s1[i][0]=='$' && !var->used->s1[i][1]) 749 | fprintf(of," <td> <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#file\">%s</a></span>\n",goback,var->used->s2[i],html(var->used->s2[i],0)); 750 | else 751 | { 752 | if(var->scope&LOCAL) 753 | { 754 | fprintf(of," <td><a href=\"#func-%s\">%s()</a>\n",var->used->s1[i],html(var->used->s1[i],0)); 755 | fprintf(of," <td> \n"); 756 | } 757 | else 758 | { 759 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s()</a></span>\n",goback,var->used->s2[i],var->used->s1[i],html(var->used->s1[i],0)); 760 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s</a></span>\n",goback,var->used->s2[i],var->used->s1[i],html(var->used->s2[i],0)); 761 | } 762 | } 763 | fprintf(of," </tr>\n"); 764 | } 765 | } 766 | 767 | if(var->incfrom || var->visible->n || var->used->n) 768 | fprintf(of,"</table>\n"); 769 | } 770 | else 771 | if(var->scope&(EXTERNAL|EXTERN_F) && var->defined) 772 | { 773 | fprintf(of,"<table>\n"); 774 | fprintf(of," <tr>\n"); 775 | fprintf(of," <td>Defined in:\n"); 776 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#var-%s\">%s</a></span>\n",goback,var->defined,html(var->name,0),var->defined); 777 | fprintf(of," </tr>\n"); 778 | fprintf(of,"</table>\n"); 779 | } 780 | } 781 | 782 | 783 | /*++++++++++++++++++++++++++++++++++++++ 784 | Write a Function structure out. 785 | 786 | Function func The Function structure to output. 787 | ++++++++++++++++++++++++++++++++++++++*/ 788 | 789 | static void WriteHTMLFunction(Function func) 790 | { 791 | int i,pret,pargs; 792 | char* comment2=NULL,*type; 793 | 794 | if(func->scope&(GLOBAL|EXTERNAL)) 795 | fprintf(of,"\n<hr>\n<h2><a name=\"func-%s\">Global Function %s()</a></h2>\n\n",func->name,html(func->name,0)); 796 | else 797 | fprintf(of,"\n<hr>\n<h2><a name=\"func-%s\">Local Function %s()</a></h2>\n\n",func->name,html(func->name,0)); 798 | 799 | if(func->comment) 800 | { 801 | if(option_verbatim_comments) 802 | fprintf(of,"<pre>\n%s\n</pre>\n\n",html(func->comment,0)); 803 | else 804 | { 805 | comment2=strstr(func->comment,"\n\n"); 806 | if(comment2) 807 | comment2[0]=0; 808 | fprintf(of,"<p>\n<span class=\"cxref-function-comment\">%s</span>\n",html(func->comment,0)); 809 | } 810 | } 811 | 812 | if(option_html&16) 813 | { 814 | if(func->incfrom) 815 | fprintf(of,"<p>\n<tt><span class=\"cxref-function\"><a href=\"%s%s%s#line%d\">",goback,func->incfrom,HTML_SRC_FILE,func->lineno); 816 | else 817 | fprintf(of,"<p>\n<tt><span class=\"cxref-function\"><a href=\"%s%s%s#line%d\">",goback,filename,HTML_SRC_FILE,func->lineno); 818 | } 819 | else 820 | fprintf(of,"<p>\n<tt><span class=\"cxref-function\">"); 821 | 822 | if(func->scope&LOCAL) 823 | fprintf(of,"static "); 824 | if(func->scope&INLINED) 825 | fprintf(of,"inline "); 826 | 827 | if((type=strstr(func->type,"()"))) 828 | type[0]=0; 829 | fprintf(of,"%s ( ",html(func->type,0)); 830 | 831 | for(i=0;i<func->args->n;i++) 832 | fprintf(of,i?", %s":"%s",html(func->args->s1[i],0)); 833 | 834 | if(type) 835 | {fprintf(of," %s",html(&type[1],0));type[0]='(';} 836 | else 837 | fprintf(of," )"); 838 | 839 | if(option_html&16) 840 | fprintf(of,"</a></span></tt>\n"); 841 | else 842 | fprintf(of,"</span></tt>\n"); 843 | 844 | pret =strncmp("void ",func->type,5) && func->cret; 845 | for(pargs=0,i=0;i<func->args->n;i++) 846 | pargs = pargs || ( strcmp("void",func->args->s1[i]) && func->args->s2[i] ); 847 | 848 | if(pret || pargs) 849 | { 850 | fprintf(of,"<br>\n"); 851 | fprintf(of,"<dl>\n"); 852 | if(pret) 853 | { 854 | fprintf(of," <dt><tt><span class=\"cxref-function\">%s</span></tt>\n",html(func->type,0)); 855 | fprintf(of," <dd><span class=\"cxref-function-comment\">%s</span>\n",func->cret?html(func->cret,0):" "); 856 | } 857 | if(pargs) 858 | for(i=0;i<func->args->n;i++) 859 | { 860 | fprintf(of," <dt><tt><span class=\"cxref-function\">%s</span></tt>\n",html(func->args->s1[i],0)); 861 | fprintf(of," <dd><span class=\"cxref-function-comment\">%s</span>\n",func->args->s2[i]?html(func->args->s2[i],0):" "); 862 | } 863 | fprintf(of,"</dl>\n"); 864 | } 865 | 866 | if(comment2) 867 | { 868 | fprintf(of,"<p>\n<span class=\"cxref-function-comment\">%s</span>\n",html(&comment2[2],0)); 869 | comment2[0]='\n'; 870 | } 871 | 872 | if(func->protofile || func->incfrom || func->calls->n || func->called->n || func->used->n || func->f_refs->n || func->v_refs->n) 873 | { 874 | fprintf(of,"<p>\n"); 875 | fprintf(of,"<table>\n"); 876 | } 877 | 878 | if(func->protofile) 879 | { 880 | fprintf(of," <tr>\n"); 881 | fprintf(of," <td>Prototyped in:\n"); 882 | fprintf(of," <td colspan=2><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#file\">%s</a></span>\n",goback,func->protofile,html(func->protofile,0)); 883 | fprintf(of," </tr>\n"); 884 | } 885 | 886 | if(func->incfrom) 887 | { 888 | fprintf(of," <tr>\n"); 889 | fprintf(of," <td>Included from:\n"); 890 | fprintf(of," <td colspan=2><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s</a></span>\n",goback,func->incfrom,func->name,html(func->incfrom,0)); 891 | fprintf(of," </tr>\n"); 892 | } 893 | 894 | if(func->calls->n) 895 | { 896 | int others=0; 897 | 898 | fprintf(of," <tr>\n"); 899 | fprintf(of," <td>Calls:\n"); 900 | 901 | for(i=0;i<func->calls->n;i++) 902 | if(func->calls->s2[i]) 903 | { 904 | if(i!=others) 905 | { 906 | fprintf(of," <tr>\n"); 907 | fprintf(of," <td> \n"); 908 | } 909 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s()</a></span>\n",goback,func->calls->s2[i],func->calls->s1[i],html(func->calls->s1[i],0)); 910 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s</a></span>\n",goback,func->calls->s2[i],func->calls->s1[i],html(func->calls->s2[i],0)); 911 | fprintf(of," </tr>\n"); 912 | } 913 | else 914 | others++; 915 | 916 | if(others) 917 | { 918 | if(i==others) 919 | fprintf(of," <td colspan=2><span class=\"cxref-reference-system\">"); 920 | else 921 | { 922 | fprintf(of," <tr>\n"); 923 | fprintf(of," <td> \n"); 924 | fprintf(of," <td colspan=2><span class=\"cxref-reference-system\">"); 925 | } 926 | for(i=0;i<func->calls->n;i++) 927 | if(!func->calls->s2[i]) 928 | fprintf(of,--others?"%s(), ":"%s()",html(func->calls->s1[i],0)); 929 | fprintf(of,"</span>\n"); 930 | fprintf(of," </tr>\n"); 931 | } 932 | } 933 | 934 | if(func->called->n) 935 | { 936 | fprintf(of," <tr>\n"); 937 | fprintf(of," <td>Called by:\n"); 938 | 939 | for(i=0;i<func->called->n;i++) 940 | { 941 | if(i!=0) 942 | { 943 | fprintf(of," <tr>\n"); 944 | fprintf(of," <td> \n"); 945 | } 946 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s()</a></span>\n",goback,func->called->s2[i],func->called->s1[i],html(func->called->s1[i],0)); 947 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s</a></span>\n",goback,func->called->s2[i],func->called->s1[i],html(func->called->s2[i],0)); 948 | fprintf(of," </tr>\n"); 949 | } 950 | } 951 | 952 | if(func->used->n) 953 | { 954 | fprintf(of," <tr>\n"); 955 | fprintf(of," <td>Used in:\n"); 956 | 957 | for(i=0;i<func->used->n;i++) 958 | { 959 | if(i!=0) 960 | { 961 | fprintf(of," <tr>\n"); 962 | fprintf(of," <td> \n"); 963 | } 964 | if(func->used->s1[i][0]=='$' && !func->used->s1[i][1]) 965 | { 966 | fprintf(of," <td> \n"); 967 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#file\">%s</a></span>\n",goback,func->used->s2[i],html(func->used->s2[i],0)); 968 | } 969 | else 970 | { 971 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s()</a></span>\n",goback,func->used->s2[i],func->used->s1[i],html(func->used->s1[i],0)); 972 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s</a></span>\n",goback,func->used->s2[i],func->used->s1[i],html(func->used->s2[i],0)); 973 | } 974 | fprintf(of," </tr>\n"); 975 | } 976 | } 977 | 978 | if(func->f_refs->n) 979 | { 980 | int others=0; 981 | 982 | fprintf(of," <tr>\n"); 983 | fprintf(of," <td>References Functions:\n"); 984 | 985 | for(i=0;i<func->f_refs->n;i++) 986 | if(func->f_refs->s2[i]) 987 | { 988 | if(i!=others) 989 | { 990 | fprintf(of," <tr>\n"); 991 | fprintf(of," <td> \n"); 992 | } 993 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s()</a></span>\n",goback,func->f_refs->s2[i],func->f_refs->s1[i],html(func->f_refs->s1[i],0)); 994 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#func-%s\">%s</a></span>\n",goback,func->f_refs->s2[i],func->f_refs->s1[i],html(func->f_refs->s2[i],0)); 995 | fprintf(of," </tr>\n"); 996 | } 997 | else 998 | others++; 999 | 1000 | if(others) 1001 | { 1002 | if(i==others) 1003 | fprintf(of," <td colspan=2><span class=\"cxref-reference-system\">"); 1004 | else 1005 | { 1006 | fprintf(of," <tr>\n"); 1007 | fprintf(of," <td> \n"); 1008 | fprintf(of," <td colspan=2><span class=\"cxref-reference-system\">"); 1009 | } 1010 | for(i=0;i<func->f_refs->n;i++) 1011 | if(!func->f_refs->s2[i]) 1012 | fprintf(of,--others?"%s(), ":"%s()",html(func->f_refs->s1[i],0)); 1013 | fprintf(of,"</span>\n"); 1014 | fprintf(of," </tr>\n"); 1015 | } 1016 | } 1017 | 1018 | if(func->v_refs->n) 1019 | { 1020 | int others=0; 1021 | 1022 | fprintf(of," <tr>\n"); 1023 | fprintf(of," <td>References Variables:\n"); 1024 | 1025 | for(i=0;i<func->v_refs->n;i++) 1026 | if(func->v_refs->s2[i]) 1027 | { 1028 | if(i!=others) 1029 | { 1030 | fprintf(of," <tr>\n"); 1031 | fprintf(of," <td> \n"); 1032 | } 1033 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#var-%s\">%s</a></span>\n",goback,func->v_refs->s2[i],func->v_refs->s1[i],html(func->v_refs->s1[i],0)); 1034 | fprintf(of," <td><span class=\"cxref-reference-local\"><a href=\"%s%s"HTML_FILE"#var-%s\">%s</a></span>\n",goback,func->v_refs->s2[i],func->v_refs->s1[i],html(func->v_refs->s2[i],0)); 1035 | fprintf(of," </tr>\n"); 1036 | } 1037 | else 1038 | others++; 1039 | 1040 | if(others) 1041 | { 1042 | if(i==others) 1043 | fprintf(of," <td colspan=2><span class=\"cxref-reference-system\">"); 1044 | else 1045 | { 1046 | fprintf(of," <tr>\n"); 1047 | fprintf(of," <td> \n"); 1048 | fprintf(of," <td colspan=2><span class=\"cxref-reference-system\">"); 1049 | } 1050 | for(i=0;i<func->v_refs->n;i++) 1051 | if(!func->v_refs->s2[i]) 1052 | fprintf(of,--others?"%s, ":"%s",html(func->v_refs->s1[i],0)); 1053 | fprintf(of,"</span>\n"); 1054 | fprintf(of," </tr>\n"); 1055 | } 1056 | } 1057 | 1058 | if(func->protofile || func->incfrom || func->calls->n || func->called->n || func->used->n || func->f_refs->n || func->v_refs->n) 1059 | fprintf(of,"</table>\n"); 1060 | } 1061 | 1062 | 1063 | /*++++++++++++++++++++++++++++++++++++++ 1064 | Write out a file that will include the current information. 1065 | 1066 | char* name The name of the file. 1067 | 1068 | int appendix set to non-zero if the appendix file is to be added, else a normal source file. 1069 | ++++++++++++++++++++++++++++++++++++++*/ 1070 | 1071 | static void WriteHTMLDocument(char* name,int appendix) 1072 | { 1073 | FILE *in,*out; 1074 | char line[256]; 1075 | int seen=0; 1076 | char *inc_file,*ofile,*ifile; 1077 | char *fname; 1078 | struct stat stat_buf; 1079 | 1080 | if(appendix) 1081 | inc_file=ConcatStrings(4,"<a href=\"",name,HTML_FILE,"\">Appendix</a><br>\n"); 1082 | else 1083 | inc_file=ConcatStrings(6,"<a href=\"",name,HTML_FILE,"#file\">",name,"</a><br>\n"); 1084 | ifile=ConcatStrings(4,option_odir,"/",option_name,HTML_FILE); 1085 | ofile=ConcatStrings(4,option_odir,"/",option_name,HTML_FILE_BACKUP); 1086 | 1087 | in=fopen(ifile,"r"); 1088 | if(!in) 1089 | { 1090 | in =fopen(ifile,"w"); 1091 | if(!in) 1092 | {fprintf(stderr,"cxref: Failed to open the main HTML output file '%s'\n",ifile);exit(1);} 1093 | 1094 | WriteHTMLPreamble(in,ConcatStrings(3,"Cross Reference Of ",option_name,"."),1); 1095 | WriteHTMLPostamble(in,1); 1096 | fclose(in); 1097 | 1098 | in =fopen(ifile,"r"); 1099 | } 1100 | 1101 | out=fopen(ofile,"w"); 1102 | 1103 | if(!out) 1104 | {fprintf(stderr,"cxref: Failed to open the main HTML output file '%s'\n",ofile);exit(1);} 1105 | 1106 | while(fgets(line,256,in)) 1107 | { 1108 | if(!strcmp(inc_file,line) || 1109 | (!strncmp("<!--",line,4) && !strncmp(inc_file,line+4,strlen(inc_file))) || 1110 | (!strncmp("<!-- ",line,5) && !strncmp(inc_file,line+5,strlen(inc_file)))) 1111 | {seen=1;break;} 1112 | if(line[0]=='<' && !strcmp("<!-- End-Of-Source-Files -->\n",line)) 1113 | { 1114 | if(appendix) 1115 | { 1116 | fputs(line,out); 1117 | fputs("\n",out); 1118 | fputs("<!-- Appendix -->\n",out); 1119 | fputs("\n",out); 1120 | fputs("<hr>\n",out); 1121 | fputs("<h1>Appendix</h1>\n",out); 1122 | fputs("\n",out); 1123 | fputs(inc_file,out); 1124 | } 1125 | else 1126 | { 1127 | fputs(inc_file,out); 1128 | fputs("\n",out); 1129 | fputs(line,out); 1130 | } 1131 | } 1132 | else 1133 | fputs(line,out); 1134 | } 1135 | 1136 | fclose(in); 1137 | fclose(out); 1138 | 1139 | if(!seen) 1140 | { 1141 | unlink(ifile); 1142 | rename(ofile,ifile); 1143 | } 1144 | else 1145 | unlink(ofile); 1146 | 1147 | /* Style file */ 1148 | 1149 | fname=ConcatStrings(2,option_odir,"/cxref.css"); 1150 | if(stat(fname,&stat_buf)) 1151 | { 1152 | FILE* file=fopen(fname,"w"); 1153 | if(!file) 1154 | {fprintf(stderr,"cxref: Cannot write the HTML style file '%s'\n",fname);exit(1);} 1155 | fputs(html_cxref_style,file); 1156 | fclose(file); 1157 | } 1158 | } 1159 | 1160 | 1161 | /*++++++++++++++++++++++++++++++++++++++ 1162 | Write out a standard pre-amble. 1163 | 1164 | FILE* f The file to write the pre amble to. 1165 | 1166 | char* title The title of the file. 1167 | 1168 | int sourcefile True if the Source-Files line is to be included. 1169 | ++++++++++++++++++++++++++++++++++++++*/ 1170 | 1171 | static void WriteHTMLPreamble(FILE* f,char* title,int sourcefile) 1172 | { 1173 | fputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n",f); 1174 | fputs("\n",f); 1175 | fputs("<!-- This HTML file generated by cxref (version " CXREF_VERSION "). -->\n",f); 1176 | fputs("<!-- cxref program " CXREF_COPYRIGHT ". -->\n",f); 1177 | fputs("\n",f); 1178 | if(!sourcefile) 1179 | { 1180 | fputs("<!--\n",f); 1181 | if(filename) 1182 | fprintf(f,"Cxref: %s %s\n",run_command,filename); 1183 | else 1184 | fprintf(f,"Cxref: %s\n",run_command); 1185 | fprintf(f,"CPP : %s\n",run_cpp_command); 1186 | fputs("-->\n",f); 1187 | fputs("\n",f); 1188 | } 1189 | fputs("<HTML>\n",f); 1190 | fputs("\n",f); 1191 | fputs("<HEAD>\n",f); 1192 | fprintf(f,"<TITLE>%s</TITLE>\n",title); 1193 | fprintf(f,"<LINK rel=\"stylesheet\" href=\"%scxref.css\" type=\"text/css\">\n",goback); 1194 | fputs("</HEAD>\n",f); 1195 | fputs("\n",f); 1196 | fputs("<BODY>\n",f); 1197 | fputs("\n",f); 1198 | if(sourcefile) 1199 | { 1200 | fputs("<h1>Source Files</h1>\n",f); 1201 | fputs("\n",f); 1202 | fputs("<!-- Begin-Of-Source-Files -->\n",f); 1203 | } 1204 | } 1205 | 1206 | 1207 | /*++++++++++++++++++++++++++++++++++++++ 1208 | Write out a standard post-amble. This includes the end of document marker. 1209 | 1210 | FILE* f The file to write the post amble to. 1211 | 1212 | int sourcefile True if the Source-Files line is to be included. 1213 | ++++++++++++++++++++++++++++++++++++++*/ 1214 | 1215 | static void WriteHTMLPostamble(FILE* f,int sourcefile) 1216 | { 1217 | if(sourcefile) 1218 | { 1219 | fputs("\n",f); 1220 | fputs("<!-- End-Of-Source-Files -->\n",f); 1221 | } 1222 | fputs("\n",f); 1223 | fputs("</BODY>\n",f); 1224 | fputs("</HTML>\n",f); 1225 | } 1226 | 1227 | 1228 | /*++++++++++++++++++++++++++++++++++++++ 1229 | Write out the appendix information. 1230 | 1231 | StringList files The list of files to write. 1232 | 1233 | StringList2 funcs The list of functions to write. 1234 | 1235 | StringList2 vars The list of variables to write. 1236 | 1237 | StringList2 types The list of types to write. 1238 | ++++++++++++++++++++++++++++++++++++++*/ 1239 | 1240 | void WriteHTMLAppendix(StringList files,StringList2 funcs,StringList2 vars,StringList2 types) 1241 | { 1242 | char* ofile; 1243 | int i; 1244 | 1245 | filename=NULL; 1246 | 1247 | /* Write the bits to the including file. */ 1248 | 1249 | goback=""; 1250 | WriteHTMLDocument(ConcatStrings(2,option_name,HTML_APDX),1); 1251 | 1252 | /* Open the file */ 1253 | 1254 | ofile=ConcatStrings(5,option_odir,"/",option_name,HTML_APDX,HTML_FILE); 1255 | 1256 | of=fopen(ofile,"w"); 1257 | 1258 | if(!of) 1259 | {fprintf(stderr,"cxref: Failed to open the HTML appendix file '%s'\n",ofile);exit(1);} 1260 | 1261 | /* Write the file structure out */ 1262 | 1263 | WriteHTMLPreamble(of,ConcatStrings(3,"Cross reference index of ",option_name,"."),0); 1264 | 1265 | fprintf(of,"<h1>Cross References</h1>\n\n"); 1266 | 1267 | if(files->n || funcs->n || vars->n || types->n) 1268 | { 1269 | fprintf(of,"<p>\n"); 1270 | fprintf(of,"<ul>\n"); 1271 | if(files->n) 1272 | fprintf(of," <li><a href=\"#files\">Files</a></li>\n"); 1273 | if(funcs->n) 1274 | fprintf(of," <li><a href=\"#functions\">Global Functions</a></li>\n"); 1275 | if(vars->n) 1276 | fprintf(of," <li><a href=\"#variables\">Global Variables</a></li>\n"); 1277 | if(types->n) 1278 | fprintf(of," <li><a href=\"#types\">Defined Types</a></li>\n"); 1279 | fprintf(of,"</ul>\n"); 1280 | } 1281 | 1282 | /* Write out the appendix of files. */ 1283 | 1284 | if(files->n) 1285 | { 1286 | fprintf(of,"\n<hr>\n<h2><a name=\"files\">Files</a></h2>\n\n"); 1287 | fprintf(of,"<p>\n"); 1288 | fprintf(of,"<ul>\n"); 1289 | for(i=0;i<files->n;i++) 1290 | fprintf(of," <li><a href=\"%s"HTML_FILE"#file\">%s</a></li>\n",files->s[i],html(files->s[i],0)); 1291 | fprintf(of,"</ul>\n"); 1292 | } 1293 | 1294 | /* Write out the appendix of functions. */ 1295 | 1296 | if(funcs->n) 1297 | { 1298 | fprintf(of,"\n<hr>\n<h2><a name=\"functions\">Global Functions</a></h2>\n\n"); 1299 | fprintf(of,"<p>\n"); 1300 | fprintf(of,"<ul>\n"); 1301 | for(i=0;i<funcs->n;i++) 1302 | fprintf(of," <li><a href=\"%s"HTML_FILE"#func-%s\">%s() : %s</a></li>\n",funcs->s2[i],funcs->s1[i],html(funcs->s1[i],0),html(funcs->s2[i],0)); 1303 | fprintf(of,"</ul>\n"); 1304 | } 1305 | 1306 | /* Write out the appendix of variables. */ 1307 | 1308 | if(vars->n) 1309 | { 1310 | fprintf(of,"\n<hr>\n<h2><a name=\"variables\">Global Variables</a></h2>\n\n"); 1311 | fprintf(of,"<p>\n"); 1312 | fprintf(of,"<ul>\n"); 1313 | for(i=0;i<vars->n;i++) 1314 | fprintf(of," <li><a href=\"%s"HTML_FILE"#var-%s\">%s : %s</a></li>\n",vars->s2[i],vars->s1[i],html(vars->s1[i],0),html(vars->s2[i],0)); 1315 | fprintf(of,"</ul>\n"); 1316 | } 1317 | 1318 | /* Write out the appendix of types. */ 1319 | 1320 | if(types->n) 1321 | { 1322 | fprintf(of,"\n<hr>\n<h2><a name=\"types\">Defined Types</a></h2>\n\n"); 1323 | fprintf(of,"<p>\n"); 1324 | fprintf(of,"<ul>\n"); 1325 | for(i=0;i<types->n;i++) 1326 | if(!strncmp("enum",types->s1[i],4)) 1327 | fprintf(of," <li><a href=\"%s"HTML_FILE"#type-enum-%s\">%s : %s</a></li>\n",types->s2[i],&types->s1[i][5],html(types->s1[i],0),html(types->s2[i],0)); 1328 | else if(!strncmp("union",types->s1[i],5)) 1329 | fprintf(of," <li><a href=\"%s"HTML_FILE"#type-union-%s\">%s : %s</a></li>\n",types->s2[i],&types->s1[i][6],html(types->s1[i],0),html(types->s2[i],0)); 1330 | else if(!strncmp("struct",types->s1[i],6)) 1331 | fprintf(of," <li><a href=\"%s"HTML_FILE"#type-struct-%s\">%s : %s</a></li>\n",types->s2[i],&types->s1[i][7],html(types->s1[i],0),html(types->s2[i],0)); 1332 | else 1333 | fprintf(of," <li><a href=\"%s"HTML_FILE"#type-%s\">%s : %s</a></li>\n",types->s2[i],types->s1[i],html(types->s1[i],0),html(types->s2[i],0)); 1334 | fprintf(of,"</ul>\n"); 1335 | } 1336 | 1337 | WriteHTMLPostamble(of,0); 1338 | 1339 | fclose(of); 1340 | 1341 | /* Clear the memory in html(,0) */ 1342 | 1343 | html(NULL,0); html(NULL,0); html(NULL,0); html(NULL,0); 1344 | } 1345 | 1346 | 1347 | /*++++++++++++++++++++++++++++++++++++++ 1348 | Delete the HTML file and main file reference that belong to the named file. 1349 | 1350 | char *name The name of the file to delete. 1351 | ++++++++++++++++++++++++++++++++++++++*/ 1352 | 1353 | void WriteHTMLFileDelete(char *name) 1354 | { 1355 | FILE *in,*out; 1356 | char line[256]; 1357 | int seen=0; 1358 | char *inc_file,*ofile,*ifile; 1359 | 1360 | ofile=ConcatStrings(4,option_odir,"/",name,HTML_FILE); 1361 | unlink(ofile); 1362 | 1363 | inc_file=ConcatStrings(6,"<a href=\"",name,HTML_FILE,"#file\">",name,"</a><br>\n"); 1364 | ifile=ConcatStrings(4,option_odir,"/",option_name,HTML_FILE); 1365 | ofile=ConcatStrings(4,option_odir,"/",option_name,HTML_FILE_BACKUP); 1366 | 1367 | in =fopen(ifile,"r"); 1368 | out=fopen(ofile,"w"); 1369 | 1370 | if(in && !out) 1371 | {fprintf(stderr,"cxref: Failed to open the main HTML output file '%s'\n",ofile);fclose(in);} 1372 | else if(in) 1373 | { 1374 | while(fgets(line,256,in)) 1375 | { 1376 | if(!strcmp(inc_file,line) || 1377 | (!strncmp("<!--",line,4) && !strncmp(inc_file,line+4,strlen(inc_file)-1)) || 1378 | (!strncmp("<!-- ",line,5) && !strncmp(inc_file,line+5,strlen(inc_file)-1))) 1379 | seen=1; 1380 | else 1381 | fputs(line,out); 1382 | } 1383 | 1384 | fclose(in); 1385 | fclose(out); 1386 | 1387 | if(seen) 1388 | { 1389 | unlink(ifile); 1390 | rename(ofile,ifile); 1391 | } 1392 | else 1393 | unlink(ofile); 1394 | } 1395 | else if(out) 1396 | { 1397 | fclose(out); 1398 | unlink(ofile); 1399 | } 1400 | } 1401 | 1402 | 1403 | /*++++++++++++++++++++++++++++++++++++++ 1404 | Write out the source file. 1405 | 1406 | char *name The name of the source file. 1407 | ++++++++++++++++++++++++++++++++++++++*/ 1408 | 1409 | void WriteHTMLSource(char *name) 1410 | { 1411 | FILE *in,*out; 1412 | char line[256]; 1413 | char *ofile,*ifile; 1414 | int lineno=0; 1415 | char pad[5]; 1416 | 1417 | ifile=name; 1418 | ofile=ConcatStrings(4,option_odir,"/",name,HTML_SRC_FILE); 1419 | 1420 | in =fopen(ifile,"r"); 1421 | if(!in) 1422 | {fprintf(stderr,"cxref: Failed to open the source file '%s'\n",ifile);exit(1);} 1423 | 1424 | out=fopen(ofile,"w"); 1425 | if(!out) 1426 | {fprintf(stderr,"cxref: Failed to open the HTML output source file '%s'\n",ofile);exit(1);} 1427 | 1428 | WriteHTMLPreamble(out,ConcatStrings(2,"Source File ",name),0); 1429 | fputs("<pre>\n",out); 1430 | 1431 | strcpy(pad," "); 1432 | 1433 | while(fgets(line,256,in)) 1434 | { 1435 | lineno++; 1436 | if(lineno==10) 1437 | pad[3]=0; 1438 | else if(lineno==100) 1439 | pad[2]=0; 1440 | else if(lineno==1000) 1441 | pad[1]=0; 1442 | else if(lineno==10000) 1443 | pad[0]=0; 1444 | fprintf(out,"<a name=\"line%d\">%d%s|</a> %s",lineno,lineno,pad,html(line,1)); 1445 | } 1446 | 1447 | fputs("</pre>\n",out); 1448 | WriteHTMLPostamble(out,0); 1449 | 1450 | fclose(in); 1451 | fclose(out); 1452 | } 1453 | 1454 | 1455 | /*++++++++++++++++++++++++++++++++++++++ 1456 | Make the input string safe to output as HTML ( not <, >, & or " ). 1457 | 1458 | char* html Returns a safe HTML string. 1459 | 1460 | char* c A non-safe HTML string. 1461 | 1462 | int verbatim Set to true if the text is to be output verbatim ignoring the comment +html+ directives. 1463 | 1464 | The function can only be called four times in each fprintf() since it returns one of only four static strings. 1465 | ++++++++++++++++++++++++++++++++++++++*/ 1466 | 1467 | static char* html(char* c,int verbatim) 1468 | { 1469 | static char safe[4][256],*malloced[4]={NULL,NULL,NULL,NULL}; 1470 | static int which=0; 1471 | int copy=0,skip=0; 1472 | int i=0,j=0,delta=7,len=256-delta; 1473 | char* ret; 1474 | 1475 | which=(which+1)%4; 1476 | ret=safe[which]; 1477 | 1478 | safe[which][0]=0; 1479 | 1480 | if(malloced[which]) 1481 | {Free(malloced[which]);malloced[which]=NULL;} 1482 | 1483 | if(c) 1484 | { 1485 | if(!verbatim) 1486 | i=CopyOrSkip(c,"html",©,&skip); 1487 | 1488 | while(1) 1489 | { 1490 | for(;j<len && c[i];i++) 1491 | { 1492 | if(copy) 1493 | {ret[j++]=c[i]; if(c[i]=='\n') copy=0;} 1494 | else if(skip) 1495 | { if(c[i]=='\n') skip=0;} 1496 | else 1497 | switch(c[i]) 1498 | { 1499 | case 12: /* ^L */ 1500 | break; 1501 | case '<': 1502 | strcpy(&ret[j],"<");j+=4; 1503 | break; 1504 | case '>': 1505 | strcpy(&ret[j],">");j+=4; 1506 | break; 1507 | case '&': 1508 | strcpy(&ret[j],"&");j+=5; 1509 | break; 1510 | case '\n': 1511 | if(j && ret[j-1]=='\n') 1512 | { 1513 | strcpy(&ret[j],"<br>");j+=4; 1514 | } 1515 | ret[j++]=c[i]; 1516 | break; 1517 | default: 1518 | ret[j++]=c[i]; 1519 | } 1520 | if(c[i]=='\n') 1521 | if(!verbatim) 1522 | i+=CopyOrSkip(c+i,"html",©,&skip); 1523 | } 1524 | 1525 | if(c[i]) /* Not finished */ 1526 | { 1527 | if(malloced[which]) 1528 | malloced[which]=Realloc(malloced[which],len+delta+256); 1529 | else 1530 | {malloced[which]=Malloc(len+delta+256); strncpy(malloced[which],ret,(unsigned)j);} 1531 | ret=malloced[which]; 1532 | len+=256; 1533 | } 1534 | else 1535 | {ret[j]=0; break;} 1536 | } 1537 | } 1538 | 1539 | return(ret); 1540 | }