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