1 | /*************************************** 2 | $Header: /home/amb/cxref/RCS/sgml.c 1.4 1999/05/15 16:58:57 amb Exp $ 3 | 4 | C Cross Referencing & Documentation tool. Version 1.5a. 5 | 6 | Writes the SGML output. 7 | ******************/ /****************** 8 | Written by Andrew M. Bishop 9 | 10 | This file Copyright 1995,96,97,98 Andrew M. Bishop 11 | It may be distributed under the GNU Public License, version 2, or 12 | any higher version. See section COPYING of the GNU Public license 13 | for conditions under which this file may be redistributed. 14 | ***************************************/ 15 | 16 | #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 "memory.h" 24 | #include "datatype.h" 25 | #include "cxref.h" 26 | 27 | /*+ The name of the output tex file that includes each of the others. +*/ 28 | #define SGML_FILE ".sgml" 29 | #define SGML_FILE_BACKUP ".sgml~" 30 | 31 | /*+ The name of the output tex file that contains the appendix. +*/ 32 | #define SGML_APDX ".apdx" 33 | 34 | /*+ The comments are to be inserted verbatim. +*/ 35 | extern int option_verbatim_comments; 36 | 37 | /*+ The name of the directory for the output. +*/ 38 | extern char* option_odir; 39 | 40 | /*+ The base name of the file for the output. +*/ 41 | extern char* option_name; 42 | 43 | /*+ The information about the cxref run, +*/ 44 | extern char *run_command, /*+ the command line options. +*/ 45 | *run_cpp_command; /*+ the cpp command and options. +*/ 46 | 47 | /*+ The directories to go back to get to the base output directory. +*/ 48 | static char* goback=NULL; 49 | 50 | static void WriteSGMLFilePart(File file); 51 | static void WriteSGMLInclude(Include inc); 52 | static void WriteSGMLSubInclude(Include inc,int depth); 53 | static void WriteSGMLDefine(Define def); 54 | static void WriteSGMLTypedef(Typedef type); 55 | static void WriteSGMLStructUnion(StructUnion su,int depth); 56 | static void WriteSGMLVariable(Variable var); 57 | static void WriteSGMLFunction(Function func); 58 | 59 | static void WriteSGMLPreamble(FILE* f,char* title); 60 | static void WriteSGMLPostamble(FILE* f); 61 | 62 | static char* sgml(char* c,int verbatim); 63 | 64 | /*+ The output file for the SGML. +*/ 65 | static FILE* of; 66 | 67 | /*+ The name of the file. +*/ 68 | static char *filename; 69 | 70 | 71 | /*++++++++++++++++++++++++++++++++++++++ 72 | Write an sgml file for a complete File structure and all components. 73 | 74 | File file The File structure to output. 75 | ++++++++++++++++++++++++++++++++++++++*/ 76 | 77 | void WriteSGMLFile(File file) 78 | { 79 | char* ofile; 80 | int i; 81 | 82 | filename=file->name; 83 | 84 | /* Open the file */ 85 | 86 | ofile=ConcatStrings(4,option_odir,"/",file->name,SGML_FILE); 87 | 88 | of=fopen(ofile,"w"); 89 | if(!of) 90 | { 91 | struct stat stat_buf; 92 | int i,ofl=strlen(ofile); 93 | 94 | for(i=strlen(option_odir)+1;i<ofl;i++) 95 | if(ofile[i]=='/') 96 | { 97 | ofile[i]=0; 98 | if(stat(ofile,&stat_buf)) 99 | mkdir(ofile,S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); 100 | ofile[i]='/'; 101 | } 102 | 103 | of=fopen(ofile,"w"); 104 | } 105 | 106 | if(!of) 107 | {fprintf(stderr,"cxref: Failed to open the SGML output file '%s'\n",ofile);exit(1);} 108 | 109 | for(goback="",i=strlen(file->name);i>0;i--) 110 | if(file->name[i]=='/') 111 | goback=ConcatStrings(2,goback,"../"); 112 | 113 | /* Write out a header. */ 114 | 115 | WriteSGMLPreamble(of,ConcatStrings(5,"Cross reference for ",file->name," of ",option_name,".")); 116 | 117 | /*+ The file structure is broken into its components and they are each written out. +*/ 118 | 119 | WriteSGMLFilePart(file); 120 | 121 | if(file->includes) 122 | { 123 | Include inc =file->includes; 124 | fprintf(of,"\n<sect1>Included Files\n\n<p>\n"); 125 | do{ 126 | WriteSGMLInclude(inc); 127 | } 128 | while((inc=inc->next)); 129 | } 130 | 131 | if(file->defines) 132 | { 133 | Define def =file->defines; 134 | fprintf(of,"\n<sect1>Preprocessor definitions\n\n<p>\n"); 135 | do{ 136 | if(def!=file->defines) 137 | fprintf(of,"<p>\n"); 138 | WriteSGMLDefine(def); 139 | } 140 | while((def=def->next)); 141 | } 142 | 143 | if(file->typedefs) 144 | { 145 | Typedef type=file->typedefs; 146 | do{ 147 | WriteSGMLTypedef(type); 148 | } 149 | while((type=type->next)); 150 | } 151 | 152 | if(file->variables) 153 | { 154 | int any_to_mention=0; 155 | Variable var=file->variables; 156 | 157 | do{ 158 | if(var->scope&(GLOBAL|LOCAL|EXTERNAL|EXTERN_F)) 159 | any_to_mention=1; 160 | } 161 | while((var=var->next)); 162 | 163 | if(any_to_mention) 164 | { 165 | int first_ext=1,first_local=1; 166 | Variable var=file->variables; 167 | do{ 168 | if(var->scope&GLOBAL) 169 | WriteSGMLVariable(var); 170 | } 171 | while((var=var->next)); 172 | var=file->variables; 173 | do{ 174 | if(var->scope&(EXTERNAL|EXTERN_F) && !(var->scope&GLOBAL)) 175 | { 176 | if(first_ext) 177 | {fprintf(of,"\n<sect1>External Variables\n\n"); first_ext=0;} 178 | fprintf(of,"<p>\n"); 179 | WriteSGMLVariable(var); 180 | } 181 | } 182 | while((var=var->next)); 183 | var=file->variables; 184 | do{ 185 | if(var->scope&LOCAL) 186 | { 187 | if(first_local) 188 | {fprintf(of,"\n<sect1>Local Variables\n\n"); first_local=0;} 189 | fprintf(of,"<p>\n"); 190 | WriteSGMLVariable(var); 191 | } 192 | } 193 | while((var=var->next)); 194 | } 195 | } 196 | 197 | if(file->functions) 198 | { 199 | Function func=file->functions; 200 | do{ 201 | if(func->scope&(GLOBAL|EXTERNAL)) 202 | WriteSGMLFunction(func); 203 | } 204 | while((func=func->next)); 205 | func=file->functions; 206 | do{ 207 | if(func->scope&LOCAL) 208 | WriteSGMLFunction(func); 209 | } 210 | while((func=func->next)); 211 | } 212 | 213 | WriteSGMLPostamble(of); 214 | 215 | fclose(of); 216 | 217 | /* Clear the memory in sgml() */ 218 | 219 | sgml(NULL,0); sgml(NULL,0); sgml(NULL,0); sgml(NULL,0); 220 | } 221 | 222 | 223 | /*++++++++++++++++++++++++++++++++++++++ 224 | Write a File structure out. 225 | 226 | File file The File to output. 227 | ++++++++++++++++++++++++++++++++++++++*/ 228 | 229 | static void WriteSGMLFilePart(File file) 230 | { 231 | int i; 232 | 233 | fprintf(of,"<sect>File %s\n",sgml(file->name,0)); 234 | 235 | if(file->comment) 236 | if(option_verbatim_comments) 237 | fprintf(of,"<p><tscreen><verb>\n%s\n</verb></tscreen>\n\n",sgml(file->comment,1)); 238 | else 239 | { 240 | char *rcs1=strstr(file->comment,"$Header"),*rcs2=NULL; 241 | if(rcs1) 242 | { 243 | rcs2=strstr(&rcs1[1],"$"); 244 | if(rcs2) 245 | { 246 | rcs2[0]=0; 247 | fprintf(of,"<bf>RCS %s</bf>\n<p>\n",sgml(&rcs1[1],0)); 248 | rcs2[0]='$'; 249 | } 250 | } 251 | if(rcs2) 252 | fprintf(of,"%s\n<p>\n",sgml(&rcs2[2],0)); 253 | else 254 | fprintf(of,"%s\n<p>\n",sgml(file->comment,0)); 255 | } 256 | 257 | if(file->inc_in->n) 258 | { 259 | int i; 260 | 261 | fprintf(of,"<p>\n<descrip>\n<tag>Included in:</tag>\n<itemize>\n"); 262 | for(i=0;i<file->inc_in->n;i++) 263 | fprintf(of,"<item>%s\n",sgml(file->inc_in->s[i],0)); 264 | fprintf(of,"</itemize>\n</descrip>\n"); 265 | } 266 | 267 | if(file->f_refs->n || file->v_refs->n) 268 | fprintf(of,"<descrip>\n"); 269 | 270 | if(file->f_refs->n) 271 | { 272 | int others=0; 273 | fprintf(of,"<tag>References Functions:</tag>\n<itemize>\n"); 274 | for(i=0;i<file->f_refs->n;i++) 275 | if(file->f_refs->s2[i]) 276 | fprintf(of,"<item>%s() : %s\n",sgml(file->f_refs->s1[i],0),sgml(file->f_refs->s2[i],0)); 277 | else 278 | others++; 279 | 280 | if(others) 281 | { 282 | fprintf(of,"<item>"); 283 | for(i=0;i<file->f_refs->n;i++) 284 | if(!file->f_refs->s2[i]) 285 | fprintf(of,--others?" %s(),":" %s()",sgml(file->f_refs->s1[i],0)); 286 | fprintf(of,"\n"); 287 | } 288 | fprintf(of,"</itemize>\n"); 289 | } 290 | 291 | if(file->v_refs->n) 292 | { 293 | int others=0; 294 | fprintf(of,"<tag>References Variables:</tag>\n<itemize>\n"); 295 | for(i=0;i<file->v_refs->n;i++) 296 | { 297 | if(file->v_refs->s2[i]) 298 | fprintf(of,"<item>%s : %s\n",sgml(file->v_refs->s1[i],0),sgml(file->v_refs->s2[i],0)); 299 | else 300 | others++; 301 | } 302 | 303 | if(others) 304 | { 305 | fprintf(of,"<item>"); 306 | for(i=0;i<file->v_refs->n;i++) 307 | if(!file->v_refs->s2[i]) 308 | fprintf(of,--others?" %s,":" %s",sgml(file->v_refs->s1[i],0)); 309 | fprintf(of,"\n"); 310 | } 311 | fprintf(of,"</itemize>\n"); 312 | } 313 | 314 | if(file->f_refs->n || file->v_refs->n) 315 | fprintf(of,"</descrip>\n"); 316 | } 317 | 318 | 319 | /*++++++++++++++++++++++++++++++++++++++ 320 | Write an Include structure out. 321 | 322 | Include inc The Include structure to output. 323 | ++++++++++++++++++++++++++++++++++++++*/ 324 | 325 | static void WriteSGMLInclude(Include inc) 326 | { 327 | if(inc->comment) 328 | fprintf(of,"%s\n<p>\n",sgml(inc->comment,0)); 329 | 330 | fprintf(of,"<itemize>\n"); 331 | 332 | if(inc->scope==LOCAL) 333 | fprintf(of,"<item><tt>#include "%s"</tt>\n",sgml(inc->name,0)); 334 | else 335 | fprintf(of,"<item><tt>#include <%s></tt>\n",sgml(inc->name,0)); 336 | 337 | if(inc->includes) 338 | WriteSGMLSubInclude(inc->includes,1); 339 | 340 | fprintf(of,"</itemize>\n"); 341 | } 342 | 343 | 344 | /*++++++++++++++++++++++++++++++++++++++ 345 | Write an Sub Include structure out. (An include structure that is included from another file.) 346 | 347 | Include inc The Include structure to output. 348 | 349 | int depth The depth of the include hierarchy. 350 | ++++++++++++++++++++++++++++++++++++++*/ 351 | 352 | static void WriteSGMLSubInclude(Include inc,int depth) 353 | { 354 | fprintf(of,"<itemize>\n"); 355 | 356 | while(inc) 357 | { 358 | if(inc->scope==LOCAL) 359 | fprintf(of,"<item><tt>#include "%s"</tt>\n",sgml(inc->name,0)); 360 | else 361 | fprintf(of,"<item><tt>#include <%s></tt>\n",sgml(inc->name,0)); 362 | 363 | if(inc->includes) 364 | WriteSGMLSubInclude(inc->includes,depth+1); 365 | 366 | inc=inc->next; 367 | } 368 | 369 | fprintf(of,"</itemize>\n"); 370 | } 371 | 372 | 373 | /*++++++++++++++++++++++++++++++++++++++ 374 | Write a Define structure out. 375 | 376 | Define def The Define structure to output. 377 | ++++++++++++++++++++++++++++++++++++++*/ 378 | 379 | static void WriteSGMLDefine(Define def) 380 | { 381 | int i; 382 | int pargs=0; 383 | 384 | if(def->comment) 385 | fprintf(of,"%s\n<p>\n",sgml(def->comment,0)); 386 | 387 | fprintf(of,"<tt>#define %s",sgml(def->name,0)); 388 | 389 | if(def->value) 390 | fprintf(of," %s",sgml(def->value,0)); 391 | 392 | if(def->args->n) 393 | { 394 | fprintf(of,"( "); 395 | for(i=0;i<def->args->n;i++) 396 | fprintf(of,i?", %s":"%s",sgml(def->args->s1[i],0)); 397 | fprintf(of," )"); 398 | } 399 | fprintf(of,"</tt><newline>\n"); 400 | 401 | for(i=0;i<def->args->n;i++) 402 | if(def->args->s2[i]) 403 | pargs=1; 404 | 405 | if(pargs) 406 | { 407 | fprintf(of,"<descrip>\n"); 408 | for(i=0;i<def->args->n;i++) 409 | fprintf(of,"<tag><tt>%s</tt></tag>\n%s\n",sgml(def->args->s1[i],0),def->args->s2[i]?sgml(def->args->s2[i],0):""); 410 | fprintf(of,"</descrip>\n"); 411 | } 412 | } 413 | 414 | 415 | /*++++++++++++++++++++++++++++++++++++++ 416 | Write a Typedef structure out. 417 | 418 | Typedef type The Typedef structure to output. 419 | ++++++++++++++++++++++++++++++++++++++*/ 420 | 421 | static void WriteSGMLTypedef(Typedef type) 422 | { 423 | fprintf(of,"\n<sect1>"); 424 | 425 | if(type->type) 426 | fprintf(of,"Typedef %s",sgml(type->name,0)); 427 | else 428 | fprintf(of,"Type %s",sgml(type->name,0)); 429 | 430 | fprintf(of,"\n\n<p>\n"); 431 | 432 | if(type->comment) 433 | fprintf(of,"%s\n<p>\n",sgml(type->comment,0)); 434 | 435 | if(type->type) 436 | fprintf(of,"<tt>typedef %s</tt><newline>\n",sgml(type->type,0)); 437 | 438 | if(type->sutype) 439 | { 440 | fprintf(of,"<itemize>\n"); 441 | WriteSGMLStructUnion(type->sutype,0); 442 | fprintf(of,"</itemize>\n"); 443 | } 444 | else 445 | if(type->typexref) 446 | { 447 | fprintf(of,"<descrip>\n<tag>See:</tag>\n<itemize>\n"); 448 | if(type->typexref->type) 449 | fprintf(of,"<item>Typedef %s\n",sgml(type->typexref->name,0)); 450 | else 451 | if(!strncmp("enum",type->typexref->name,4)) 452 | fprintf(of,"<item>Type %s\n",sgml(type->typexref->name,0)); 453 | else 454 | if(!strncmp("union",type->typexref->name,5)) 455 | fprintf(of,"<item>Type %s\n",sgml(type->typexref->name,0)); 456 | else 457 | if(!strncmp("struct",type->typexref->name,6)) 458 | fprintf(of,"<item>Type %s\n",sgml(type->typexref->name,0)); 459 | fprintf(of,"</itemize>\n</descrip>\n"); 460 | } 461 | } 462 | 463 | 464 | /*++++++++++++++++++++++++++++++++++++++ 465 | Write a structure / union structure out. 466 | 467 | StructUnion su The structure / union to write. 468 | 469 | int depth The current depth within the structure. 470 | ++++++++++++++++++++++++++++++++++++++*/ 471 | 472 | static void WriteSGMLStructUnion(StructUnion su, int depth) 473 | { 474 | int i; 475 | char* splitsu=NULL; 476 | 477 | splitsu=strstr(su->name,"{...}"); 478 | if(splitsu) splitsu[-1]=0; 479 | 480 | if(depth && su->comment && !su->comps) 481 | fprintf(of,"<item><tt>%s; </tt>%s<newline>\n",sgml(su->name,0),sgml(su->comment,0)); 482 | else if(!depth || su->comps) 483 | fprintf(of,"<item><tt>%s</tt><newline>\n",sgml(su->name,0)); 484 | else 485 | fprintf(of,"<item><tt>%s;</tt><newline>\n",sgml(su->name,0)); 486 | 487 | if(!depth || su->comps) 488 | { 489 | fprintf(of,"<itemize>\n"); 490 | 491 | fprintf(of,"<item><tt>{</tt><newline>\n"); 492 | 493 | for(i=0;i<su->n_comp;i++) 494 | WriteSGMLStructUnion(su->comps[i],depth+1); 495 | 496 | fprintf(of,"<item><tt>}</tt><newline>\n"); 497 | 498 | fprintf(of,"</itemize>\n"); 499 | 500 | if(splitsu) 501 | { 502 | if(depth && su->comment) 503 | fprintf(of,"<item><tt>%s; </tt>%s<newline>\n",splitsu[5]?sgml(&splitsu[6],0):"",sgml(su->comment,0)); 504 | else 505 | fprintf(of,"<item><tt>%s;</tt><newline>\n",splitsu[5]?sgml(&splitsu[6],0):""); 506 | } 507 | } 508 | 509 | if(splitsu) splitsu[-1]=' '; 510 | } 511 | 512 | 513 | /*++++++++++++++++++++++++++++++++++++++ 514 | Write a Variable structure out. 515 | 516 | Variable var The Variable structure to output. 517 | ++++++++++++++++++++++++++++++++++++++*/ 518 | 519 | static void WriteSGMLVariable(Variable var) 520 | { 521 | int i; 522 | 523 | if(var->scope&GLOBAL) 524 | fprintf(of,"\n<sect1>Global Variable %s\n\n<p>\n",sgml(var->name,0)); 525 | else 526 | fprintf(of,"<bf>%s</bf><newline>\n",sgml(var->name,0)); 527 | 528 | if(var->comment) 529 | fprintf(of,"%s\n<p>\n",sgml(var->comment,0)); 530 | 531 | fprintf(of,"<tt>"); 532 | 533 | if(var->scope&LOCAL) 534 | fprintf(of,"static "); 535 | else 536 | if(!(var->scope&GLOBAL) && var->scope&(EXTERNAL|EXTERN_F)) 537 | fprintf(of,"extern "); 538 | 539 | fprintf(of,"%s</tt><newline>\n",sgml(var->type,0)); 540 | 541 | if(var->scope&(GLOBAL|LOCAL)) 542 | { 543 | if(var->incfrom || var->visible->n || var->used->n) 544 | fprintf(of,"<descrip>\n"); 545 | 546 | if(var->incfrom) 547 | { 548 | fprintf(of,"<tag>Included from:</tag>\n<itemize>\n"); 549 | fprintf(of,"<item>%s\n",sgml(var->incfrom,0)); 550 | fprintf(of,"</itemize>\n"); 551 | } 552 | 553 | if(var->visible->n) 554 | { 555 | fprintf(of,"<tag>Visible in:</tag>\n<itemize>\n"); 556 | for(i=0;i<var->visible->n;i++) 557 | if(var->visible->s1[i][0]=='$' && !var->visible->s1[i][1]) 558 | fprintf(of,"<item>%s\n",sgml(var->visible->s2[i],0)); 559 | else 560 | fprintf(of,"<item>%s() : %s\n",sgml(var->visible->s1[i],0),sgml(var->visible->s2[i],0)); 561 | fprintf(of,"</itemize>\n"); 562 | } 563 | 564 | if(var->used->n) 565 | { 566 | fprintf(of,"<tag>Used in:</tag>\n<itemize>\n"); 567 | for(i=0;i<var->used->n;i++) 568 | { 569 | if(var->used->s1[i][0]=='$' && !var->used->s1[i][1]) 570 | fprintf(of,"<item>%s\n",sgml(var->used->s2[i],0)); 571 | else 572 | { 573 | if(var->scope&LOCAL) 574 | fprintf(of,"<item>%s()\n",sgml(var->used->s1[i],0)); 575 | else 576 | fprintf(of,"<item>%s() : %s\n",sgml(var->used->s1[i],0),sgml(var->used->s2[i],0)); 577 | } 578 | } 579 | fprintf(of,"</itemize>\n"); 580 | } 581 | 582 | if(var->incfrom || var->visible->n || var->used->n) 583 | fprintf(of,"</descrip>\n"); 584 | } 585 | else 586 | if(var->scope&(EXTERNAL|EXTERN_F) && var->defined) 587 | { 588 | fprintf(of,"<descrip>\n<tag>Defined in:</tag>\n<itemize>\n"); 589 | fprintf(of,"<item>%s",sgml(var->name,0)); 590 | fprintf(of,"</itemize>\n</descrip>\n"); 591 | } 592 | } 593 | 594 | 595 | /*++++++++++++++++++++++++++++++++++++++ 596 | Write a Function structure out. 597 | 598 | Function func The Function structure to output. 599 | ++++++++++++++++++++++++++++++++++++++*/ 600 | 601 | static void WriteSGMLFunction(Function func) 602 | { 603 | int i,pret,pargs; 604 | char* comment2=NULL,*type; 605 | 606 | if(func->scope&GLOBAL) 607 | fprintf(of,"\n<sect1>Global Function %s()\n\n<p>",sgml(func->name,0)); 608 | else 609 | fprintf(of,"\n<sect1>Local Function %s()\n\n<p>",sgml(func->name,0)); 610 | 611 | if(func->comment) 612 | if(option_verbatim_comments) 613 | fprintf(of,"<tscreen><verb>\n%s\n</verb></tscreen>\n\n",sgml(func->comment,1)); 614 | else 615 | { 616 | comment2=strstr(func->comment,"\n\n"); 617 | if(comment2) 618 | comment2[0]=0; 619 | fprintf(of,"%s\n<p>\n",sgml(func->comment,0)); 620 | } 621 | 622 | fprintf(of,"<tt>"); 623 | 624 | if(func->scope&LOCAL) 625 | fprintf(of,"static "); 626 | if(func->scope&INLINED) 627 | fprintf(of,"inline "); 628 | 629 | if((type=strstr(func->type,"()"))) 630 | type[0]=0; 631 | fprintf(of,"%s ( ",sgml(func->type,0)); 632 | 633 | for(i=0;i<func->args->n;i++) 634 | fprintf(of,i?", %s":"%s",sgml(func->args->s1[i],0)); 635 | 636 | if(type) 637 | {fprintf(of," %s</tt><newline>\n",sgml(&type[1],0));type[0]='(';} 638 | else 639 | fprintf(of," )</tt><newline>\n"); 640 | 641 | pret =strncmp("void ",func->type,5) && func->cret; 642 | for(pargs=0,i=0;i<func->args->n;i++) 643 | pargs = pargs || ( strcmp("void",func->args->s1[i]) && func->args->s2[i] ); 644 | 645 | if(pret || pargs) 646 | { 647 | fprintf(of,"<descrip>\n"); 648 | if(pret) 649 | fprintf(of,"<tag><tt>%s</tt></tag>\n%s\n",sgml(func->type,0),func->cret?sgml(func->cret,0):"&nbs;"); 650 | if(pargs) 651 | for(i=0;i<func->args->n;i++) 652 | fprintf(of,"<tag><tt>%s</tt></tag>\n%s\n",sgml(func->args->s1[i],0),func->args->s2[i]?sgml(func->args->s2[i],0):"&nbs;"); 653 | fprintf(of,"</descrip>\n"); 654 | } 655 | 656 | if(comment2) 657 | { 658 | fprintf(of,"%s\n<p>\n",sgml(&comment2[2],0)); 659 | comment2[0]='\n'; 660 | } 661 | 662 | if(func->protofile || func->incfrom || func->calls->n || func->called->n || func->used->n || func->f_refs->n || func->v_refs->n) 663 | fprintf(of,"<descrip>\n"); 664 | 665 | if(func->protofile) 666 | { 667 | fprintf(of,"<tag>Prototyped in:</tag>\n<itemize>\n"); 668 | fprintf(of,"<item>%s\n",sgml(func->protofile,0)); 669 | fprintf(of,"</itemize>\n"); 670 | } 671 | 672 | if(func->incfrom) 673 | { 674 | fprintf(of,"<tag>Included from:</tag>\n<itemize>\n"); 675 | fprintf(of,"<item>%s\n",sgml(func->incfrom,0)); 676 | fprintf(of,"</itemize>\n"); 677 | } 678 | 679 | if(func->calls->n) 680 | { 681 | int others=0; 682 | fprintf(of,"<tag>Calls:</tag>\n<itemize>\n"); 683 | for(i=0;i<func->calls->n;i++) 684 | { 685 | if(func->calls->s2[i]) 686 | fprintf(of,"<item>%s() : %s\n",sgml(func->calls->s1[i],0),sgml(func->calls->s2[i],0)); 687 | else 688 | others++; 689 | } 690 | 691 | if(others) 692 | { 693 | fprintf(of,"<item>"); 694 | for(i=0;i<func->calls->n;i++) 695 | if(!func->calls->s2[i]) 696 | fprintf(of,--others?"%s(), ":"%s()",sgml(func->calls->s1[i],0)); 697 | fprintf(of,"\n"); 698 | } 699 | fprintf(of,"</itemize>\n"); 700 | } 701 | 702 | if(func->called->n) 703 | { 704 | fprintf(of,"<tag>Called by:</tag>\n<itemize>\n"); 705 | for(i=0;i<func->called->n;i++) 706 | fprintf(of,"<item>%s() : %s\n",sgml(func->called->s1[i],0),sgml(func->called->s2[i],0)); 707 | fprintf(of,"</itemize>\n"); 708 | } 709 | 710 | if(func->used->n) 711 | { 712 | fprintf(of,"<tag>Used in:</tag>\n<itemize>\n"); 713 | for(i=0;i<func->used->n;i++) 714 | { 715 | if(func->used->s1[i][0]=='$' && !func->used->s1[i][1]) 716 | fprintf(of,"<item>%s\n",sgml(func->used->s2[i],0)); 717 | else 718 | fprintf(of,"<item>%s() : %s\n",sgml(func->used->s1[i],0),sgml(func->used->s2[i],0)); 719 | } 720 | fprintf(of,"</itemize>\n"); 721 | } 722 | 723 | if(func->f_refs->n) 724 | { 725 | int others=0; 726 | fprintf(of,"<tag>References Functions:</tag>\n<itemize>\n"); 727 | for(i=0;i<func->f_refs->n;i++) 728 | { 729 | if(func->f_refs->s2[i]) 730 | fprintf(of,"<item>%s() : %s\n",sgml(func->f_refs->s1[i],0),sgml(func->f_refs->s2[i],0)); 731 | else 732 | others++; 733 | } 734 | 735 | if(others) 736 | { 737 | fprintf(of,"<item>"); 738 | for(i=0;i<func->f_refs->n;i++) 739 | if(!func->f_refs->s2[i]) 740 | fprintf(of,--others?"%s(), ":"%s()",sgml(func->f_refs->s1[i],0)); 741 | fprintf(of,"\n"); 742 | } 743 | fprintf(of,"</itemize>\n"); 744 | } 745 | 746 | if(func->v_refs->n) 747 | { 748 | int others=0; 749 | fprintf(of,"<tag>References Variables:</tag>\n<itemize>\n"); 750 | for(i=0;i<func->v_refs->n;i++) 751 | { 752 | if(func->v_refs->s2[i]) 753 | fprintf(of,"<item>%s : %s\n",sgml(func->v_refs->s1[i],0),sgml(func->v_refs->s2[i],0)); 754 | else 755 | others++; 756 | } 757 | 758 | if(others) 759 | { 760 | fprintf(of,"<item>"); 761 | for(i=0;i<func->v_refs->n;i++) 762 | if(!func->v_refs->s2[i]) 763 | fprintf(of,--others?"%s, ":"%s",sgml(func->v_refs->s1[i],0)); 764 | fprintf(of,"\n"); 765 | } 766 | fprintf(of,"</itemize>\n"); 767 | } 768 | 769 | if(func->protofile || func->incfrom || func->calls->n || func->called->n || func->used->n || func->f_refs->n || func->v_refs->n) 770 | fprintf(of,"</descrip>\n"); 771 | } 772 | 773 | 774 | /*++++++++++++++++++++++++++++++++++++++ 775 | Write out a standard pre-amble. 776 | 777 | FILE* f The file to write the pre amble to. 778 | 779 | char* title The title of the file. 780 | ++++++++++++++++++++++++++++++++++++++*/ 781 | 782 | static void WriteSGMLPreamble(FILE* f,char* title) 783 | { 784 | fputs("<!DOCTYPE LINUXDOC SYSTEM>\n",f); 785 | fputs("\n",f); 786 | fputs("<!-- This SGML file generated by cxref. -->\n",f); 787 | fputs("<!-- cxref program (c) Andrew M. Bishop 1995,96,97,98,99. -->\n",f); 788 | fputs("\n",f); 789 | fputs("<!--\n",f); 790 | if(filename) 791 | fprintf(f,"Cxref: %s %s\n",run_command,filename); 792 | else 793 | fprintf(f,"Cxref: %s\n",run_command); 794 | fprintf(f,"CPP : %s\n",run_cpp_command); 795 | fputs("-->\n",f); 796 | fputs("\n",f); 797 | fputs("<article>\n",f); 798 | fputs("\n",f); 799 | fputs("<title>",f); 800 | fputs(title,f); 801 | fputs("\n",f); 802 | fputs("<author>cxref\n",f); 803 | fputs("\n",f); 804 | } 805 | 806 | 807 | /*++++++++++++++++++++++++++++++++++++++ 808 | Write out a standard post-amble. This includes the end of document marker. 809 | 810 | FILE* f The file to write the post amble to. 811 | ++++++++++++++++++++++++++++++++++++++*/ 812 | 813 | static void WriteSGMLPostamble(FILE* f) 814 | { 815 | fputs("\n",f); 816 | fputs("</article>\n",f); 817 | } 818 | 819 | 820 | /*++++++++++++++++++++++++++++++++++++++ 821 | Write out the appendix information. 822 | 823 | StringList files The list of files to write. 824 | 825 | StringList2 funcs The list of functions to write. 826 | 827 | StringList2 vars The list of variables to write. 828 | 829 | StringList2 types The list of types to write. 830 | ++++++++++++++++++++++++++++++++++++++*/ 831 | 832 | void WriteSGMLAppendix(StringList files,StringList2 funcs,StringList2 vars,StringList2 types) 833 | { 834 | char* ofile; 835 | int i; 836 | 837 | filename=NULL; 838 | 839 | /* Open the file */ 840 | 841 | ofile=ConcatStrings(5,option_odir,"/",option_name,SGML_APDX,SGML_FILE); 842 | 843 | of=fopen(ofile,"w"); 844 | 845 | if(!of) 846 | {fprintf(stderr,"cxref: Failed to open the SGML appendix file '%s'\n",ofile);exit(1);} 847 | 848 | /* Write the file structure out */ 849 | 850 | WriteSGMLPreamble(of,ConcatStrings(3,"Cross reference index of ",option_name,".")); 851 | 852 | fprintf(of,"<sect>Cross References\n"); 853 | 854 | /* Write out the appendix of files. */ 855 | 856 | if(files->n) 857 | { 858 | fprintf(of,"\n<sect1>Files\n\n<p>\n"); 859 | fprintf(of,"<itemize>\n"); 860 | for(i=0;i<files->n;i++) 861 | fprintf(of,"<item>%s>\n",sgml(files->s[i],0)); 862 | fprintf(of,"</itemize>\n"); 863 | } 864 | 865 | /* Write out the appendix of functions. */ 866 | 867 | if(funcs->n) 868 | { 869 | fprintf(of,"\n<sect1>Global Functions\n\n<p>\n"); 870 | fprintf(of,"<itemize>\n"); 871 | for(i=0;i<funcs->n;i++) 872 | fprintf(of,"<item>%s() : %s\n",sgml(funcs->s1[i],0),sgml(funcs->s2[i],0)); 873 | fprintf(of,"</itemize>\n"); 874 | } 875 | 876 | /* Write out the appendix of variables. */ 877 | 878 | if(vars->n) 879 | { 880 | fprintf(of,"\n<sect1>Global Variables\n\n<p>\n"); 881 | fprintf(of,"<itemize>\n"); 882 | for(i=0;i<vars->n;i++) 883 | fprintf(of,"<item>%s : %s\n",sgml(vars->s1[i],0),sgml(vars->s2[i],0)); 884 | fprintf(of,"</itemize>\n"); 885 | } 886 | 887 | /* Write out the appendix of types. */ 888 | 889 | if(types->n) 890 | { 891 | fprintf(of,"\n<sect1>Defined Types\n\n<p>\n"); 892 | fprintf(of,"<itemize>\n"); 893 | for(i=0;i<types->n;i++) 894 | if(!strncmp("enum",types->s1[i],4)) 895 | fprintf(of,"<item>%s : %s\n",sgml(types->s1[i],0),sgml(types->s2[i],0)); 896 | else 897 | if(!strncmp("union",types->s1[i],5)) 898 | fprintf(of,"<item>%s : %s\n",sgml(types->s1[i],0),sgml(types->s2[i],0)); 899 | else 900 | if(!strncmp("struct",types->s1[i],6)) 901 | fprintf(of,"<item>%s : %s\n",sgml(types->s1[i],0),sgml(types->s2[i],0)); 902 | else 903 | fprintf(of,"<item>%s : %s\n",sgml(types->s1[i],0),sgml(types->s2[i],0)); 904 | fprintf(of,"</itemize>\n"); 905 | } 906 | 907 | WriteSGMLPostamble(of); 908 | 909 | fclose(of); 910 | 911 | /* Clear the memory in sgml(,0) */ 912 | 913 | sgml(NULL,0); sgml(NULL,0); sgml(NULL,0); sgml(NULL,0); 914 | } 915 | 916 | 917 | /*++++++++++++++++++++++++++++++++++++++ 918 | Delete the SGML file and main file reference that belong to the named file. 919 | 920 | char *name The name of the file to delete. 921 | ++++++++++++++++++++++++++++++++++++++*/ 922 | 923 | void WriteSGMLFileDelete(char *name) 924 | { 925 | char *ofile; 926 | 927 | ofile=ConcatStrings(4,option_odir,"/",name,SGML_FILE); 928 | unlink(ofile); 929 | } 930 | 931 | 932 | /*++++++++++++++++++++++++++++++++++++++ 933 | Make the input string safe to output as SGML ( not <, >, &, ", $, #, % or ~ ). 934 | 935 | char* sgml Returns a safe SGML string. 936 | 937 | char* c A non-safe SGML string. 938 | 939 | int verbatim Set to true inside a verbatim environment. 940 | 941 | The function can only be called four times in each fprintf() since it returns one of only four static strings. 942 | ++++++++++++++++++++++++++++++++++++++*/ 943 | 944 | static char* sgml(char* c,int verbatim) 945 | { 946 | static char safe[4][256],*malloced[4]={NULL,NULL,NULL,NULL}; 947 | static int which=0; 948 | int copy=0,skip=0; 949 | int i=0,j=0,delta=10,len=256-delta; 950 | char* ret; 951 | 952 | which=(which+1)%4; 953 | ret=safe[which]; 954 | 955 | safe[which][0]=0; 956 | 957 | if(malloced[which]) 958 | {Free(malloced[which]);malloced[which]=NULL;} 959 | 960 | if(c) 961 | { 962 | i=CopyOrSkip(c,"sgml",©,&skip); 963 | 964 | while(1) 965 | { 966 | for(;j<len && c[i];i++) 967 | { 968 | if(copy) 969 | {ret[j++]=c[i]; if(c[i]=='\n') copy=0;} 970 | else if(skip) 971 | { if(c[i]=='\n') skip=0;} 972 | else if(verbatim) 973 | switch(c[i]) 974 | { 975 | case '&': 976 | strcpy(&ret[j],"&ero;");j+=5; 977 | break; 978 | case '<': 979 | if(c[i+1]=='/') 980 | {strcpy(&ret[j],"&etago;");j+=7; break;} 981 | default: 982 | ret[j++]=c[i]; 983 | } 984 | else 985 | switch(c[i]) 986 | { 987 | case '<': 988 | if(c[i+1]=='/') 989 | {strcpy(&ret[j],"&etago;");j+=7;} 990 | else 991 | {strcpy(&ret[j],"<");j+=4;} 992 | break; 993 | case '>': 994 | strcpy(&ret[j],">");j+=4; 995 | break; 996 | case '"': 997 | strcpy(&ret[j],""");j+=6; 998 | break; 999 | case '&': 1000 | strcpy(&ret[j],"&");j+=5; 1001 | break; 1002 | case '$': 1003 | strcpy(&ret[j],"$");j+=8; 1004 | break; 1005 | case '#': 1006 | strcpy(&ret[j],"#");j+=5; 1007 | break; 1008 | case '%': 1009 | strcpy(&ret[j],"%");j+=8; 1010 | break; 1011 | case '~': 1012 | strcpy(&ret[j],"˜");j+=7; 1013 | break; 1014 | case '\n': 1015 | if(j && ret[j-1]=='\n') 1016 | { 1017 | strcpy(&ret[j],"<newline>");j+=9; 1018 | } 1019 | ret[j++]=c[i]; 1020 | break; 1021 | default: 1022 | ret[j++]=c[i]; 1023 | } 1024 | if(c[i]=='\n') 1025 | i+=CopyOrSkip(c+i,"sgml",©,&skip); 1026 | } 1027 | 1028 | if(c[i]) /* Not finished */ 1029 | { 1030 | if(malloced[which]) 1031 | malloced[which]=Realloc(malloced[which],len+delta+256); 1032 | else 1033 | {malloced[which]=Malloc(len+delta+256); strncpy(malloced[which],ret,(unsigned)j);} 1034 | ret=malloced[which]; 1035 | len+=256; 1036 | } 1037 | else 1038 | {ret[j]=0; break;} 1039 | } 1040 | } 1041 | 1042 | return(ret); 1043 | }