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