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