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