Autodoc corrections.
[cake.git] / tools / cxref / sgml.c
blob328d58db8a23f9e6bc8950cc00d023c170f0d98f
1 /***************************************
2 $Header$
4 C Cross Referencing & Documentation tool. Version 1.5f.
6 Writes the SGML output.
7 ******************/ /******************
8 Written by Andrew M. Bishop
10 This file Copyright 1995,96,97,98,2001,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 ***************************************/
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>
23 #include "memory.h"
24 #include "datatype.h"
25 #include "cxref.h"
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~"
31 /*+ The name of the output tex file that contains the appendix. +*/
32 #define SGML_APDX ".apdx"
34 /*+ The comments are to be inserted verbatim. +*/
35 extern int option_verbatim_comments;
37 /*+ The name of the directory for the output. +*/
38 extern char* option_odir;
40 /*+ The base name of the file for the output. +*/
41 extern char* option_name;
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. +*/
47 /*+ The directories to go back to get to the base output directory. +*/
48 static char* goback=NULL;
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);
59 static void WriteSGMLPreamble(FILE* f,char* title);
60 static void WriteSGMLPostamble(FILE* f);
62 static char* sgml(char* c,int verbatim);
64 /*+ The output file for the SGML. +*/
65 static FILE* of;
67 /*+ The name of the file. +*/
68 static char *filename;
71 /*++++++++++++++++++++++++++++++++++++++
72 Write an sgml file for a complete File structure and all components.
74 File file The File structure to output.
75 ++++++++++++++++++++++++++++++++++++++*/
77 void WriteSGMLFile(File file)
79 char* ofile;
80 int i;
82 filename=file->name;
84 /* Open the file */
86 ofile=ConcatStrings(4,option_odir,"/",file->name,SGML_FILE);
88 of=fopen(ofile,"w");
89 if(!of)
91 struct stat stat_buf;
92 int i,ofl=strlen(ofile);
94 for(i=strlen(option_odir)+1;i<ofl;i++)
95 if(ofile[i]=='/')
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]='/';
103 of=fopen(ofile,"w");
106 if(!of)
107 {fprintf(stderr,"cxref: Failed to open the SGML output file '%s'\n",ofile);exit(1);}
109 for(goback="",i=strlen(file->name);i>0;i--)
110 if(file->name[i]=='/')
111 goback=ConcatStrings(2,goback,"../");
113 /* Write out a header. */
115 WriteSGMLPreamble(of,ConcatStrings(5,"Cross reference for ",file->name," of ",option_name,"."));
117 /*+ The file structure is broken into its components and they are each written out. +*/
119 WriteSGMLFilePart(file);
121 if(file->includes)
123 Include inc =file->includes;
124 fprintf(of,"\n<sect1>Included Files\n\n<p>\n");
126 WriteSGMLInclude(inc);
128 while((inc=inc->next));
131 if(file->defines)
133 Define def =file->defines;
134 fprintf(of,"\n<sect1>Preprocessor definitions\n\n<p>\n");
136 if(def!=file->defines)
137 fprintf(of,"<p>\n");
138 WriteSGMLDefine(def);
140 while((def=def->next));
143 if(file->typedefs)
145 Typedef type=file->typedefs;
147 WriteSGMLTypedef(type);
149 while((type=type->next));
152 if(file->variables)
154 int any_to_mention=0;
155 Variable var=file->variables;
158 if(var->scope&(GLOBAL|LOCAL|EXTERNAL|EXTERN_F))
159 any_to_mention=1;
161 while((var=var->next));
163 if(any_to_mention)
165 int first_ext=1,first_local=1;
166 Variable var=file->variables;
168 if(var->scope&GLOBAL)
169 WriteSGMLVariable(var);
171 while((var=var->next));
172 var=file->variables;
174 if(var->scope&(EXTERNAL|EXTERN_F) && !(var->scope&GLOBAL))
176 if(first_ext)
177 {fprintf(of,"\n<sect1>External Variables\n\n"); first_ext=0;}
178 fprintf(of,"<p>\n");
179 WriteSGMLVariable(var);
182 while((var=var->next));
183 var=file->variables;
185 if(var->scope&LOCAL)
187 if(first_local)
188 {fprintf(of,"\n<sect1>Local Variables\n\n"); first_local=0;}
189 fprintf(of,"<p>\n");
190 WriteSGMLVariable(var);
193 while((var=var->next));
197 if(file->functions)
199 Function func=file->functions;
201 if(func->scope&(GLOBAL|EXTERNAL))
202 WriteSGMLFunction(func);
204 while((func=func->next));
205 func=file->functions;
207 if(func->scope&LOCAL)
208 WriteSGMLFunction(func);
210 while((func=func->next));
213 WriteSGMLPostamble(of);
215 fclose(of);
217 /* Clear the memory in sgml() */
219 sgml(NULL,0); sgml(NULL,0); sgml(NULL,0); sgml(NULL,0);
223 /*++++++++++++++++++++++++++++++++++++++
224 Write a File structure out.
226 File file The File to output.
227 ++++++++++++++++++++++++++++++++++++++*/
229 static void WriteSGMLFilePart(File file)
231 int i;
233 fprintf(of,"<sect>File %s\n",sgml(file->name,0));
235 if(file->comment)
237 if(option_verbatim_comments)
238 fprintf(of,"<p><tscreen><verb>\n%s\n</verb></tscreen>\n\n",sgml(file->comment,1));
239 else
241 char *rcs1=strstr(file->comment,"$Header"),*rcs2=NULL;
242 if(rcs1)
244 rcs2=strstr(&rcs1[1],"$");
245 if(rcs2)
247 rcs2[0]=0;
248 fprintf(of,"<bf>RCS %s</bf>\n<p>\n",sgml(&rcs1[1],0));
249 rcs2[0]='$';
252 if(rcs2)
253 fprintf(of,"%s\n<p>\n",sgml(&rcs2[2],0));
254 else
255 fprintf(of,"%s\n<p>\n",sgml(file->comment,0));
259 if(file->inc_in->n)
261 int i;
263 fprintf(of,"<p>\n<descrip>\n<tag>Included in:</tag>\n<itemize>\n");
264 for(i=0;i<file->inc_in->n;i++)
265 fprintf(of,"<item>%s\n",sgml(file->inc_in->s[i],0));
266 fprintf(of,"</itemize>\n</descrip>\n");
269 if(file->f_refs->n || file->v_refs->n)
270 fprintf(of,"<descrip>\n");
272 if(file->f_refs->n)
274 int others=0;
275 fprintf(of,"<tag>References Functions:</tag>\n<itemize>\n");
276 for(i=0;i<file->f_refs->n;i++)
277 if(file->f_refs->s2[i])
278 fprintf(of,"<item>%s() : %s\n",sgml(file->f_refs->s1[i],0),sgml(file->f_refs->s2[i],0));
279 else
280 others++;
282 if(others)
284 fprintf(of,"<item>");
285 for(i=0;i<file->f_refs->n;i++)
286 if(!file->f_refs->s2[i])
287 fprintf(of,--others?" %s(),":" %s()",sgml(file->f_refs->s1[i],0));
288 fprintf(of,"\n");
290 fprintf(of,"</itemize>\n");
293 if(file->v_refs->n)
295 int others=0;
296 fprintf(of,"<tag>References Variables:</tag>\n<itemize>\n");
297 for(i=0;i<file->v_refs->n;i++)
299 if(file->v_refs->s2[i])
300 fprintf(of,"<item>%s : %s\n",sgml(file->v_refs->s1[i],0),sgml(file->v_refs->s2[i],0));
301 else
302 others++;
305 if(others)
307 fprintf(of,"<item>");
308 for(i=0;i<file->v_refs->n;i++)
309 if(!file->v_refs->s2[i])
310 fprintf(of,--others?" %s,":" %s",sgml(file->v_refs->s1[i],0));
311 fprintf(of,"\n");
313 fprintf(of,"</itemize>\n");
316 if(file->f_refs->n || file->v_refs->n)
317 fprintf(of,"</descrip>\n");
321 /*++++++++++++++++++++++++++++++++++++++
322 Write an Include structure out.
324 Include inc The Include structure to output.
325 ++++++++++++++++++++++++++++++++++++++*/
327 static void WriteSGMLInclude(Include inc)
329 if(inc->comment)
330 fprintf(of,"%s\n<p>\n",sgml(inc->comment,0));
332 fprintf(of,"<itemize>\n");
334 if(inc->scope==LOCAL)
335 fprintf(of,"<item><tt>#include &quot;%s&quot;</tt>\n",sgml(inc->name,0));
336 else
337 fprintf(of,"<item><tt>#include &lt;%s&gt;</tt>\n",sgml(inc->name,0));
339 if(inc->includes)
340 WriteSGMLSubInclude(inc->includes,1);
342 fprintf(of,"</itemize>\n");
346 /*++++++++++++++++++++++++++++++++++++++
347 Write an Sub Include structure out. (An include structure that is included from another file.)
349 Include inc The Include structure to output.
351 int depth The depth of the include hierarchy.
352 ++++++++++++++++++++++++++++++++++++++*/
354 static void WriteSGMLSubInclude(Include inc,int depth)
356 fprintf(of,"<itemize>\n");
358 while(inc)
360 if(inc->scope==LOCAL)
361 fprintf(of,"<item><tt>#include &quot;%s&quot;</tt>\n",sgml(inc->name,0));
362 else
363 fprintf(of,"<item><tt>#include &lt;%s&gt;</tt>\n",sgml(inc->name,0));
365 if(inc->includes)
366 WriteSGMLSubInclude(inc->includes,depth+1);
368 inc=inc->next;
371 fprintf(of,"</itemize>\n");
375 /*++++++++++++++++++++++++++++++++++++++
376 Write a Define structure out.
378 Define def The Define structure to output.
379 ++++++++++++++++++++++++++++++++++++++*/
381 static void WriteSGMLDefine(Define def)
383 int i;
384 int pargs=0;
386 if(def->comment)
387 fprintf(of,"%s\n<p>\n",sgml(def->comment,0));
389 fprintf(of,"<tt>#define %s",sgml(def->name,0));
391 if(def->value)
392 fprintf(of," %s",sgml(def->value,0));
394 if(def->args->n)
396 fprintf(of,"( ");
397 for(i=0;i<def->args->n;i++)
398 fprintf(of,i?", %s":"%s",sgml(def->args->s1[i],0));
399 fprintf(of," )");
401 fprintf(of,"</tt><newline>\n");
403 for(i=0;i<def->args->n;i++)
404 if(def->args->s2[i])
405 pargs=1;
407 if(pargs)
409 fprintf(of,"<descrip>\n");
410 for(i=0;i<def->args->n;i++)
411 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):"");
412 fprintf(of,"</descrip>\n");
417 /*++++++++++++++++++++++++++++++++++++++
418 Write a Typedef structure out.
420 Typedef type The Typedef structure to output.
421 ++++++++++++++++++++++++++++++++++++++*/
423 static void WriteSGMLTypedef(Typedef type)
425 fprintf(of,"\n<sect1>");
427 if(type->type)
428 fprintf(of,"Typedef %s",sgml(type->name,0));
429 else
430 fprintf(of,"Type %s",sgml(type->name,0));
432 fprintf(of,"\n\n<p>\n");
434 if(type->comment)
435 fprintf(of,"%s\n<p>\n",sgml(type->comment,0));
437 if(type->type)
438 fprintf(of,"<tt>typedef %s</tt><newline>\n",sgml(type->type,0));
440 if(type->sutype)
442 fprintf(of,"<itemize>\n");
443 WriteSGMLStructUnion(type->sutype,0);
444 fprintf(of,"</itemize>\n");
446 else
447 if(type->typexref)
449 fprintf(of,"<descrip>\n<tag>See:</tag>\n<itemize>\n");
450 if(type->typexref->type)
451 fprintf(of,"<item>Typedef %s\n",sgml(type->typexref->name,0));
452 else
453 if(!strncmp("enum",type->typexref->name,4))
454 fprintf(of,"<item>Type %s\n",sgml(type->typexref->name,0));
455 else
456 if(!strncmp("union",type->typexref->name,5))
457 fprintf(of,"<item>Type %s\n",sgml(type->typexref->name,0));
458 else
459 if(!strncmp("struct",type->typexref->name,6))
460 fprintf(of,"<item>Type %s\n",sgml(type->typexref->name,0));
461 fprintf(of,"</itemize>\n</descrip>\n");
466 /*++++++++++++++++++++++++++++++++++++++
467 Write a structure / union structure out.
469 StructUnion su The structure / union to write.
471 int depth The current depth within the structure.
472 ++++++++++++++++++++++++++++++++++++++*/
474 static void WriteSGMLStructUnion(StructUnion su, int depth)
476 int i;
477 char* splitsu=NULL;
479 splitsu=strstr(su->name,"{...}");
480 if(splitsu) splitsu[-1]=0;
482 if(depth && su->comment && !su->comps)
483 fprintf(of,"<item><tt>%s; </tt>%s<newline>\n",sgml(su->name,0),sgml(su->comment,0));
484 else if(!depth || su->comps)
485 fprintf(of,"<item><tt>%s</tt><newline>\n",sgml(su->name,0));
486 else
487 fprintf(of,"<item><tt>%s;</tt><newline>\n",sgml(su->name,0));
489 if(!depth || su->comps)
491 fprintf(of,"<itemize>\n");
493 fprintf(of,"<item><tt>{</tt><newline>\n");
495 for(i=0;i<su->n_comp;i++)
496 WriteSGMLStructUnion(su->comps[i],depth+1);
498 fprintf(of,"<item><tt>}</tt><newline>\n");
500 fprintf(of,"</itemize>\n");
502 if(splitsu)
504 if(depth && su->comment)
505 fprintf(of,"<item><tt>%s; </tt>%s<newline>\n",splitsu[5]?sgml(&splitsu[6],0):"",sgml(su->comment,0));
506 else
507 fprintf(of,"<item><tt>%s;</tt><newline>\n",splitsu[5]?sgml(&splitsu[6],0):"");
511 if(splitsu) splitsu[-1]=' ';
515 /*++++++++++++++++++++++++++++++++++++++
516 Write a Variable structure out.
518 Variable var The Variable structure to output.
519 ++++++++++++++++++++++++++++++++++++++*/
521 static void WriteSGMLVariable(Variable var)
523 int i;
525 if(var->scope&GLOBAL)
526 fprintf(of,"\n<sect1>Global Variable %s\n\n<p>\n",sgml(var->name,0));
527 else
528 fprintf(of,"<bf>%s</bf><newline>\n",sgml(var->name,0));
530 if(var->comment)
531 fprintf(of,"%s\n<p>\n",sgml(var->comment,0));
533 fprintf(of,"<tt>");
535 if(var->scope&LOCAL)
536 fprintf(of,"static ");
537 else
538 if(!(var->scope&GLOBAL) && var->scope&(EXTERNAL|EXTERN_F))
539 fprintf(of,"extern ");
541 fprintf(of,"%s</tt><newline>\n",sgml(var->type,0));
543 if(var->scope&(GLOBAL|LOCAL))
545 if(var->incfrom || var->visible->n || var->used->n)
546 fprintf(of,"<descrip>\n");
548 if(var->incfrom)
550 fprintf(of,"<tag>Included from:</tag>\n<itemize>\n");
551 fprintf(of,"<item>%s\n",sgml(var->incfrom,0));
552 fprintf(of,"</itemize>\n");
555 if(var->visible->n)
557 fprintf(of,"<tag>Visible in:</tag>\n<itemize>\n");
558 for(i=0;i<var->visible->n;i++)
559 if(var->visible->s1[i][0]=='$' && !var->visible->s1[i][1])
560 fprintf(of,"<item>%s\n",sgml(var->visible->s2[i],0));
561 else
562 fprintf(of,"<item>%s() : %s\n",sgml(var->visible->s1[i],0),sgml(var->visible->s2[i],0));
563 fprintf(of,"</itemize>\n");
566 if(var->used->n)
568 fprintf(of,"<tag>Used in:</tag>\n<itemize>\n");
569 for(i=0;i<var->used->n;i++)
571 if(var->used->s1[i][0]=='$' && !var->used->s1[i][1])
572 fprintf(of,"<item>%s\n",sgml(var->used->s2[i],0));
573 else
575 if(var->scope&LOCAL)
576 fprintf(of,"<item>%s()\n",sgml(var->used->s1[i],0));
577 else
578 fprintf(of,"<item>%s() : %s\n",sgml(var->used->s1[i],0),sgml(var->used->s2[i],0));
581 fprintf(of,"</itemize>\n");
584 if(var->incfrom || var->visible->n || var->used->n)
585 fprintf(of,"</descrip>\n");
587 else
588 if(var->scope&(EXTERNAL|EXTERN_F) && var->defined)
590 fprintf(of,"<descrip>\n<tag>Defined in:</tag>\n<itemize>\n");
591 fprintf(of,"<item>%s",sgml(var->name,0));
592 fprintf(of,"</itemize>\n</descrip>\n");
597 /*++++++++++++++++++++++++++++++++++++++
598 Write a Function structure out.
600 Function func The Function structure to output.
601 ++++++++++++++++++++++++++++++++++++++*/
603 static void WriteSGMLFunction(Function func)
605 int i,pret,pargs;
606 char* comment2=NULL,*type;
608 if(func->scope&(GLOBAL|EXTERNAL))
609 fprintf(of,"\n<sect1>Global Function %s()\n\n<p>",sgml(func->name,0));
610 else
611 fprintf(of,"\n<sect1>Local Function %s()\n\n<p>",sgml(func->name,0));
613 if(func->comment)
615 if(option_verbatim_comments)
616 fprintf(of,"<tscreen><verb>\n%s\n</verb></tscreen>\n\n",sgml(func->comment,1));
617 else
619 comment2=strstr(func->comment,"\n\n");
620 if(comment2)
621 comment2[0]=0;
622 fprintf(of,"%s\n<p>\n",sgml(func->comment,0));
626 fprintf(of,"<tt>");
628 if(func->scope&LOCAL)
629 fprintf(of,"static ");
630 if(func->scope&INLINED)
631 fprintf(of,"inline ");
633 if((type=strstr(func->type,"()")))
634 type[0]=0;
635 fprintf(of,"%s ( ",sgml(func->type,0));
637 for(i=0;i<func->args->n;i++)
638 fprintf(of,i?", %s":"%s",sgml(func->args->s1[i],0));
640 if(type)
641 {fprintf(of," %s</tt><newline>\n",sgml(&type[1],0));type[0]='(';}
642 else
643 fprintf(of," )</tt><newline>\n");
645 pret =strncmp("void ",func->type,5) && func->cret;
646 for(pargs=0,i=0;i<func->args->n;i++)
647 pargs = pargs || ( strcmp("void",func->args->s1[i]) && func->args->s2[i] );
649 if(pret || pargs)
651 fprintf(of,"<descrip>\n");
652 if(pret)
653 fprintf(of,"<tag><tt>%s</tt></tag>\n%s\n",sgml(func->type,0),func->cret?sgml(func->cret,0):"&nbsp;");
654 if(pargs)
655 for(i=0;i<func->args->n;i++)
656 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):"&nbsp;");
657 fprintf(of,"</descrip>\n");
660 if(comment2)
662 fprintf(of,"%s\n<p>\n",sgml(&comment2[2],0));
663 comment2[0]='\n';
666 if(func->protofile || func->incfrom || func->calls->n || func->called->n || func->used->n || func->f_refs->n || func->v_refs->n)
667 fprintf(of,"<descrip>\n");
669 if(func->protofile)
671 fprintf(of,"<tag>Prototyped in:</tag>\n<itemize>\n");
672 fprintf(of,"<item>%s\n",sgml(func->protofile,0));
673 fprintf(of,"</itemize>\n");
676 if(func->incfrom)
678 fprintf(of,"<tag>Included from:</tag>\n<itemize>\n");
679 fprintf(of,"<item>%s\n",sgml(func->incfrom,0));
680 fprintf(of,"</itemize>\n");
683 if(func->calls->n)
685 int others=0;
686 fprintf(of,"<tag>Calls:</tag>\n<itemize>\n");
687 for(i=0;i<func->calls->n;i++)
689 if(func->calls->s2[i])
690 fprintf(of,"<item>%s() : %s\n",sgml(func->calls->s1[i],0),sgml(func->calls->s2[i],0));
691 else
692 others++;
695 if(others)
697 fprintf(of,"<item>");
698 for(i=0;i<func->calls->n;i++)
699 if(!func->calls->s2[i])
700 fprintf(of,--others?"%s(), ":"%s()",sgml(func->calls->s1[i],0));
701 fprintf(of,"\n");
703 fprintf(of,"</itemize>\n");
706 if(func->called->n)
708 fprintf(of,"<tag>Called by:</tag>\n<itemize>\n");
709 for(i=0;i<func->called->n;i++)
710 fprintf(of,"<item>%s() : %s\n",sgml(func->called->s1[i],0),sgml(func->called->s2[i],0));
711 fprintf(of,"</itemize>\n");
714 if(func->used->n)
716 fprintf(of,"<tag>Used in:</tag>\n<itemize>\n");
717 for(i=0;i<func->used->n;i++)
719 if(func->used->s1[i][0]=='$' && !func->used->s1[i][1])
720 fprintf(of,"<item>%s\n",sgml(func->used->s2[i],0));
721 else
722 fprintf(of,"<item>%s() : %s\n",sgml(func->used->s1[i],0),sgml(func->used->s2[i],0));
724 fprintf(of,"</itemize>\n");
727 if(func->f_refs->n)
729 int others=0;
730 fprintf(of,"<tag>References Functions:</tag>\n<itemize>\n");
731 for(i=0;i<func->f_refs->n;i++)
733 if(func->f_refs->s2[i])
734 fprintf(of,"<item>%s() : %s\n",sgml(func->f_refs->s1[i],0),sgml(func->f_refs->s2[i],0));
735 else
736 others++;
739 if(others)
741 fprintf(of,"<item>");
742 for(i=0;i<func->f_refs->n;i++)
743 if(!func->f_refs->s2[i])
744 fprintf(of,--others?"%s(), ":"%s()",sgml(func->f_refs->s1[i],0));
745 fprintf(of,"\n");
747 fprintf(of,"</itemize>\n");
750 if(func->v_refs->n)
752 int others=0;
753 fprintf(of,"<tag>References Variables:</tag>\n<itemize>\n");
754 for(i=0;i<func->v_refs->n;i++)
756 if(func->v_refs->s2[i])
757 fprintf(of,"<item>%s : %s\n",sgml(func->v_refs->s1[i],0),sgml(func->v_refs->s2[i],0));
758 else
759 others++;
762 if(others)
764 fprintf(of,"<item>");
765 for(i=0;i<func->v_refs->n;i++)
766 if(!func->v_refs->s2[i])
767 fprintf(of,--others?"%s, ":"%s",sgml(func->v_refs->s1[i],0));
768 fprintf(of,"\n");
770 fprintf(of,"</itemize>\n");
773 if(func->protofile || func->incfrom || func->calls->n || func->called->n || func->used->n || func->f_refs->n || func->v_refs->n)
774 fprintf(of,"</descrip>\n");
778 /*++++++++++++++++++++++++++++++++++++++
779 Write out a standard pre-amble.
781 FILE* f The file to write the pre amble to.
783 char* title The title of the file.
784 ++++++++++++++++++++++++++++++++++++++*/
786 static void WriteSGMLPreamble(FILE* f,char* title)
788 fputs("<!DOCTYPE LINUXDOC SYSTEM>\n",f);
789 fputs("\n",f);
790 fputs("<!-- This SGML file generated by cxref. -->\n",f);
791 fputs("<!-- cxref program (c) Andrew M. Bishop 1995,96,97,98,99. -->\n",f);
792 fputs("\n",f);
793 fputs("<!--\n",f);
794 if(filename)
795 fprintf(f,"Cxref: %s %s\n",run_command,filename);
796 else
797 fprintf(f,"Cxref: %s\n",run_command);
798 fprintf(f,"CPP : %s\n",run_cpp_command);
799 fputs("-->\n",f);
800 fputs("\n",f);
801 fputs("<article>\n",f);
802 fputs("\n",f);
803 fputs("<title>",f);
804 fputs(title,f);
805 fputs("\n",f);
806 fputs("<author>cxref\n",f);
807 fputs("\n",f);
811 /*++++++++++++++++++++++++++++++++++++++
812 Write out a standard post-amble. This includes the end of document marker.
814 FILE* f The file to write the post amble to.
815 ++++++++++++++++++++++++++++++++++++++*/
817 static void WriteSGMLPostamble(FILE* f)
819 fputs("\n",f);
820 fputs("</article>\n",f);
824 /*++++++++++++++++++++++++++++++++++++++
825 Write out the appendix information.
827 StringList files The list of files to write.
829 StringList2 funcs The list of functions to write.
831 StringList2 vars The list of variables to write.
833 StringList2 types The list of types to write.
834 ++++++++++++++++++++++++++++++++++++++*/
836 void WriteSGMLAppendix(StringList files,StringList2 funcs,StringList2 vars,StringList2 types)
838 char* ofile;
839 int i;
841 filename=NULL;
843 /* Open the file */
845 ofile=ConcatStrings(5,option_odir,"/",option_name,SGML_APDX,SGML_FILE);
847 of=fopen(ofile,"w");
849 if(!of)
850 {fprintf(stderr,"cxref: Failed to open the SGML appendix file '%s'\n",ofile);exit(1);}
852 /* Write the file structure out */
854 WriteSGMLPreamble(of,ConcatStrings(3,"Cross reference index of ",option_name,"."));
856 fprintf(of,"<sect>Cross References\n");
858 /* Write out the appendix of files. */
860 if(files->n)
862 fprintf(of,"\n<sect1>Files\n\n<p>\n");
863 fprintf(of,"<itemize>\n");
864 for(i=0;i<files->n;i++)
865 fprintf(of,"<item>%s>\n",sgml(files->s[i],0));
866 fprintf(of,"</itemize>\n");
869 /* Write out the appendix of functions. */
871 if(funcs->n)
873 fprintf(of,"\n<sect1>Global Functions\n\n<p>\n");
874 fprintf(of,"<itemize>\n");
875 for(i=0;i<funcs->n;i++)
876 fprintf(of,"<item>%s() : %s\n",sgml(funcs->s1[i],0),sgml(funcs->s2[i],0));
877 fprintf(of,"</itemize>\n");
880 /* Write out the appendix of variables. */
882 if(vars->n)
884 fprintf(of,"\n<sect1>Global Variables\n\n<p>\n");
885 fprintf(of,"<itemize>\n");
886 for(i=0;i<vars->n;i++)
887 fprintf(of,"<item>%s : %s\n",sgml(vars->s1[i],0),sgml(vars->s2[i],0));
888 fprintf(of,"</itemize>\n");
891 /* Write out the appendix of types. */
893 if(types->n)
895 fprintf(of,"\n<sect1>Defined Types\n\n<p>\n");
896 fprintf(of,"<itemize>\n");
897 for(i=0;i<types->n;i++)
898 if(!strncmp("enum",types->s1[i],4))
899 fprintf(of,"<item>%s : %s\n",sgml(types->s1[i],0),sgml(types->s2[i],0));
900 else
901 if(!strncmp("union",types->s1[i],5))
902 fprintf(of,"<item>%s : %s\n",sgml(types->s1[i],0),sgml(types->s2[i],0));
903 else
904 if(!strncmp("struct",types->s1[i],6))
905 fprintf(of,"<item>%s : %s\n",sgml(types->s1[i],0),sgml(types->s2[i],0));
906 else
907 fprintf(of,"<item>%s : %s\n",sgml(types->s1[i],0),sgml(types->s2[i],0));
908 fprintf(of,"</itemize>\n");
911 WriteSGMLPostamble(of);
913 fclose(of);
915 /* Clear the memory in sgml(,0) */
917 sgml(NULL,0); sgml(NULL,0); sgml(NULL,0); sgml(NULL,0);
921 /*++++++++++++++++++++++++++++++++++++++
922 Delete the SGML file and main file reference that belong to the named file.
924 char *name The name of the file to delete.
925 ++++++++++++++++++++++++++++++++++++++*/
927 void WriteSGMLFileDelete(char *name)
929 char *ofile;
931 ofile=ConcatStrings(4,option_odir,"/",name,SGML_FILE);
932 unlink(ofile);
936 /*++++++++++++++++++++++++++++++++++++++
937 Make the input string safe to output as SGML ( not <, >, &, ", $, #, % or ~ ).
939 char* sgml Returns a safe SGML string.
941 char* c A non-safe SGML string.
943 int verbatim Set to true inside a verbatim environment.
945 The function can only be called four times in each fprintf() since it returns one of only four static strings.
946 ++++++++++++++++++++++++++++++++++++++*/
948 static char* sgml(char* c,int verbatim)
950 static char safe[4][256],*malloced[4]={NULL,NULL,NULL,NULL};
951 static int which=0;
952 int copy=0,skip=0;
953 int i=0,j=0,delta=10,len=256-delta;
954 char* ret;
956 which=(which+1)%4;
957 ret=safe[which];
959 safe[which][0]=0;
961 if(malloced[which])
962 {Free(malloced[which]);malloced[which]=NULL;}
964 if(c)
966 i=CopyOrSkip(c,"sgml",&copy,&skip);
968 while(1)
970 for(;j<len && c[i];i++)
972 if(copy)
973 {ret[j++]=c[i]; if(c[i]=='\n') copy=0;}
974 else if(skip)
975 { if(c[i]=='\n') skip=0;}
976 else if(verbatim)
977 switch(c[i])
979 case '&':
980 strcpy(&ret[j],"&ero;");j+=5;
981 break;
982 case '<':
983 if(c[i+1]=='/')
984 {strcpy(&ret[j],"&etago;");j+=7; break;}
985 default:
986 ret[j++]=c[i];
988 else
989 switch(c[i])
991 case '<':
992 if(c[i+1]=='/')
993 {strcpy(&ret[j],"&etago;");j+=7;}
994 else
995 {strcpy(&ret[j],"&lt;");j+=4;}
996 break;
997 case '>':
998 strcpy(&ret[j],"&gt;");j+=4;
999 break;
1000 case '"':
1001 strcpy(&ret[j],"&quot;");j+=6;
1002 break;
1003 case '&':
1004 strcpy(&ret[j],"&amp;");j+=5;
1005 break;
1006 case '$':
1007 strcpy(&ret[j],"&dollar;");j+=8;
1008 break;
1009 case '#':
1010 strcpy(&ret[j],"&num;");j+=5;
1011 break;
1012 case '%':
1013 strcpy(&ret[j],"&percnt;");j+=8;
1014 break;
1015 case '~':
1016 strcpy(&ret[j],"&tilde;");j+=7;
1017 break;
1018 case '\n':
1019 if(j && ret[j-1]=='\n')
1021 strcpy(&ret[j],"<newline>");j+=9;
1023 ret[j++]=c[i];
1024 break;
1025 default:
1026 ret[j++]=c[i];
1028 if(c[i]=='\n')
1029 i+=CopyOrSkip(c+i,"sgml",&copy,&skip);
1032 if(c[i]) /* Not finished */
1034 if(malloced[which])
1035 malloced[which]=Realloc(malloced[which],len+delta+256);
1036 else
1037 {malloced[which]=Malloc(len+delta+256); strncpy(malloced[which],ret,(unsigned)j);}
1038 ret=malloced[which];
1039 len+=256;
1041 else
1042 {ret[j]=0; break;}
1046 return(ret);