Converted png_au.library into the MorphOS-compatible png.library. All
[AROS.git] / tools / cxref / latex.c
blob0d9f3c7b5fd86b223b32dce4f42ea1f48278d519
1 /***************************************
2 $Header$
4 C Cross Referencing & Documentation tool. Version 1.5f.
6 Writes the Latex output.
7 ******************/ /******************
8 Written by Andrew M. Bishop
10 This file Copyright 1995,96,97,98,2001,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 ***************************************/
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>
23 #ifndef min
24 #define min(x,y) ( (x) < (y) ? (x) : (y) )
25 #endif
27 #include "memory.h"
28 #include "datatype.h"
29 #include "cxref.h"
31 /*+ The name of the output tex file that includes each of the others. +*/
32 #define LATEX_FILE ".tex"
33 #define LATEX_FILE_BACKUP ".tex~"
35 /*+ The name of the output tex file that contains the appendix. +*/
36 #define LATEX_APDX ".apdx"
38 /*+ The comments are to be inserted verbatim. +*/
39 extern int option_verbatim_comments;
41 /*+ The type of LaTeX output to produce. +*/
42 extern int option_latex;
44 /*+ The name of the directory for the output. +*/
45 extern char* option_odir;
47 /*+ The base name of the file for the output. +*/
48 extern char* option_name;
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. +*/
54 extern char *latex_fonts_style,*latex_page_style,*latex_cxref_style;
56 static void WriteLatexFilePart(File file);
57 static void WriteLatexInclude(Include inc);
58 static void WriteLatexSubInclude(Include inc,int depth);
59 static void WriteLatexDefine(Define def);
60 static void WriteLatexTypedef(Typedef type,char* filename);
61 static void WriteLatexStructUnion(StructUnion su,int depth);
62 static void WriteLatexVariable(Variable var,char* filename);
63 static void WriteLatexFunction(Function func,char* filename);
65 static void WriteLatexDocument(char* name,int appendix);
66 static void WriteLatexTemplate(char* name);
68 static char* latex(char* c,int verbatim);
70 /*+ The output file for the latex. +*/
71 static FILE* of;
73 /*+ Counts the lines in a table to insert breaks. +*/
74 static int countlines=0;
77 /*++++++++++++++++++++++++++++++++++++++
78 Write a Latex file for a complete File structure and all components.
80 File file The File structure to output.
81 ++++++++++++++++++++++++++++++++++++++*/
83 void WriteLatexFile(File file)
85 char* ofile;
87 /* Write the including file. */
89 WriteLatexDocument(file->name,0);
91 /* Open the file */
93 ofile=ConcatStrings(4,option_odir,"/",file->name,LATEX_FILE);
95 of=fopen(ofile,"w");
96 if(!of)
98 struct stat stat_buf;
99 int i,ofl=strlen(ofile);
101 for(i=strlen(option_odir)+1;i<ofl;i++)
102 if(ofile[i]=='/')
104 ofile[i]=0;
105 if(stat(ofile,&stat_buf))
106 mkdir(ofile,S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
107 ofile[i]='/';
110 of=fopen(ofile,"w");
113 if(!of)
114 {fprintf(stderr,"cxref: Failed to open the LaTeX output file '%s'\n",ofile);exit(1);}
116 /* Write out a header. */
118 fputs("% This LaTeX file generated by cxref\n",of);
119 fputs("% cxref program (c) Andrew M. Bishop 1995,96,97,98,99.\n",of);
120 fputs("\n",of);
121 fprintf(of,"%% Cxref: %s %s\n",run_command,file->name);
122 fprintf(of,"%% CPP : %s\n",run_cpp_command);
123 fputs("\n",of);
125 /*+ The file structure is broken into its components and they are each written out. +*/
127 WriteLatexFilePart(file);
129 if(file->includes)
131 Include inc =file->includes;
132 fprintf(of,"\n\\subsection*{Included Files}\n\n");
134 if(inc!=file->includes)
135 fprintf(of,"\\medskip\n");
136 WriteLatexInclude(inc);
138 while((inc=inc->next));
141 if(file->defines)
143 Define def =file->defines;
144 fprintf(of,"\n\\subsection*{Preprocessor definitions}\n\n");
146 if(def!=file->defines)
147 fprintf(of,"\\medskip\n");
148 WriteLatexDefine(def);
150 while((def=def->next));
153 if(file->typedefs)
155 Typedef type=file->typedefs;
156 fprintf(of,"\n\\subsection{Type definitions}\n\n");
158 WriteLatexTypedef(type,file->name);
160 while((type=type->next));
163 if(file->variables)
165 int any_to_mention=0;
166 Variable var=file->variables;
169 if(var->scope&(GLOBAL|LOCAL|EXTERNAL|EXTERN_F))
170 any_to_mention=1;
172 while((var=var->next));
174 if(any_to_mention)
176 int first_ext=1,first_local=1;
177 Variable var=file->variables;
178 fprintf(of,"\n\\subsection{Variables}\n\n");
180 if(var->scope&GLOBAL)
181 WriteLatexVariable(var,file->name);
183 while((var=var->next));
184 var=file->variables;
186 if(var->scope&(EXTERNAL|EXTERN_F) && !(var->scope&GLOBAL))
188 if(first_ext)
189 {fprintf(of,"\n\\subsubsection{External Variables}\n\n"); first_ext=0;}
190 else
191 fprintf(of,"\\medskip\n");
192 WriteLatexVariable(var,file->name);
195 while((var=var->next));
196 var=file->variables;
198 if(var->scope&LOCAL)
200 if(first_local)
201 {fprintf(of,"\n\\subsubsection{Local Variables}\n\n"); first_local=0;}
202 else
203 fprintf(of,"\\medskip\n");
204 WriteLatexVariable(var,file->name);
207 while((var=var->next));
211 if(file->functions)
213 Function func=file->functions;
214 fprintf(of,"\n\\subsection{Functions}\n\n");
216 if(func->scope&(GLOBAL|EXTERNAL))
217 WriteLatexFunction(func,file->name);
219 while((func=func->next));
220 func=file->functions;
222 if(func->scope&LOCAL)
223 WriteLatexFunction(func,file->name);
225 while((func=func->next));
228 fclose(of);
230 /* Clear the memory in latex() */
232 latex(NULL,0); latex(NULL,0); latex(NULL,0); latex(NULL,0);
236 /*++++++++++++++++++++++++++++++++++++++
237 Write a File structure out.
239 File file The File to output.
240 ++++++++++++++++++++++++++++++++++++++*/
242 static void WriteLatexFilePart(File file)
244 int i;
246 fprintf(of,"\\markboth{File %s}{File %s}\n",latex(file->name,0),latex(file->name,0));
247 fprintf(of,"\\section{File %s}\n",latex(file->name,0));
248 fprintf(of,"\\label{file_%s}\n\n",file->name);
250 if(file->comment)
252 if(option_verbatim_comments)
253 fprintf(of,"\\begin{verbatim}\n%s\n\\end{verbatim}\n\n",latex(file->comment,1));
254 else
256 char *rcs1=strstr(file->comment,"$Header"),*rcs2=NULL;
257 if(rcs1)
259 rcs2=strstr(&rcs1[1],"$");
260 if(rcs2)
262 rcs2[0]=0;
263 fprintf(of,"{\\bf RCS %s}\n\n",latex(&rcs1[1],0));
264 fprintf(of,"\\smallskip\n");
265 rcs2[0]='$';
268 if(rcs2)
269 fprintf(of,"%s\n\n",latex(&rcs2[2],0));
270 else
271 fprintf(of,"%s\n\n",latex(file->comment,0));
275 if(file->inc_in->n)
277 int i;
279 if(file->comment)
280 fprintf(of,"\\medskip\n");
281 fprintf(of,"\\begin{cxreftabii}\nIncluded in:");
282 for(i=0;i<file->inc_in->n;i++)
283 {/* Allow a break in every 8 (or so) items to allow the table to break over the page. */
284 if(min(i,file->inc_in->n-i)%8 == 4)
285 fprintf(of,"\\cxreftabbreak{cxreftabii}\n");
286 fprintf(of,"\\ & %s & \\cxreffile{%s}\\\\\n",latex(file->inc_in->s[i],0),file->inc_in->s[i]);
288 fprintf(of,"\\end{cxreftabii}\n\n");
291 if(file->f_refs->n || file->v_refs->n)
293 int tabcount=0;
294 fprintf(of,"\\smallskip\n");
295 fprintf(of,"\\begin{cxreftabiii}\n");
297 if(file->f_refs->n)
299 int others=0;
301 fprintf(of,"Refs Func:");
303 for(i=0;i<file->f_refs->n;i++)
304 if(file->f_refs->s2[i])
306 fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(file->f_refs->s1[i],0),latex(file->f_refs->s2[i],0),file->f_refs->s1[i],file->f_refs->s2[i]);
307 if(++tabcount%8 == 4)
308 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
310 else
311 others++;
313 if(others)
315 fprintf(of,"\\ & \\cxreftabiiispan{");
316 for(i=0;i<file->f_refs->n;i++)
317 if(!file->f_refs->s2[i])
318 fprintf(of,--others?"%s(), ":"%s()",latex(file->f_refs->s1[i],0));
319 fprintf(of,"} &\\\\\n");
323 if(file->v_refs->n)
325 int others=0;
327 fprintf(of,"Refs Var:");
329 for(i=0;i<file->v_refs->n;i++)
330 if(file->v_refs->s2[i])
332 fprintf(of,"\\ & %s & %s & \\cxrefvar{%s}{%s}\\\\\n",latex(file->v_refs->s1[i],0),latex(file->v_refs->s2[i],0),file->v_refs->s1[i],file->v_refs->s2[i]);
333 if(++tabcount%8 == 4)
334 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
336 else
337 others++;
339 if(others)
341 fprintf(of,"\\ & \\cxreftabiiispan{");
342 for(i=0;i<file->v_refs->n;i++)
343 if(!file->v_refs->s2[i])
344 fprintf(of,--others?" %s,":" %s",latex(file->v_refs->s1[i],0));
345 fprintf(of,"} &\\\\\n");
349 fprintf(of,"\\end{cxreftabiii}\n\n");
354 /*++++++++++++++++++++++++++++++++++++++
355 Write an Include structure out.
357 Include inc The Include structure to output.
358 ++++++++++++++++++++++++++++++++++++++*/
360 static void WriteLatexInclude(Include inc)
362 if(inc->comment)
363 fprintf(of,"%s\n\n\\smallskip\n",latex(inc->comment,0));
365 fprintf(of,"\\begin{cxreftabi}\n"); countlines=1;
367 if(inc->scope==LOCAL)
368 fprintf(of,"{\\stt \\#include \"%s\"} &\\cxreffile{%s}\\\\\n",latex(inc->name,0),inc->name);
369 else
370 fprintf(of,"{\\stt \\#include <%s>} &\\\\\n",latex(inc->name,0));
372 if(inc->includes)
373 WriteLatexSubInclude(inc->includes,1);
375 fprintf(of,"\\end{cxreftabi}\n\n");
379 /*++++++++++++++++++++++++++++++++++++++
380 Write an Sub Include structure out. (An include structure that is included from another file.)
382 Include inc The Include structure to output.
384 int depth The depth of the include hierarchy.
385 ++++++++++++++++++++++++++++++++++++++*/
387 static void WriteLatexSubInclude(Include inc,int depth)
389 while(inc)
391 if(countlines++%8==4)
392 fprintf(of,"\\cxreftabbreak{cxreftabi}\n");
394 fprintf(of,"\\hspace*{%3.1fin}",0.2*depth);
396 if(inc->scope==LOCAL)
397 fprintf(of,"{\\stt \\#include \"%s\"} &\\cxreffile{%s}\\\\\n",latex(inc->name,0),inc->name);
398 else
399 fprintf(of,"{\\stt \\#include <%s>} &\\\\\n",latex(inc->name,0));
401 if(inc->includes)
402 WriteLatexSubInclude(inc->includes,depth+1);
404 inc=inc->next;
409 /*++++++++++++++++++++++++++++++++++++++
410 Write a Define structure out.
412 Define def The Define structure to output.
413 ++++++++++++++++++++++++++++++++++++++*/
415 static void WriteLatexDefine(Define def)
417 int i;
418 int pargs=0;
420 if(def->comment)
421 fprintf(of,"%s\n\n\\smallskip\n",latex(def->comment,0));
423 fprintf(of,"{\\stt \\#define %s",latex(def->name,0));
425 if(def->value)
426 fprintf(of," %s",latex(def->value,0));
428 if(def->args->n)
430 fprintf(of,"( ");
431 for(i=0;i<def->args->n;i++)
432 fprintf(of,i?", %s":"%s",latex(def->args->s1[i],0));
433 fprintf(of," )");
435 fprintf(of,"}\n\n");
437 for(i=0;i<def->args->n;i++)
438 if(def->args->s2[i])
439 pargs=1;
441 if(pargs)
443 fprintf(of,"\\smallskip\n");
444 fprintf(of,"\\begin{cxrefarglist}\n");
445 for(i=0;i<def->args->n;i++)
446 fprintf(of,"\\cxrefargitem{%s} %s\n",latex(def->args->s1[i],0),def->args->s2[i]?latex(def->args->s2[i],0):"\\ ");
447 fprintf(of,"\\end{cxrefarglist}\n\n");
452 /*++++++++++++++++++++++++++++++++++++++
453 Write a Typedef structure out.
455 Typedef type The Typedef structure to output.
457 char* filename The name of the file that is being processed (required for the cross reference label).
458 ++++++++++++++++++++++++++++++++++++++*/
460 static void WriteLatexTypedef(Typedef type,char* filename)
462 if(type->type)
463 fprintf(of,"\n\\subsubsection{Typedef %s}\n",latex(type->name,0));
464 else
465 fprintf(of,"\n\\subsubsection{Type %s}\n",latex(type->name,0));
467 if(!strncmp("enum",type->name,4))
468 fprintf(of,"\\label{type_enum_%s_%s}\n\n",&type->name[5],filename);
469 else
470 if(!strncmp("union",type->name,5))
471 fprintf(of,"\\label{type_union_%s_%s}\n\n",&type->name[6],filename);
472 else
473 if(!strncmp("struct",type->name,6))
474 fprintf(of,"\\label{type_struct_%s_%s}\n\n",&type->name[7],filename);
475 else
476 fprintf(of,"\\label{type_%s_%s}\n\n",type->name,filename);
478 if(type->comment)
479 fprintf(of,"%s\n\n\\smallskip\n",latex(type->comment,0));
481 if(type->type)
482 fprintf(of,"{\\stt typedef %s}\n\n",latex(type->type,0));
484 if(type->sutype)
486 fprintf(of,"\\smallskip\n");
487 fprintf(of,"\\begin{cxreftabiia}\n"); countlines=0;
488 WriteLatexStructUnion(type->sutype,0);
489 fprintf(of,"\\end{cxreftabiia}\n\n");
491 else
492 if(type->typexref)
494 fprintf(of,"\\smallskip\n");
495 fprintf(of,"\\begin{cxreftabii}\n");
496 if(type->typexref->type)
497 fprintf(of,"See:& Typedef %s & \\cxreftype{%s}{%s}\\\\\n",latex(type->typexref->name,0),type->typexref->name,filename);
498 else
499 if(!strncmp("enum",type->typexref->name,4))
500 fprintf(of,"See:& Type %s & \\cxreftype{enum_%s}{%s}\\\\\n",latex(type->typexref->name,0),&type->typexref->name[5],filename);
501 else
502 if(!strncmp("union",type->typexref->name,5))
503 fprintf(of,"See:& Type %s & \\cxreftype{union_%s}{%s}\\\\\n",latex(type->typexref->name,0),&type->typexref->name[6],filename);
504 else
505 if(!strncmp("struct",type->typexref->name,6))
506 fprintf(of,"See:& Type %s & \\cxreftype{struct_%s}{%s}\\\\\n",latex(type->typexref->name,0),&type->typexref->name[7],filename);
507 fprintf(of,"\\end{cxreftabii}\n\n");
512 /*++++++++++++++++++++++++++++++++++++++
513 Write a structure / union structure out.
515 StructUnion su The structure / union to write.
517 int depth The current depth within the structure.
518 ++++++++++++++++++++++++++++++++++++++*/
520 static void WriteLatexStructUnion(StructUnion su, int depth)
522 int i;
523 char* splitsu=NULL;
525 splitsu=strstr(su->name,"{...}");
526 if(splitsu) splitsu[-1]=0;
528 if(countlines++%8==4)
529 fprintf(of,"\\cxreftabbreak{cxreftabiia}\n");
530 fprintf(of,"\\hspace*{%3.1fin}",0.2*depth);
532 if(depth && su->comment && !su->comps)
533 fprintf(of,"{\\stt %s;} & %s \\\\\n",latex(su->name,0),latex(su->comment,0));
534 else if(!depth || su->comps)
535 fprintf(of,"{\\stt %s} &\\\\\n",latex(su->name,0));
536 else
537 fprintf(of,"{\\stt %s;} &\\\\\n",latex(su->name,0));
539 if(!depth || su->comps)
541 fprintf(of,"\\hspace*{%3.1fin}",0.1+0.2*depth);
542 fprintf(of,"{\\stt \\{} &\\\\\n");
544 for(i=0;i<su->n_comp;i++)
545 WriteLatexStructUnion(su->comps[i],depth+1);
547 fprintf(of,"\\hspace*{%3.1fin}",0.1+0.2*depth);
548 fprintf(of,"{\\stt \\}} &\\\\\n");
549 if(splitsu)
551 fprintf(of,"\\hspace*{%3.1fin}",0.1+0.2*depth);
552 if(depth && su->comment)
553 fprintf(of,"{\\stt %s;} & %s \\\\\n",splitsu[5]?latex(&splitsu[6],0):"",latex(su->comment,0));
554 else
555 fprintf(of,"{\\stt %s;} &\\\\\n",splitsu[5]?latex(&splitsu[6],0):"");
559 if(splitsu) splitsu[-1]=' ';
563 /*++++++++++++++++++++++++++++++++++++++
564 Write a Variable structure out.
566 Variable var The Variable structure to output.
568 char* filename The name of the file that is being processed (required for the cross reference label).
569 ++++++++++++++++++++++++++++++++++++++*/
571 static void WriteLatexVariable(Variable var,char* filename)
573 int i;
575 if(var->scope&GLOBAL)
576 fprintf(of,"\n\\subsubsection{Variable %s}\n",latex(var->name,0));
577 else
578 fprintf(of,"{\\bf %s}\n",latex(var->name,0));
580 fprintf(of,"\\label{var_%s_%s}\n\n",var->name,filename);
582 if(var->comment)
583 fprintf(of,"%s\n\n\\smallskip\n",latex(var->comment,0));
585 fprintf(of,"{\\stt ");
587 if(var->scope&LOCAL)
588 fprintf(of,"static ");
589 else
590 if(!(var->scope&GLOBAL) && var->scope&(EXTERNAL|EXTERN_F))
591 fprintf(of,"extern ");
593 fprintf(of,"%s}\n\n",latex(var->type,0));
595 if(var->scope&(GLOBAL|LOCAL))
597 if(var->incfrom || var->used->n || var->visible->n)
599 fprintf(of,"\\smallskip\n");
600 fprintf(of,"\\begin{cxreftabiii}\n");
602 if(var->incfrom)
603 fprintf(of,"Inc. from:& %s & \\ & \\cxrefvar{%s}{%s}\\\\\n",latex(var->incfrom,0),var->name,var->incfrom);
605 for(i=0;i<var->visible->n;i++)
607 if(min(i,var->visible->n+var->used->n-i)%8 == 4)
608 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
609 if(i==0) fprintf(of,"Visible in:");
610 if(var->visible->s1[i][0]=='$' && !var->visible->s1[i][1])
611 fprintf(of,"\\ & %s & \\ & \\cxreffile{%s}\\\\\n",latex(var->visible->s2[i],0),var->visible->s2[i]);
612 else
613 fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(var->visible->s1[i],0),latex(var->visible->s2[i],0),var->visible->s1[i],var->visible->s2[i]);
616 for(i=0;i<var->used->n;i++)
618 if(min(i,var->visible->n+var->used->n-i)%8 == 4)
619 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
620 if(i==0) fprintf(of,"Used in:");
621 if(var->used->s1[i][0]=='$' && !var->used->s1[i][1])
622 fprintf(of,"\\ & %s & \\ & \\cxreffile{%s}\\\\\n",latex(var->used->s2[i],0),var->used->s2[i]);
623 else
624 if(var->scope&LOCAL)
625 fprintf(of,"\\ & %s() & \\ & \\cxreffunc{%s}{%s}\\\\\n",latex(var->used->s1[i],0),var->used->s1[i],var->used->s2[i]);
626 else
627 fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(var->used->s1[i],0),latex(var->used->s2[i],0),var->used->s1[i],var->used->s2[i]);
630 fprintf(of,"\\end{cxreftabiii}\n\n");
633 else
634 if(var->scope&(EXTERNAL|EXTERN_F) && var->defined)
636 fprintf(of,"\\smallskip\n");
637 fprintf(of,"\\begin{cxreftabiii}\n");
638 fprintf(of,"Defined in:& %s & \\ & \\cxrefvar{%s}{%s}\\\\\n",latex(var->defined,0),var->name,var->defined);
639 fprintf(of,"\\end{cxreftabiii}\n\n");
644 /*++++++++++++++++++++++++++++++++++++++
645 Write a Function structure out.
647 Function func The Function structure to output.
649 char* filename The name of the file that is being processed (required for the cross reference label).
650 ++++++++++++++++++++++++++++++++++++++*/
652 static void WriteLatexFunction(Function func,char* filename)
654 int i,pret,pargs;
655 char* comment2=NULL,*type;
657 if(func->scope&(GLOBAL|EXTERNAL))
658 fprintf(of,"\n\\subsubsection{Global Function %s()}\n",latex(func->name,0));
659 else
660 fprintf(of,"\n\\subsubsection{Local Function %s()}\n",latex(func->name,0));
661 fprintf(of,"\\label{func_%s_%s}\n\n",func->name,filename);
663 if(func->comment)
665 if(option_verbatim_comments)
666 fprintf(of,"\\begin{verbatim}\n%s\n\\end{verbatim}\n\n",latex(func->comment,1));
667 else
669 comment2=strstr(func->comment,"\n\n");
670 if(comment2)
671 comment2[0]=0;
672 fprintf(of,"%s\n\n",latex(func->comment,0));
673 fprintf(of,"\\smallskip\n");
677 fprintf(of,"{\\stt ");
679 if(func->scope&LOCAL)
680 fprintf(of,"static ");
681 if(func->scope&INLINED)
682 fprintf(of,"inline ");
684 if((type=strstr(func->type,"()")))
685 type[0]=0;
686 fprintf(of,"%s ( ",latex(func->type,0));
688 for(i=0;i<func->args->n;i++)
689 fprintf(of,i?", %s":"%s",latex(func->args->s1[i],0));
691 if(type)
692 {fprintf(of," %s}\n\n",&type[1]);type[0]='(';}
693 else
694 fprintf(of," )}\n\n");
696 pret =strncmp("void ",func->type,5) && func->cret;
697 for(pargs=0,i=0;i<func->args->n;i++)
698 pargs = pargs || ( strcmp("void",func->args->s1[i]) && func->args->s2[i] );
700 if(pret || pargs)
702 fprintf(of,"\\smallskip\n");
703 fprintf(of,"\\begin{cxrefarglist}\n");
704 if(pret)
705 fprintf(of,"\\cxrefargitem{%s} %s\n",latex(func->type,0),func->cret?latex(func->cret,0):"\\ ");
706 if(pargs)
707 for(i=0;i<func->args->n;i++)
708 fprintf(of,"\\cxrefargitem{%s} %s\n",latex(func->args->s1[i],0),func->args->s2[i]?latex(func->args->s2[i],0):"\\ ");
709 fprintf(of,"\\end{cxrefarglist}\n\n");
712 if(comment2)
714 fprintf(of,"\\smallskip\n");
715 fprintf(of,"%s\n\n",latex(&comment2[2],0));
716 comment2[0]='\n';
719 if(func->protofile || func->incfrom || func->calls->n || func->called->n || func->used->n || func->f_refs->n || func->v_refs->n)
721 int tabcount=func->protofile?1:0;
722 fprintf(of,"\\smallskip\n");
723 fprintf(of,"\\begin{cxreftabiii}\n");
725 if(func->protofile)
726 fprintf(of,"Prototype:& %s & \\ & \\cxreffile{%s}\\\\\n",latex(func->protofile,0),func->protofile);
728 if(func->incfrom)
729 fprintf(of,"Inc. from:& %s & \\ & \\cxreffunc{%s}{%s}\\\\\n",latex(func->incfrom,0),func->name,func->incfrom);
731 if(func->calls->n)
733 int others=0;
735 fprintf(of,"Calls:");
737 for(i=0;i<func->calls->n;i++)
738 if(func->calls->s2[i])
740 fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->calls->s1[i],0),latex(func->calls->s2[i],0),func->calls->s1[i],func->calls->s2[i]);
741 if(++tabcount%8 == 4)
742 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
744 else
745 others++;
747 if(others)
749 fprintf(of,"\\ & \\cxreftabiiispan{");
750 for(i=0;i<func->calls->n;i++)
751 if(!func->calls->s2[i])
752 fprintf(of,--others?" %s(),":" %s()",latex(func->calls->s1[i],0));
753 fprintf(of,"} &\\\\\n");
757 if(func->called->n)
759 fprintf(of,"Called by:");
761 for(i=0;i<func->called->n;i++)
763 fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->called->s1[i],0),latex(func->called->s2[i],0),func->called->s1[i],func->called->s2[i]);
764 if(++tabcount%8 == 4)
765 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
769 if(func->used->n)
771 fprintf(of,"Used in:");
773 for(i=0;i<func->used->n;i++)
775 if(func->used->s1[i][0]=='$' && !func->used->s1[i][1])
776 fprintf(of,"\\ & %s & \\ & \\cxreffile{%s}\\\\\n",latex(func->used->s2[i],0),func->used->s2[i]);
777 else
778 fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->used->s1[i],0),latex(func->used->s2[i],0),func->used->s1[i],func->used->s2[i]);
779 if(++tabcount%8 == 4)
780 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
784 if(func->f_refs->n)
786 int others=0;
788 fprintf(of,"Refs Func:");
790 for(i=0;i<func->f_refs->n;i++)
791 if(func->f_refs->s2[i])
793 fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->f_refs->s1[i],0),latex(func->f_refs->s2[i],0),func->f_refs->s1[i],func->f_refs->s2[i]);
794 if(++tabcount%8 == 4)
795 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
797 else
798 others++;
800 if(others)
802 fprintf(of,"\\ & \\cxreftabiiispan{");
803 for(i=0;i<func->f_refs->n;i++)
804 if(!func->f_refs->s2[i])
805 fprintf(of,--others?" %s(),":" %s()",latex(func->f_refs->s1[i],0));
806 fprintf(of,"} &\\\\\n");
810 if(func->v_refs->n)
812 int others=0;
814 fprintf(of,"Refs Var:");
816 for(i=0;i<func->v_refs->n;i++)
817 if(func->v_refs->s2[i])
819 fprintf(of,"\\ & %s & %s & \\cxrefvar{%s}{%s}\\\\\n",latex(func->v_refs->s1[i],0),latex(func->v_refs->s2[i],0),func->v_refs->s1[i],func->v_refs->s2[i]);
820 if(++tabcount%8 == 4)
821 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
823 else
824 others++;
826 if(others)
828 fprintf(of,"\\ & \\cxreftabiiispan{");
829 for(i=0;i<func->v_refs->n;i++)
830 if(!func->v_refs->s2[i])
831 fprintf(of,--others?" %s,":" %s",latex(func->v_refs->s1[i],0));
832 fprintf(of,"} &\\\\\n");
836 fprintf(of,"\\end{cxreftabiii}\n\n");
841 /*++++++++++++++++++++++++++++++++++++++
842 Write out a file that will include the current information.
844 char* name The name of the file (without the LaTeX extension).
846 int appendix set to non-zero if the appendix file is to be added, else a normal source file.
847 ++++++++++++++++++++++++++++++++++++++*/
849 static void WriteLatexDocument(char* name,int appendix)
851 FILE *in,*out;
852 char line[256];
853 int seen=0;
854 char *inc_file,*ofile,*ifile;
856 inc_file=ConcatStrings(4,"\\input{",name,LATEX_FILE,"}\n");
857 ifile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE);
858 ofile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE_BACKUP);
860 in =fopen(ifile,"r");
861 if(!in)
863 WriteLatexTemplate(ifile);
864 in =fopen(ifile,"r");
867 out=fopen(ofile,"w");
869 if(!out)
870 {fprintf(stderr,"cxref: Failed to open the main LaTeX output file '%s'\n",ofile);exit(1);}
872 while(fgets(line,256,in))
874 if(!strcmp(inc_file,line) ||
875 (line[0]=='%' && !strcmp(inc_file,line+1)) ||
876 (line[0]=='%' && line[1]==' ' && !strcmp(inc_file,line+2)))
877 {seen=1;break;}
878 if(line[0]=='%' && !strcmp("% End-Of-Source-Files\n",line))
880 if(appendix)
882 fputs(line,out);
883 fputs("\n",out);
884 fputs("% Appendix\n",out);
885 fputs("\n",out);
886 fputs("\\appendix\n",out);
887 fputs("\\markboth{Appendix}{Appendix}\n",out);
888 fputs(inc_file,out);
890 else
892 fputs(inc_file,out);
893 fputs("\n",out);
894 fputs(line,out);
897 else
898 fputs(line,out);
901 fclose(in);
902 fclose(out);
904 if(!seen)
906 unlink(ifile);
907 rename(ofile,ifile);
909 else
910 unlink(ofile);
914 /*++++++++++++++++++++++++++++++++++++++
915 Write out the standard template for the main LaTeX file.
916 This sets up the page styles, and includes markers for the start and end of included source code.
918 char* name The name of the file to write the template to.
919 ++++++++++++++++++++++++++++++++++++++*/
921 static void WriteLatexTemplate(char* name)
923 FILE *template;
924 struct stat stat_buf;
925 char* fname;
927 template=fopen(name,"w");
929 if(!template)
930 {fprintf(stderr,"cxref: Failed to open the main LaTeX output file '%s'\n",name);exit(1);}
932 fputs("% This LaTeX file generated by cxref\n",template);
933 fputs("% cxref program (c) Andrew M. Bishop 1995,96,97,98,99.\n",template);
934 fputs("\n",template);
935 if(option_latex==1)
936 fputs("\\documentstyle[fonts,page,cxref]{report}\n",template);
937 else
939 fputs("\\documentclass{report}\n",template);
940 fputs("\\usepackage{fonts,page,cxref}\n",template);
942 fputs("\\pagestyle{myheadings}\n",template);
943 fputs("\n",template);
944 fputs("\\begin{document}\n",template);
945 fputs("\n",template);
946 fputs("% Contents (Optional, either here or at end)\n",template);
947 fputs("\n",template);
948 fputs("%\\markboth{Contents}{Contents}\n",template);
949 fputs("%\\tableofcontents\n",template);
950 fputs("\n",template);
951 fputs("\\chapter{Source Files}\n",template);
952 fputs("\n",template);
953 fputs("% Begin-Of-Source-Files\n",template);
954 fputs("\n",template);
955 fputs("% End-Of-Source-Files\n",template);
956 fputs("\n",template);
957 fputs("% Contents (Optional, either here or at beginning)\n",template);
958 fputs("\n",template);
959 fputs("\\markboth{Contents}{Contents}\n",template);
960 fputs("\\tableofcontents\n",template);
961 fputs("\n",template);
962 fputs("\\end{document}\n",template);
964 fclose(template);
966 fname=ConcatStrings(2,option_odir,"/fonts.sty");
967 if(stat(fname,&stat_buf))
969 FILE* file=fopen(fname,"w");
970 if(!file)
971 {fprintf(stderr,"cxref: Cannot write the LaTeX style file '%s'\n",fname);exit(1);}
972 fputs(latex_fonts_style,file);
973 fclose(file);
976 fname=ConcatStrings(2,option_odir,"/page.sty");
977 if(stat(fname,&stat_buf))
979 FILE* file=fopen(fname,"w");
980 if(!file)
981 {fprintf(stderr,"cxref: Cannot write the LaTeX style file '%s'\n",fname);exit(1);}
982 fputs(latex_page_style,file);
983 fclose(file);
986 fname=ConcatStrings(2,option_odir,"/cxref.sty");
987 if(stat(fname,&stat_buf))
989 FILE* file=fopen(fname,"w");
990 if(!file)
991 {fprintf(stderr,"cxref: Cannot write the LaTeX style file '%s'\n",fname);exit(1);}
992 fputs(latex_cxref_style,file);
993 fclose(file);
998 /*++++++++++++++++++++++++++++++++++++++
999 Write out the appendix information.
1001 StringList files The list of files to write.
1003 StringList2 funcs The list of functions to write.
1005 StringList2 vars The list of variables to write.
1007 StringList2 types The list of types to write.
1008 ++++++++++++++++++++++++++++++++++++++*/
1010 void WriteLatexAppendix(StringList files,StringList2 funcs,StringList2 vars,StringList2 types)
1012 char* ofile;
1013 int i;
1015 /* Write the bits to the including file. */
1017 WriteLatexDocument(ConcatStrings(2,option_name,LATEX_APDX),1);
1019 /* Open the file */
1021 ofile=ConcatStrings(5,option_odir,"/",option_name,LATEX_APDX,LATEX_FILE);
1023 of=fopen(ofile,"w");
1025 if(!of)
1026 {fprintf(stderr,"cxref: Failed to open the LaTeX appendix file '%s'\n",ofile);exit(1);}
1028 /* Write out a header. */
1030 fputs("% This LaTeX file generated by cxref\n",of);
1031 fputs("% cxref program (c) Andrew M. Bishop 1995,96,97,98,99.\n",of);
1032 fputs("\n",of);
1033 fprintf(of,"%% Cxref: %s\n",run_command);
1034 fprintf(of,"%% CPP : %s\n",run_cpp_command);
1035 fputs("\n",of);
1037 /* Write the file structure out */
1039 fprintf(of,"\\chapter{Cross References}\n");
1041 /* Write out the appendix of files. */
1043 if(files->n)
1045 fprintf(of,"\n\\section{Files}\n");
1046 fprintf(of,"\\label{appendix_file}\n\n");
1047 fprintf(of,"\\begin{cxreftabiib}\n");
1048 for(i=0;i<files->n;i++)
1050 if(min(i,files->n-i)%8 == 4)
1051 fprintf(of,"\\cxreftabbreak{cxreftabiib}\n");
1052 fprintf(of,"%s & \\ & \\cxreffile{%s}\\\\\n",latex(files->s[i],0),files->s[i]);
1054 fprintf(of,"\\end{cxreftabiib}\n\n");
1057 /* Write out the appendix of functions. */
1059 if(funcs->n)
1061 fprintf(of,"\n\\section{Global Functions}\n");
1062 fprintf(of,"\\label{appendix_func}\n\n");
1063 fprintf(of,"\\begin{cxreftabiib}\n");
1064 for(i=0;i<funcs->n;i++)
1066 if(min(i,funcs->n-i)%8 == 4)
1067 fprintf(of,"\\cxreftabbreak{cxreftabiib}\n");
1068 fprintf(of,"%s & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(funcs->s1[i],0),latex(funcs->s2[i],0),funcs->s1[i],funcs->s2[i]);
1070 fprintf(of,"\\end{cxreftabiib}\n\n");
1073 /* Write out the appendix of variables. */
1075 if(vars->n)
1077 fprintf(of,"\n\\section{Global Variables}\n");
1078 fprintf(of,"\\label{appendix_var}\n\n");
1079 fprintf(of,"\\begin{cxreftabiib}\n");
1080 for(i=0;i<vars->n;i++)
1082 if(min(i,vars->n-i)%8 == 4)
1083 fprintf(of,"\\cxreftabbreak{cxreftabiib}\n");
1084 fprintf(of,"%s & %s & \\cxrefvar{%s}{%s}\\\\\n",latex(vars->s1[i],0),latex(vars->s2[i],0),vars->s1[i],vars->s2[i]);
1086 fprintf(of,"\\end{cxreftabiib}\n\n");
1089 /* Write out the appendix of types. */
1091 if(types->n)
1093 fprintf(of,"\n\\section{Defined Types}\n");
1094 fprintf(of,"\\label{appendix_type}\n\n");
1095 fprintf(of,"\\begin{cxreftabiib}\n");
1096 for(i=0;i<types->n;i++)
1098 if(min(i,types->n-i)%8 == 4)
1099 fprintf(of,"\\cxreftabbreak{cxreftabiib}\n");
1100 if(!strncmp("enum",types->s1[i],4))
1101 fprintf(of,"%s & %s & \\cxreftype{enum_%s}{%s}\\\\\n",latex(types->s1[i],0),latex(types->s2[i],0),&types->s1[i][5],types->s2[i]);
1102 else
1103 if(!strncmp("union",types->s1[i],5))
1104 fprintf(of,"%s & %s & \\cxreftype{union_%s}{%s}\\\\\n",latex(types->s1[i],0),latex(types->s2[i],0),&types->s1[i][6],types->s2[i]);
1105 else
1106 if(!strncmp("struct",types->s1[i],6))
1107 fprintf(of,"%s & %s & \\cxreftype{struct_%s}{%s}\\\\\n",latex(types->s1[i],0),latex(types->s2[i],0),&types->s1[i][7],types->s2[i]);
1108 else
1109 fprintf(of,"%s & %s & \\cxreftype{%s}{%s}\\\\\n",latex(types->s1[i],0),latex(types->s2[i],0),types->s1[i],types->s2[i]);
1111 fprintf(of,"\\end{cxreftabiib}\n\n");
1114 fclose(of);
1116 /* Clear the memory in latex(,0) */
1118 latex(NULL,0); latex(NULL,0); latex(NULL,0); latex(NULL,0);
1122 /*++++++++++++++++++++++++++++++++++++++
1123 Delete the latex file and main file reference that belong to the named file.
1125 char *name The name of the file to delete.
1126 ++++++++++++++++++++++++++++++++++++++*/
1128 void WriteLatexFileDelete(char *name)
1130 FILE *in,*out;
1131 char line[256];
1132 int seen=0;
1133 char *inc_file,*ofile,*ifile;
1135 ofile=ConcatStrings(4,option_odir,"/",name,LATEX_FILE);
1136 unlink(ofile);
1138 inc_file=ConcatStrings(4,"\\input{",name,LATEX_FILE,"}\n");
1139 ifile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE);
1140 ofile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE_BACKUP);
1142 in =fopen(ifile,"r");
1143 out=fopen(ofile,"w");
1145 if(in && !out)
1146 {fprintf(stderr,"cxref: Failed to open the main LaTeX output file '%s'\n",ofile);fclose(in);}
1147 else if(in)
1149 while(fgets(line,256,in))
1151 if(!strcmp(inc_file,line) ||
1152 (line[0]=='%' && !strcmp(inc_file,line+1)) ||
1153 (line[0]=='%' && line[1]==' ' && !strcmp(inc_file,line+2)))
1154 seen=1;
1155 else
1156 fputs(line,out);
1159 fclose(in);
1160 fclose(out);
1162 if(seen)
1164 unlink(ifile);
1165 rename(ofile,ifile);
1167 else
1168 unlink(ofile);
1170 else if(out)
1172 fclose(out);
1173 unlink(ofile);
1178 /*++++++++++++++++++++++++++++++++++++++
1179 Make the input string safe to output as LaTeX ( not #, $, %, &, \, ^, _, {, }, <, > or ~ ).
1181 char* latex Returns a safe LaTeX string.
1183 char* c A non-safe LaTeX string.
1185 int verbatim Set to true inside a verbatim environment.
1187 The function can only be called four times in each fprintf() since it returns one of only four static strings.
1188 ++++++++++++++++++++++++++++++++++++++*/
1190 static char* latex(char* c,int verbatim)
1192 static char safe[4][256],*malloced[4]={NULL,NULL,NULL,NULL};
1193 static int which=0;
1194 int copy=0,skip=0;
1195 int i=0,j=0,delta=13,len=256-delta;
1196 char* ret;
1198 which=(which+1)%4;
1199 ret=safe[which];
1201 safe[which][0]=0;
1203 if(malloced[which])
1204 {Free(malloced[which]);malloced[which]=NULL;}
1206 if(c)
1208 i=CopyOrSkip(c,"latex",&copy,&skip);
1210 while(1)
1212 for(;j<len && c[i];i++)
1214 if(copy)
1215 {ret[j++]=c[i]; if(c[i]=='\n') copy=0;}
1216 else if(skip)
1217 { if(c[i]=='\n') skip=0;}
1218 else if(verbatim)
1219 ret[j++]=c[i];
1220 else
1221 switch(c[i])
1223 case '<':
1224 case '>':
1225 ret[j++]='$';
1226 ret[j++]=c[i];
1227 ret[j++]='$';
1228 break;
1229 case '\\':
1230 strcpy(&ret[j],"$\\backslash$");j+=12;
1231 break;
1232 case '~':
1233 strcpy(&ret[j],"$\\sim$");j+=6;
1234 break;
1235 case '^':
1236 strcpy(&ret[j],"$\\wedge$");j+=8;
1237 break;
1238 case '#':
1239 case '$':
1240 case '%':
1241 case '&':
1242 case '_':
1243 case '{':
1244 case '}':
1245 ret[j++]='\\';
1246 ret[j++]=c[i];
1247 break;
1248 default:
1249 ret[j++]=c[i];
1251 if(c[i]=='\n')
1252 i+=CopyOrSkip(c+i,"latex",&copy,&skip);
1255 if(c[i]) /* Not finished */
1257 if(malloced[which])
1258 malloced[which]=Realloc(malloced[which],len+delta+256);
1259 else
1260 {malloced[which]=Malloc(len+delta+256); strncpy(malloced[which],ret,(unsigned)j);}
1261 ret=malloced[which];
1262 len+=256;
1264 else
1265 {ret[j]=0; break;}
1269 return(ret);