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