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