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