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