    1    | /***************************************
    2    |   $Header: /home/amb/cxref/RCS/latex.c 1.30 1998/12/22 14:25:50 amb Exp $
    3    |
    4    |   C Cross Referencing & Documentation tool. Version 1.5.
    5    |
    6    |   Writes the Latex output.
    7    |   ******************/ /******************
    8    |   Written by Andrew M. Bishop
    9    |
    10   |   This file Copyright 1995,96,97,98 Andrew M. Bishop
    11   |   It may be distributed under the GNU Public License, version 2, or
    12   |   any higher version.  See section COPYING of the GNU Public license
    13   |   for conditions under which this file may be redistributed.
    14   |   ***************************************/
    15   |
    16   | #include <stdlib.h>
    17   | #include <stdio.h>
    18   | #include <string.h>
    19   | #include <sys/types.h>
    20   | #include <sys/stat.h>
    21   | #include <unistd.h>
    22   |
    23   | #ifndef min
    24   | #define min(x,y) ( (x) < (y) ? (x) : (y) )
    25   | #endif
    26   |
    27   | #include "memory.h"
    28   | #include "datatype.h"
    29   | #include "cxref.h"
    30   |
    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~"
    34   |
    35   | /*+ The name of the output tex file that contains the appendix. +*/
    36   | #define LATEX_APDX        ".apdx"
    37   |
    38   | /*+ The comments are to be inserted verbatim. +*/
    39   | extern int option_verbatim_comments;
    40   |
    41   | /*+ The type of LaTeX output to produce. +*/
    42   | extern int option_latex;
    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   | extern char *latex_fonts_style,*latex_page_style,*latex_cxref_style;
    51   |
    52   | static void WriteLatexFilePart(File file);
    53   | static void WriteLatexInclude(Include inc);
    54   | static void WriteLatexSubInclude(Include inc,int depth);
    55   | static void WriteLatexDefine(Define def);
    56   | static void WriteLatexTypedef(Typedef type,char* filename);
    57   | static void WriteLatexStructUnion(StructUnion su,int depth);
    58   | static void WriteLatexVariable(Variable var,char* filename);
    59   | static void WriteLatexFunction(Function func,char* filename);
    60   |
    61   | static void WriteLatexDocument(char* name,int appendix);
    62   | static void WriteLatexTemplate(char* name);
    63   |
    64   | static char* latex(char* c);
    65   |
    66   | /*+ The output file for the latex. +*/
    67   | static FILE* of;
    68   |
    69   | /*+ Counts the lines in a table to insert breaks. +*/
    70   | static int countlines=0;
    71   |
    72   |
    73   | /*++++++++++++++++++++++++++++++++++++++
    74   |   Write a Latex file for a complete File structure and all components.
    75   |
    76   |   File file The File structure to output.
    77   |   ++++++++++++++++++++++++++++++++++++++*/
    78   |
    79   | void WriteLatexFile(File file)
    80   | {
    81   |  char* ofile;
    82   |
    83   |  /* Write the including file. */
    84   |
    85   |  WriteLatexDocument(file->name,0);
    86   |
    87   |  /* Open the file */
    88   |
    89   |  ofile=ConcatStrings(4,option_odir,"/",file->name,LATEX_FILE);
    90   |
    91   |  of=fopen(ofile,"w");
    92   |  if(!of)
    93   |    {
    94   |     struct stat stat_buf;
    95   |     int i,ofl=strlen(ofile);
    96   |
    97   |     for(i=strlen(option_odir)+1;i<ofl;i++)
    98   |        if(ofile[i]=='/')
    99   |          {
    100  |           ofile[i]=0;
    101  |           if(stat(ofile,&stat_buf))
    102  |              mkdir(ofile,S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
    103  |           ofile[i]='/';
    104  |          }
    105  |
    106  |     of=fopen(ofile,"w");
    107  |    }
    108  |
    109  |  if(!of)
    110  |    {fprintf(stderr,"cxref: Failed to open the LaTeX output file '%s'\n",ofile);exit(1);}
    111  |
    112  |  /* Write out a header. */
    113  |
    114  |  fputs("% This LaTeX file generated by cxref\n",of);
    115  |  fputs("% cxref program (c) Andrew M. Bishop 1995,96,97.\n",of);
    116  |  fputs("\n",of);
    117  |
    118  |  /*+ The file structure is broken into its components and they are each written out. +*/
    119  |
    120  |  WriteLatexFilePart(file);
    121  |
    122  |  if(file->includes)
    123  |    {
    124  |     Include inc =file->includes;
    125  |     fprintf(of,"\n\\subsection*{Included Files}\n\n");
    126  |     do{
    127  |        if(inc!=file->includes)
    128  |           fprintf(of,"\\medskip\n");
    129  |        WriteLatexInclude(inc);
    130  |       }
    131  |     while((inc=inc->next));
    132  |    }
    133  |
    134  |  if(file->defines)
    135  |    {
    136  |     Define def =file->defines;
    137  |     fprintf(of,"\n\\subsection*{Preprocessor definitions}\n\n");
    138  |     do{
    139  |        if(def!=file->defines)
    140  |           fprintf(of,"\\medskip\n");
    141  |        WriteLatexDefine(def);
    142  |       }
    143  |     while((def=def->next));
    144  |    }
    145  |
    146  |  if(file->typedefs)
    147  |    {
    148  |     Typedef type=file->typedefs;
    149  |     fprintf(of,"\n\\subsection{Type definitions}\n\n");
    150  |     do{
    151  |        WriteLatexTypedef(type,file->name);
    152  |       }
    153  |     while((type=type->next));
    154  |    }
    155  |
    156  |  if(file->variables)
    157  |    {
    158  |     int any_to_mention=0;
    159  |     Variable var=file->variables;
    160  |
    161  |     do{
    162  |        if(var->scope&(GLOBAL|LOCAL|EXTERNAL|EXTERN_F))
    163  |           any_to_mention=1;
    164  |       }
    165  |     while((var=var->next));
    166  |
    167  |     if(any_to_mention)
    168  |       {
    169  |        int first_ext=1,first_local=1;
    170  |        Variable var=file->variables;
    171  |        fprintf(of,"\n\\subsection{Variables}\n\n");
    172  |        do{
    173  |           if(var->scope&GLOBAL)
    174  |              WriteLatexVariable(var,file->name);
    175  |          }
    176  |        while((var=var->next));
    177  |        var=file->variables;
    178  |        do{
    179  |           if(var->scope&(EXTERNAL|EXTERN_F) && !(var->scope&GLOBAL))
    180  |             {
    181  |              if(first_ext)
    182  |                {fprintf(of,"\n\\subsubsection{External Variables}\n\n"); first_ext=0;}
    183  |              else
    184  |                 fprintf(of,"\\medskip\n");
    185  |              WriteLatexVariable(var,file->name);
    186  |             }
    187  |          }
    188  |        while((var=var->next));
    189  |        var=file->variables;
    190  |        do{
    191  |           if(var->scope&LOCAL)
    192  |             {
    193  |              if(first_local)
    194  |                {fprintf(of,"\n\\subsubsection{Local Variables}\n\n"); first_local=0;}
    195  |              else
    196  |                 fprintf(of,"\\medskip\n");
    197  |              WriteLatexVariable(var,file->name);
    198  |             }
    199  |          }
    200  |        while((var=var->next));
    201  |       }
    202  |    }
    203  |
    204  |  if(file->functions)
    205  |    {
    206  |     Function func=file->functions;
    207  |     fprintf(of,"\n\\subsection{Functions}\n\n");
    208  |     do{
    209  |        if(func->scope&(GLOBAL|EXTERNAL))
    210  |           WriteLatexFunction(func,file->name);
    211  |       }
    212  |     while((func=func->next));
    213  |     func=file->functions;
    214  |     do{
    215  |        if(func->scope&LOCAL)
    216  |           WriteLatexFunction(func,file->name);
    217  |       }
    218  |     while((func=func->next));
    219  |    }
    220  |
    221  |  fclose(of);
    222  |
    223  |  /* Clear the memory in latex() */
    224  |
    225  |  latex(NULL); latex(NULL); latex(NULL); latex(NULL);
    226  | }
    227  |
    228  |
    229  | /*++++++++++++++++++++++++++++++++++++++
    230  |   Write a File structure out.
    231  |
    232  |   File file The File to output.
    233  |   ++++++++++++++++++++++++++++++++++++++*/
    234  |
    235  | static void WriteLatexFilePart(File file)
    236  | {
    237  |  int i;
    238  |
    239  |  fprintf(of,"\\markboth{File %s}{File %s}\n",latex(file->name),latex(file->name));
    240  |  fprintf(of,"\\section{File %s}\n",latex(file->name));
    241  |  fprintf(of,"\\label{file_%s}\n\n",file->name);
    242  |
    243  |  if(file->comment)
    244  |     if(option_verbatim_comments)
    245  |        fprintf(of,"\\begin{verbatim}\n%s\n\\end{verbatim}\n\n",latex(file->comment));
    246  |     else
    247  |       {
    248  |        char *rcs1=strstr(file->comment,"$Header"),*rcs2=NULL;
    249  |        if(rcs1)
    250  |          {
    251  |           rcs2=strstr(&rcs1[1],"$");
    252  |           if(rcs2)
    253  |             {
    254  |              rcs2[0]=0;
    255  |              fprintf(of,"{\\bf RCS %s}\n\n",latex(&rcs1[1]));
    256  |              fprintf(of,"\\smallskip\n");
    257  |              rcs2[0]='$';
    258  |             }
    259  |          }
    260  |        if(rcs2)
    261  |           fprintf(of,"%s\n\n",latex(&rcs2[2]));
    262  |        else
    263  |           fprintf(of,"%s\n\n",latex(file->comment));
    264  |       }
    265  |
    266  |  if(file->inc_in->n)
    267  |    {
    268  |     int i;
    269  |
    270  |     if(file->comment)
    271  |        fprintf(of,"\\medskip\n");
    272  |     fprintf(of,"\\begin{cxreftabii}\nIncluded in:");
    273  |     for(i=0;i<file->inc_in->n;i++)
    274  |       {/* Allow a break in every 8 (or so) items to allow the table to break over the page. */
    275  |        if(min(i,file->inc_in->n-i)%8 == 4)
    276  |           fprintf(of,"\\cxreftabbreak{cxreftabii}\n");
    277  |        fprintf(of,"\\ & %s & \\cxreffile{%s}\\\\\n",latex(file->inc_in->s[i]),file->inc_in->s[i]);
    278  |       }
    279  |     fprintf(of,"\\end{cxreftabii}\n\n");
    280  |    }
    281  |
    282  |  if(file->f_refs->n || file->v_refs->n)
    283  |    {
    284  |     int tabcount=0;
    285  |     fprintf(of,"\\smallskip\n");
    286  |     fprintf(of,"\\begin{cxreftabiii}\n");
    287  |
    288  |     if(file->f_refs->n)
    289  |       {
    290  |        int others=0;
    291  |
    292  |        fprintf(of,"Refs Func:");
    293  |
    294  |        for(i=0;i<file->f_refs->n;i++)
    295  |           if(file->f_refs->s2[i])
    296  |             {
    297  |              fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(file->f_refs->s1[i]),latex(file->f_refs->s2[i]),file->f_refs->s1[i],file->f_refs->s2[i]);
    298  |              if(++tabcount%8 == 4)
    299  |                 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
    300  |             }
    301  |           else
    302  |              others++;
    303  |
    304  |        if(others)
    305  |          {
    306  |           fprintf(of,"\\ & \\cxreftabiiispan{");
    307  |           for(i=0;i<file->f_refs->n;i++)
    308  |              if(!file->f_refs->s2[i])
    309  |                 fprintf(of,--others?"%s(), ":"%s()",latex(file->f_refs->s1[i]));
    310  |           fprintf(of,"} &\\\\\n");
    311  |          }
    312  |       }
    313  |
    314  |     if(file->v_refs->n)
    315  |       {
    316  |        int others=0;
    317  |
    318  |        fprintf(of,"Refs Var:");
    319  |
    320  |        for(i=0;i<file->v_refs->n;i++)
    321  |           if(file->v_refs->s2[i])
    322  |             {
    323  |              fprintf(of,"\\ & %s & %s & \\cxrefvar{%s}{%s}\\\\\n",latex(file->v_refs->s1[i]),latex(file->v_refs->s2[i]),file->v_refs->s1[i],file->v_refs->s2[i]);
    324  |              if(++tabcount%8 == 4)
    325  |                 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
    326  |             }
    327  |           else
    328  |              others++;
    329  |
    330  |        if(others)
    331  |          {
    332  |           fprintf(of,"\\ & \\cxreftabiiispan{");
    333  |           for(i=0;i<file->v_refs->n;i++)
    334  |              if(!file->v_refs->s2[i])
    335  |                 fprintf(of,--others?" %s,":" %s",latex(file->v_refs->s1[i]));
    336  |           fprintf(of,"} &\\\\\n");
    337  |          }
    338  |       }
    339  |
    340  |     fprintf(of,"\\end{cxreftabiii}\n\n");
    341  |    }
    342  | }
    343  |
    344  |
    345  | /*++++++++++++++++++++++++++++++++++++++
    346  |   Write an Include structure out.
    347  |
    348  |   Include inc The Include structure to output.
    349  |   ++++++++++++++++++++++++++++++++++++++*/
    350  |
    351  | static void WriteLatexInclude(Include inc)
    352  | {
    353  |  if(inc->comment)
    354  |     fprintf(of,"%s\n\n\\smallskip\n",latex(inc->comment));
    355  |
    356  |  fprintf(of,"\\begin{cxreftabi}\n"); countlines=1;
    357  |
    358  |  if(inc->scope==LOCAL)
    359  |     fprintf(of,"{\\stt \\#include \"%s\"} &\\cxreffile{%s}\\\\\n",latex(inc->name),inc->name);
    360  |  else
    361  |     fprintf(of,"{\\stt \\#include <%s>} &\\\\\n",latex(inc->name));
    362  |
    363  |  if(inc->includes)
    364  |     WriteLatexSubInclude(inc->includes,1);
    365  |
    366  |  fprintf(of,"\\end{cxreftabi}\n\n");
    367  | }
    368  |
    369  |
    370  | /*++++++++++++++++++++++++++++++++++++++
    371  |   Write an Sub Include structure out. (An include structure that is included from another file.)
    372  |
    373  |   Include inc The Include structure to output.
    374  |
    375  |   int depth The depth of the include hierarchy.
    376  |   ++++++++++++++++++++++++++++++++++++++*/
    377  |
    378  | static void WriteLatexSubInclude(Include inc,int depth)
    379  | {
    380  |  while(inc)
    381  |    {
    382  |     if(countlines++%8==4)
    383  |        fprintf(of,"\\cxreftabbreak{cxreftabi}\n");
    384  |
    385  |     fprintf(of,"\\hspace*{%3.1fin}",0.2*depth);
    386  |
    387  |     if(inc->scope==LOCAL)
    388  |        fprintf(of,"{\\stt \\#include \"%s\"} &\\cxreffile{%s}\\\\\n",latex(inc->name),inc->name);
    389  |     else
    390  |        fprintf(of,"{\\stt \\#include <%s>} &\\\\\n",latex(inc->name));
    391  |
    392  |     if(inc->includes)
    393  |        WriteLatexSubInclude(inc->includes,depth+1);
    394  |
    395  |     inc=inc->next;
    396  |    }
    397  | }
    398  |
    399  |
    400  | /*++++++++++++++++++++++++++++++++++++++
    401  |   Write a Define structure out.
    402  |
    403  |   Define def The Define structure to output.
    404  |   ++++++++++++++++++++++++++++++++++++++*/
    405  |
    406  | static void WriteLatexDefine(Define def)
    407  | {
    408  |  int i;
    409  |  int pargs=0;
    410  |
    411  |  if(def->comment)
    412  |     fprintf(of,"%s\n\n\\smallskip\n",latex(def->comment));
    413  |
    414  |  fprintf(of,"{\\stt \\#define %s",latex(def->name));
    415  |
    416  |  if(def->value)
    417  |     fprintf(of," %s",latex(def->value));
    418  |
    419  |  if(def->args->n)
    420  |    {
    421  |     fprintf(of,"( ");
    422  |     for(i=0;i<def->args->n;i++)
    423  |        fprintf(of,i?", %s":"%s",latex(def->args->s1[i]));
    424  |     fprintf(of," )");
    425  |    }
    426  |  fprintf(of,"}\n\n");
    427  |
    428  |  for(i=0;i<def->args->n;i++)
    429  |     if(def->args->s2[i])
    430  |        pargs=1;
    431  |
    432  |  if(pargs)
    433  |    {
    434  |     fprintf(of,"\\smallskip\n");
    435  |     fprintf(of,"\\begin{cxrefarglist}\n");
    436  |     for(i=0;i<def->args->n;i++)
    437  |        fprintf(of,"\\cxrefargitem{%s} %s\n",latex(def->args->s1[i]),def->args->s2[i]?latex(def->args->s2[i]):"\\ ");
    438  |     fprintf(of,"\\end{cxrefarglist}\n\n");
    439  |    }
    440  | }
    441  |
    442  |
    443  | /*++++++++++++++++++++++++++++++++++++++
    444  |   Write a Typedef structure out.
    445  |
    446  |   Typedef type The Typedef structure to output.
    447  |
    448  |   char* filename The name of the file that is being processed (required for the cross reference label).
    449  |   ++++++++++++++++++++++++++++++++++++++*/
    450  |
    451  | static void WriteLatexTypedef(Typedef type,char* filename)
    452  | {
    453  |  if(type->type)
    454  |     fprintf(of,"\n\\subsubsection{Typedef %s}\n",latex(type->name));
    455  |  else
    456  |     fprintf(of,"\n\\subsubsection{Type %s}\n",latex(type->name));
    457  |
    458  |  if(!strncmp("enum",type->name,4))
    459  |     fprintf(of,"\\label{type_enum_%s_%s}\n\n",&type->name[5],filename);
    460  |  else
    461  |     if(!strncmp("union",type->name,5))
    462  |        fprintf(of,"\\label{type_union_%s_%s}\n\n",&type->name[6],filename);
    463  |     else
    464  |        if(!strncmp("struct",type->name,6))
    465  |           fprintf(of,"\\label{type_struct_%s_%s}\n\n",&type->name[7],filename);
    466  |        else
    467  |           fprintf(of,"\\label{type_%s_%s}\n\n",type->name,filename);
    468  |
    469  |  if(type->comment)
    470  |     fprintf(of,"%s\n\n\\smallskip\n",latex(type->comment));
    471  |
    472  |  if(type->type)
    473  |     fprintf(of,"{\\stt typedef %s}\n\n",latex(type->type));
    474  |
    475  |  if(type->sutype)
    476  |    {
    477  |     fprintf(of,"\\smallskip\n");
    478  |     fprintf(of,"\\begin{cxreftabiia}\n"); countlines=0;
    479  |     WriteLatexStructUnion(type->sutype,0);
    480  |     fprintf(of,"\\end{cxreftabiia}\n\n");
    481  |    }
    482  |  else
    483  |     if(type->typexref)
    484  |       {
    485  |        fprintf(of,"\\smallskip\n");
    486  |        fprintf(of,"\\begin{cxreftabii}\n");
    487  |        if(type->typexref->type)
    488  |           fprintf(of,"See:& Typedef %s & \\cxreftype{%s}{%s}\\\\\n",latex(type->typexref->name),type->typexref->name,filename);
    489  |        else
    490  |           if(!strncmp("enum",type->typexref->name,4))
    491  |              fprintf(of,"See:& Type %s & \\cxreftype{enum_%s}{%s}\\\\\n",latex(type->typexref->name),&type->typexref->name[5],filename);
    492  |           else
    493  |              if(!strncmp("union",type->typexref->name,5))
    494  |                 fprintf(of,"See:& Type %s & \\cxreftype{union_%s}{%s}\\\\\n",latex(type->typexref->name),&type->typexref->name[6],filename);
    495  |              else
    496  |                 if(!strncmp("struct",type->typexref->name,6))
    497  |                    fprintf(of,"See:& Type %s & \\cxreftype{struct_%s}{%s}\\\\\n",latex(type->typexref->name),&type->typexref->name[7],filename);
    498  |        fprintf(of,"\\end{cxreftabii}\n\n");
    499  |       }
    500  | }
    501  |
    502  |
    503  | /*++++++++++++++++++++++++++++++++++++++
    504  |   Write a structure / union structure out.
    505  |
    506  |   StructUnion su The structure / union to write.
    507  |
    508  |   int depth The current depth within the structure.
    509  |   ++++++++++++++++++++++++++++++++++++++*/
    510  |
    511  | static void WriteLatexStructUnion(StructUnion su, int depth)
    512  | {
    513  |  int i;
    514  |  char* splitsu=NULL;
    515  |
    516  |  splitsu=strstr(su->name,"{...}");
    517  |  if(splitsu) splitsu[-1]=0;
    518  |
    519  |  if(countlines++%8==4)
    520  |     fprintf(of,"\\cxreftabbreak{cxreftabiia}\n");
    521  |  fprintf(of,"\\hspace*{%3.1fin}",0.2*depth);
    522  |
    523  |  if(depth && su->comment && !su->comps)
    524  |     fprintf(of,"{\\stt %s;} & %s \\\\\n",latex(su->name),latex(su->comment));
    525  |  else if(!depth || su->comps)
    526  |     fprintf(of,"{\\stt %s} &\\\\\n",latex(su->name));
    527  |  else
    528  |     fprintf(of,"{\\stt %s;} &\\\\\n",latex(su->name));
    529  |
    530  |  if(!depth || su->comps)
    531  |    {
    532  |     fprintf(of,"\\hspace*{%3.1fin}",0.1+0.2*depth);
    533  |     fprintf(of,"{\\stt \\{} &\\\\\n");
    534  |
    535  |     for(i=0;i<su->n_comp;i++)
    536  |        WriteLatexStructUnion(su->comps[i],depth+1);
    537  |
    538  |     fprintf(of,"\\hspace*{%3.1fin}",0.1+0.2*depth);
    539  |     fprintf(of,"{\\stt \\}} &\\\\\n");
    540  |     if(splitsu)
    541  |       {
    542  |        fprintf(of,"\\hspace*{%3.1fin}",0.1+0.2*depth);
    543  |        if(depth && su->comment)
    544  |           fprintf(of,"{\\stt %s;} & %s \\\\\n",splitsu[5]?latex(&splitsu[6]):"",latex(su->comment));
    545  |        else
    546  |           fprintf(of,"{\\stt %s;} &\\\\\n",splitsu[5]?latex(&splitsu[6]):"");
    547  |       }
    548  |    }
    549  |
    550  |  if(splitsu) splitsu[-1]=' ';
    551  | }
    552  |
    553  |
    554  | /*++++++++++++++++++++++++++++++++++++++
    555  |   Write a Variable structure out.
    556  |
    557  |   Variable var The Variable structure to output.
    558  |
    559  |   char* filename The name of the file that is being processed (required for the cross reference label).
    560  |   ++++++++++++++++++++++++++++++++++++++*/
    561  |
    562  | static void WriteLatexVariable(Variable var,char* filename)
    563  | {
    564  |  int i;
    565  |
    566  |  if(var->scope&GLOBAL)
    567  |     fprintf(of,"\n\\subsubsection{Variable %s}\n",latex(var->name));
    568  |  else
    569  |     fprintf(of,"{\\bf %s}\n",latex(var->name));
    570  |
    571  |  fprintf(of,"\\label{var_%s_%s}\n\n",var->name,filename);
    572  |
    573  |  if(var->comment)
    574  |     fprintf(of,"%s\n\n\\smallskip\n",latex(var->comment));
    575  |
    576  |  fprintf(of,"{\\stt ");
    577  |
    578  |  if(var->scope&LOCAL)
    579  |     fprintf(of,"static ");
    580  |  else
    581  |     if(!(var->scope&GLOBAL) && var->scope&(EXTERNAL|EXTERN_F))
    582  |        fprintf(of,"extern ");
    583  |
    584  |  fprintf(of,"%s}\n\n",latex(var->type));
    585  |
    586  |  if(var->scope&(GLOBAL|LOCAL))
    587  |    {
    588  |     if(var->incfrom || var->used->n || var->visible->n)
    589  |       {
    590  |        fprintf(of,"\\smallskip\n");
    591  |        fprintf(of,"\\begin{cxreftabiii}\n");
    592  |
    593  |        if(var->incfrom)
    594  |           fprintf(of,"Inc. from:& %s & \\ & \\cxrefvar{%s}{%s}\\\\\n",latex(var->incfrom),var->name,var->incfrom);
    595  |
    596  |        for(i=0;i<var->visible->n;i++)
    597  |          {
    598  |           if(min(i,var->visible->n+var->used->n-i)%8 == 4)
    599  |              fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
    600  |           if(i==0) fprintf(of,"Visible in:");
    601  |           if(var->visible->s1[i][0]=='$')
    602  |              fprintf(of,"\\ & %s & \\ & \\cxreffile{%s}\\\\\n",latex(var->visible->s2[i]),var->visible->s2[i]);
    603  |           else
    604  |              fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(var->visible->s1[i]),latex(var->visible->s2[i]),var->visible->s1[i],var->visible->s2[i]);
    605  |          }
    606  |
    607  |        for(i=0;i<var->used->n;i++)
    608  |          {
    609  |           if(min(i,var->visible->n+var->used->n-i)%8 == 4)
    610  |              fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
    611  |           if(i==0) fprintf(of,"Used in:");
    612  |           if(var->used->s1[i][0]=='$')
    613  |              fprintf(of,"\\ & %s & \\ & \\cxreffile{%s}\\\\\n",latex(var->used->s2[i]),var->used->s2[i]);
    614  |           else
    615  |              if(var->scope&LOCAL)
    616  |                 fprintf(of,"\\ & %s() & \\ & \\cxreffunc{%s}{%s}\\\\\n",latex(var->used->s1[i]),var->used->s1[i],var->used->s2[i]);
    617  |              else
    618  |                 fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(var->used->s1[i]),latex(var->used->s2[i]),var->used->s1[i],var->used->s2[i]);
    619  |          }
    620  |
    621  |        fprintf(of,"\\end{cxreftabiii}\n\n");
    622  |       }
    623  |    }
    624  |  else
    625  |     if(var->scope&(EXTERNAL|EXTERN_F) && var->defined)
    626  |       {
    627  |        fprintf(of,"\\smallskip\n");
    628  |        fprintf(of,"\\begin{cxreftabiii}\n");
    629  |        fprintf(of,"Defined in:& %s & \\ & \\cxrefvar{%s}{%s}\\\\\n",latex(var->defined),var->name,var->defined);
    630  |        fprintf(of,"\\end{cxreftabiii}\n\n");
    631  |       }
    632  | }
    633  |
    634  |
    635  | /*++++++++++++++++++++++++++++++++++++++
    636  |   Write a Function structure out.
    637  |
    638  |   Function func The Function structure to output.
    639  |
    640  |   char* filename The name of the file that is being processed (required for the cross reference label).
    641  |   ++++++++++++++++++++++++++++++++++++++*/
    642  |
    643  | static void WriteLatexFunction(Function func,char* filename)
    644  | {
    645  |  int i,pret,pargs;
    646  |  char* comment2=NULL,*type;
    647  |
    648  |  if(func->scope&GLOBAL)
    649  |     fprintf(of,"\n\\subsubsection{Global Function %s()}\n",latex(func->name));
    650  |  else
    651  |     fprintf(of,"\n\\subsubsection{Local Function %s()}\n",latex(func->name));
    652  |  fprintf(of,"\\label{func_%s_%s}\n\n",func->name,filename);
    653  |
    654  |  if(func->comment)
    655  |     if(option_verbatim_comments)
    656  |        fprintf(of,"\\begin{verbatim}\n%s\n\\end{verbatim}\n\n",latex(func->comment));
    657  |     else
    658  |       {
    659  |        comment2=strstr(func->comment,"\n\n");
    660  |        if(comment2)
    661  |           comment2[0]=0;
    662  |        fprintf(of,"%s\n\n",latex(func->comment));
    663  |        fprintf(of,"\\smallskip\n");
    664  |       }
    665  |
    666  |  fprintf(of,"{\\stt ");
    667  |
    668  |  if(func->scope&LOCAL)
    669  |     fprintf(of,"static ");
    670  |  if(func->scope&INLINED)
    671  |    fprintf(of,"inline ");
    672  |
    673  |  if((type=strstr(func->type,"()")))
    674  |     type[0]=0;
    675  |  fprintf(of,"%s ( ",latex(func->type));
    676  |
    677  |  for(i=0;i<func->args->n;i++)
    678  |     fprintf(of,i?", %s":"%s",latex(func->args->s1[i]));
    679  |
    680  |  if(type)
    681  |    {fprintf(of," %s}\n\n",&type[1]);type[0]='(';}
    682  |  else
    683  |     fprintf(of," )}\n\n");
    684  |
    685  |  pret =strncmp("void ",func->type,5) && func->cret;
    686  |  for(pargs=0,i=0;i<func->args->n;i++)
    687  |     pargs = pargs || ( strcmp("void",func->args->s1[i]) && func->args->s2[i] );
    688  |
    689  |  if(pret || pargs)
    690  |    {
    691  |     fprintf(of,"\\smallskip\n");
    692  |     fprintf(of,"\\begin{cxrefarglist}\n");
    693  |     if(pret)
    694  |        fprintf(of,"\\cxrefargitem{%s} %s\n",latex(func->type),func->cret?latex(func->cret):"\\ ");
    695  |     if(pargs)
    696  |        for(i=0;i<func->args->n;i++)
    697  |           fprintf(of,"\\cxrefargitem{%s} %s\n",latex(func->args->s1[i]),func->args->s2[i]?latex(func->args->s2[i]):"\\ ");
    698  |     fprintf(of,"\\end{cxrefarglist}\n\n");
    699  |    }
    700  |
    701  |  if(comment2)
    702  |    {
    703  |     fprintf(of,"\\smallskip\n");
    704  |     fprintf(of,"%s\n\n",latex(&comment2[2]));
    705  |     comment2[0]='\n';
    706  |    }
    707  |
    708  |  if(func->protofile || func->incfrom || func->calls->n || func->called->n || func->used->n || func->f_refs->n || func->v_refs->n)
    709  |    {
    710  |     int tabcount=func->protofile?1:0;
    711  |     fprintf(of,"\\smallskip\n");
    712  |     fprintf(of,"\\begin{cxreftabiii}\n");
    713  |
    714  |     if(func->protofile)
    715  |        fprintf(of,"Prototype:& %s & \\ & \\cxreffile{%s}\\\\\n",latex(func->protofile),func->protofile);
    716  |
    717  |     if(func->incfrom)
    718  |        fprintf(of,"Inc. from:& %s & \\ & \\cxreffunc{%s}{%s}\\\\\n",latex(func->incfrom),func->name,func->incfrom);
    719  |
    720  |     if(func->calls->n)
    721  |       {
    722  |        int others=0;
    723  |
    724  |        fprintf(of,"Calls:");
    725  |
    726  |        for(i=0;i<func->calls->n;i++)
    727  |           if(func->calls->s2[i])
    728  |             {
    729  |              fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->calls->s1[i]),latex(func->calls->s2[i]),func->calls->s1[i],func->calls->s2[i]);
    730  |              if(++tabcount%8 == 4)
    731  |                 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
    732  |             }
    733  |           else
    734  |              others++;
    735  |
    736  |        if(others)
    737  |          {
    738  |           fprintf(of,"\\ & \\cxreftabiiispan{");
    739  |           for(i=0;i<func->calls->n;i++)
    740  |              if(!func->calls->s2[i])
    741  |                 fprintf(of,--others?" %s(),":" %s()",latex(func->calls->s1[i]));
    742  |           fprintf(of,"} &\\\\\n");
    743  |          }
    744  |       }
    745  |
    746  |     if(func->called->n)
    747  |       {
    748  |        fprintf(of,"Called by:");
    749  |
    750  |        for(i=0;i<func->called->n;i++)
    751  |          {
    752  |           fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->called->s1[i]),latex(func->called->s2[i]),func->called->s1[i],func->called->s2[i]);
    753  |           if(++tabcount%8 == 4)
    754  |              fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
    755  |          }
    756  |       }
    757  |
    758  |     if(func->used->n)
    759  |       {
    760  |        fprintf(of,"Used in:");
    761  |
    762  |        for(i=0;i<func->used->n;i++)
    763  |          {
    764  |           if(func->used->s1[i][0]=='$')
    765  |              fprintf(of,"\\ & %s & \\ & \\cxreffile{%s}\\\\\n",latex(func->used->s2[i]),func->used->s2[i]);
    766  |           else
    767  |              fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->used->s1[i]),latex(func->used->s2[i]),func->used->s1[i],func->used->s2[i]);
    768  |           if(++tabcount%8 == 4)
    769  |              fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
    770  |          }
    771  |       }
    772  |
    773  |     if(func->f_refs->n)
    774  |       {
    775  |        int others=0;
    776  |
    777  |        fprintf(of,"Refs Func:");
    778  |
    779  |        for(i=0;i<func->f_refs->n;i++)
    780  |           if(func->f_refs->s2[i])
    781  |             {
    782  |              fprintf(of,"\\ & %s() & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(func->f_refs->s1[i]),latex(func->f_refs->s2[i]),func->f_refs->s1[i],func->f_refs->s2[i]);
    783  |              if(++tabcount%8 == 4)
    784  |                 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
    785  |             }
    786  |           else
    787  |              others++;
    788  |
    789  |        if(others)
    790  |          {
    791  |           fprintf(of,"\\ & \\cxreftabiiispan{");
    792  |           for(i=0;i<func->f_refs->n;i++)
    793  |              if(!func->f_refs->s2[i])
    794  |                 fprintf(of,--others?" %s(),":" %s()",latex(func->f_refs->s1[i]));
    795  |           fprintf(of,"} &\\\\\n");
    796  |          }
    797  |       }
    798  |
    799  |     if(func->v_refs->n)
    800  |       {
    801  |        int others=0;
    802  |
    803  |        fprintf(of,"Refs Var:");
    804  |
    805  |        for(i=0;i<func->v_refs->n;i++)
    806  |           if(func->v_refs->s2[i])
    807  |             {
    808  |              fprintf(of,"\\ & %s & %s & \\cxrefvar{%s}{%s}\\\\\n",latex(func->v_refs->s1[i]),latex(func->v_refs->s2[i]),func->v_refs->s1[i],func->v_refs->s2[i]);
    809  |              if(++tabcount%8 == 4)
    810  |                 fprintf(of,"\\cxreftabbreak{cxreftabiii}\n");
    811  |             }
    812  |           else
    813  |              others++;
    814  |
    815  |        if(others)
    816  |          {
    817  |           fprintf(of,"\\ & \\cxreftabiiispan{");
    818  |           for(i=0;i<func->v_refs->n;i++)
    819  |              if(!func->v_refs->s2[i])
    820  |                 fprintf(of,--others?" %s,":" %s",latex(func->v_refs->s1[i]));
    821  |           fprintf(of,"} &\\\\\n");
    822  |          }
    823  |       }
    824  |
    825  |     fprintf(of,"\\end{cxreftabiii}\n\n");
    826  |    }
    827  | }
    828  |
    829  |
    830  | /*++++++++++++++++++++++++++++++++++++++
    831  |   Write out a file that will include the current information.
    832  |
    833  |   char* name The name of the file (without the LaTeX extension).
    834  |
    835  |   int appendix set to non-zero if the appendix file is to be added, else a normal source file.
    836  |   ++++++++++++++++++++++++++++++++++++++*/
    837  |
    838  | static void WriteLatexDocument(char* name,int appendix)
    839  | {
    840  |  FILE *in,*out;
    841  |  char line[256];
    842  |  int seen=0;
    843  |  char *inc_file,*ofile,*ifile;
    844  |
    845  |  inc_file=ConcatStrings(4,"\\input{",name,LATEX_FILE,"}\n");
    846  |  ifile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE);
    847  |  ofile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE_BACKUP);
    848  |
    849  |  in =fopen(ifile,"r");
    850  |  if(!in)
    851  |    {
    852  |     WriteLatexTemplate(ifile);
    853  |     in =fopen(ifile,"r");
    854  |    }
    855  |
    856  |  out=fopen(ofile,"w");
    857  |
    858  |  if(!out)
    859  |    {fprintf(stderr,"cxref: Failed to open the main LaTeX output file '%s'\n",ofile);exit(1);}
    860  |
    861  |  while(fgets(line,256,in))
    862  |    {
    863  |     if(!strcmp(inc_file,line) ||
    864  |        (line[0]=='%' && !strcmp(inc_file,line+1)) ||
    865  |        (line[0]=='%' && line[1]==' ' && !strcmp(inc_file,line+2)))
    866  |        {seen=1;break;}
    867  |     if(line[0]=='%' && !strcmp("% End-Of-Source-Files\n",line))
    868  |       {
    869  |        if(appendix)
    870  |          {
    871  |           fputs(line,out);
    872  |           fputs("\n",out);
    873  |           fputs("% Appendix\n",out);
    874  |           fputs("\n",out);
    875  |           fputs("\\appendix\n",out);
    876  |           fputs("\\markboth{Appendix}{Appendix}\n",out);
    877  |           fputs(inc_file,out);
    878  |          }
    879  |        else
    880  |          {
    881  |           fputs(inc_file,out);
    882  |           fputs("\n",out);
    883  |           fputs(line,out);
    884  |          }
    885  |       }
    886  |     else
    887  |        fputs(line,out);
    888  |    }
    889  |
    890  |  fclose(in);
    891  |  fclose(out);
    892  |
    893  |  if(!seen)
    894  |    {
    895  |     unlink(ifile);
    896  |     rename(ofile,ifile);
    897  |    }
    898  |  else
    899  |     unlink(ofile);
    900  | }
    901  |
    902  |
    903  | /*++++++++++++++++++++++++++++++++++++++
    904  |   Write out the standard template for the main LaTeX file.
    905  |   This sets up the page styles, and includes markers for the start and end of included source code.
    906  |
    907  |   char* name The name of the file to write the template to.
    908  |   ++++++++++++++++++++++++++++++++++++++*/
    909  |
    910  | static void WriteLatexTemplate(char* name)
    911  | {
    912  |  FILE *template;
    913  |  struct stat stat_buf;
    914  |  char* fname;
    915  |
    916  |  template=fopen(name,"w");
    917  |
    918  |  if(!template)
    919  |    {fprintf(stderr,"cxref: Failed to open the main LaTeX output file '%s'\n",name);exit(1);}
    920  |
    921  |  fputs("% This LaTeX file generated by cxref\n",template);
    922  |  fputs("% cxref program (c) Andrew M. Bishop 1995,96,97,98.\n",template);
    923  |  fputs("\n",template);
    924  |  if(option_latex==1)
    925  |     fputs("\\documentstyle[fonts,page,cxref]{report}\n",template);
    926  |  else
    927  |    {
    928  |     fputs("\\documentclass{report}\n",template);
    929  |     fputs("\\usepackage{fonts,page,cxref}\n",template);
    930  |    }
    931  |  fputs("\\pagestyle{myheadings}\n",template);
    932  |  fputs("\n",template);
    933  |  fputs("\\begin{document}\n",template);
    934  |  fputs("\n",template);
    935  |  fputs("% Contents (Optional, either here or at end)\n",template);
    936  |  fputs("\n",template);
    937  |  fputs("%\\markboth{Contents}{Contents}\n",template);
    938  |  fputs("%\\tableofcontents\n",template);
    939  |  fputs("\n",template);
    940  |  fputs("\\chapter{Source Files}\n",template);
    941  |  fputs("\n",template);
    942  |  fputs("% Begin-Of-Source-Files\n",template);
    943  |  fputs("\n",template);
    944  |  fputs("% End-Of-Source-Files\n",template);
    945  |  fputs("\n",template);
    946  |  fputs("% Contents (Optional, either here or at beginning)\n",template);
    947  |  fputs("\n",template);
    948  |  fputs("\\markboth{Contents}{Contents}\n",template);
    949  |  fputs("\\tableofcontents\n",template);
    950  |  fputs("\n",template);
    951  |  fputs("\\end{document}\n",template);
    952  |
    953  |  fclose(template);
    954  |
    955  |  fname=ConcatStrings(2,option_odir,"/fonts.sty");
    956  |  if(stat(fname,&stat_buf))
    957  |    {
    958  |     FILE* file=fopen(fname,"w");
    959  |     if(!file)
    960  |       {fprintf(stderr,"cxref: Cannot write the LaTeX style file '%s'\n",fname);exit(1);}
    961  |     fputs(latex_fonts_style,file);
    962  |     fclose(file);
    963  |    }
    964  |
    965  |  fname=ConcatStrings(2,option_odir,"/page.sty");
    966  |  if(stat(fname,&stat_buf))
    967  |    {
    968  |     FILE* file=fopen(fname,"w");
    969  |     if(!file)
    970  |       {fprintf(stderr,"cxref: Cannot write the LaTeX style file '%s'\n",fname);exit(1);}
    971  |     fputs(latex_page_style,file);
    972  |     fclose(file);
    973  |    }
    974  |
    975  |  fname=ConcatStrings(2,option_odir,"/cxref.sty");
    976  |  if(stat(fname,&stat_buf))
    977  |    {
    978  |     FILE* file=fopen(fname,"w");
    979  |     if(!file)
    980  |       {fprintf(stderr,"cxref: Cannot write the LaTeX style file '%s'\n",fname);exit(1);}
    981  |     fputs(latex_cxref_style,file);
    982  |     fclose(file);
    983  |    }
    984  | }
    985  |
    986  |
    987  | /*++++++++++++++++++++++++++++++++++++++
    988  |   Write out the appendix information.
    989  |
    990  |   StringList files The list of files to write.
    991  |
    992  |   StringList2 funcs The list of functions to write.
    993  |
    994  |   StringList2 vars The list of variables to write.
    995  |
    996  |   StringList2 types The list of types to write.
    997  |   ++++++++++++++++++++++++++++++++++++++*/
    998  |
    999  | void WriteLatexAppendix(StringList files,StringList2 funcs,StringList2 vars,StringList2 types)
    1000 | {
    1001 |  char* ofile;
    1002 |  int i;
    1003 |
    1004 |  /* Write the bits to the including file. */
    1005 |
    1006 |  WriteLatexDocument(ConcatStrings(2,option_name,LATEX_APDX),1);
    1007 |
    1008 |  /* Open the file */
    1009 |
    1010 |  ofile=ConcatStrings(5,option_odir,"/",option_name,LATEX_APDX,LATEX_FILE);
    1011 |
    1012 |  of=fopen(ofile,"w");
    1013 |
    1014 |  if(!of)
    1015 |    {fprintf(stderr,"cxref: Failed to open the LaTeX appendix file '%s'\n",ofile);exit(1);}
    1016 |
    1017 |  /* Write the file structure out */
    1018 |
    1019 |  fprintf(of,"\\chapter{Cross References}\n");
    1020 |
    1021 |  /* Write out the appendix of files. */
    1022 |
    1023 |  if(files->n)
    1024 |    {
    1025 |     fprintf(of,"\n\\section{Files}\n");
    1026 |     fprintf(of,"\\label{appendix_file}\n\n");
    1027 |     fprintf(of,"\\begin{cxreftabiib}\n");
    1028 |     for(i=0;i<files->n;i++)
    1029 |       {
    1030 |        if(min(i,files->n-i)%8 == 4)
    1031 |           fprintf(of,"\\cxreftabbreak{cxreftabiib}\n");
    1032 |        fprintf(of,"%s & \\ & \\cxreffile{%s}\\\\\n",latex(files->s[i]),files->s[i]);
    1033 |       }
    1034 |     fprintf(of,"\\end{cxreftabiib}\n\n");
    1035 |    }
    1036 |
    1037 |  /* Write out the appendix of functions. */
    1038 |
    1039 |  if(funcs->n)
    1040 |    {
    1041 |     fprintf(of,"\n\\section{Global Functions}\n");
    1042 |     fprintf(of,"\\label{appendix_func}\n\n");
    1043 |     fprintf(of,"\\begin{cxreftabiib}\n");
    1044 |     for(i=0;i<funcs->n;i++)
    1045 |       {
    1046 |        if(min(i,funcs->n-i)%8 == 4)
    1047 |           fprintf(of,"\\cxreftabbreak{cxreftabiib}\n");
    1048 |        fprintf(of,"%s & %s & \\cxreffunc{%s}{%s}\\\\\n",latex(funcs->s1[i]),latex(funcs->s2[i]),funcs->s1[i],funcs->s2[i]);
    1049 |       }
    1050 |     fprintf(of,"\\end{cxreftabiib}\n\n");
    1051 |    }
    1052 |
    1053 |  /* Write out the appendix of variables. */
    1054 |
    1055 |  if(vars->n)
    1056 |    {
    1057 |     fprintf(of,"\n\\section{Global Variables}\n");
    1058 |     fprintf(of,"\\label{appendix_var}\n\n");
    1059 |     fprintf(of,"\\begin{cxreftabiib}\n");
    1060 |     for(i=0;i<vars->n;i++)
    1061 |       {
    1062 |        if(min(i,vars->n-i)%8 == 4)
    1063 |           fprintf(of,"\\cxreftabbreak{cxreftabiib}\n");
    1064 |        fprintf(of,"%s & %s & \\cxrefvar{%s}{%s}\\\\\n",latex(vars->s1[i]),latex(vars->s2[i]),vars->s1[i],vars->s2[i]);
    1065 |       }
    1066 |     fprintf(of,"\\end{cxreftabiib}\n\n");
    1067 |    }
    1068 |
    1069 |  /* Write out the appendix of types. */
    1070 |
    1071 |  if(types->n)
    1072 |    {
    1073 |     fprintf(of,"\n\\section{Defined Types}\n");
    1074 |     fprintf(of,"\\label{appendix_type}\n\n");
    1075 |     fprintf(of,"\\begin{cxreftabiib}\n");
    1076 |     for(i=0;i<types->n;i++)
    1077 |       {
    1078 |        if(min(i,types->n-i)%8 == 4)
    1079 |           fprintf(of,"\\cxreftabbreak{cxreftabiib}\n");
    1080 |        if(!strncmp("enum",types->s1[i],4))
    1081 |           fprintf(of,"%s & %s & \\cxreftype{enum_%s}{%s}\\\\\n",latex(types->s1[i]),latex(types->s2[i]),&types->s1[i][5],types->s2[i]);
    1082 |        else
    1083 |           if(!strncmp("union",types->s1[i],5))
    1084 |              fprintf(of,"%s & %s & \\cxreftype{union_%s}{%s}\\\\\n",latex(types->s1[i]),latex(types->s2[i]),&types->s1[i][6],types->s2[i]);
    1085 |           else
    1086 |              if(!strncmp("struct",types->s1[i],6))
    1087 |                 fprintf(of,"%s & %s & \\cxreftype{struct_%s}{%s}\\\\\n",latex(types->s1[i]),latex(types->s2[i]),&types->s1[i][7],types->s2[i]);
    1088 |              else
    1089 |                 fprintf(of,"%s & %s & \\cxreftype{%s}{%s}\\\\\n",latex(types->s1[i]),latex(types->s2[i]),types->s1[i],types->s2[i]);
    1090 |       }
    1091 |     fprintf(of,"\\end{cxreftabiib}\n\n");
    1092 |    }
    1093 |
    1094 |  fclose(of);
    1095 |
    1096 |  /* Clear the memory in latex() */
    1097 |
    1098 |  latex(NULL); latex(NULL); latex(NULL); latex(NULL);
    1099 | }
    1100 |
    1101 |
    1102 | /*++++++++++++++++++++++++++++++++++++++
    1103 |   Delete the latex file and main file reference that belong to the named file.
    1104 |
    1105 |   char *name The name of the file to delete.
    1106 |   ++++++++++++++++++++++++++++++++++++++*/
    1107 |
    1108 | void WriteLatexFileDelete(char *name)
    1109 | {
    1110 |  FILE *in,*out;
    1111 |  char line[256];
    1112 |  int seen=0;
    1113 |  char *inc_file,*ofile,*ifile;
    1114 |
    1115 |  ofile=ConcatStrings(4,option_odir,"/",name,LATEX_FILE);
    1116 |  unlink(ofile);
    1117 |
    1118 |  inc_file=ConcatStrings(4,"\\input{",name,LATEX_FILE,"}\n");
    1119 |  ifile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE);
    1120 |  ofile=ConcatStrings(4,option_odir,"/",option_name,LATEX_FILE_BACKUP);
    1121 |
    1122 |  in =fopen(ifile,"r");
    1123 |  out=fopen(ofile,"w");
    1124 |
    1125 |  if(in && !out)
    1126 |    {fprintf(stderr,"cxref: Failed to open the main LaTeX output file '%s'\n",ofile);fclose(in);}
    1127 |  else if(in)
    1128 |    {
    1129 |     while(fgets(line,256,in))
    1130 |       {
    1131 |        if(!strcmp(inc_file,line) ||
    1132 |           (line[0]=='%' && !strcmp(inc_file,line+1)) ||
    1133 |           (line[0]=='%' && line[1]==' ' && !strcmp(inc_file,line+2)))
    1134 |           seen=1;
    1135 |        else
    1136 |           fputs(line,out);
    1137 |       }
    1138 |
    1139 |     fclose(in);
    1140 |     fclose(out);
    1141 |
    1142 |     if(seen)
    1143 |       {
    1144 |        unlink(ifile);
    1145 |        rename(ofile,ifile);
    1146 |       }
    1147 |     else
    1148 |        unlink(ofile);
    1149 |    }
    1150 |  else if(out)
    1151 |    {
    1152 |     fclose(out);
    1153 |     unlink(ofile);
    1154 |    }
    1155 | }
    1156 |
    1157 |
    1158 | /*++++++++++++++++++++++++++++++++++++++
    1159 |   Make the input string safe to output as LaTeX ( not #, $, %, &, \, ^, _, {, }, <, > or ~ ).
    1160 |
    1161 |   char* latex Returns a safe LaTeX string.
    1162 |
    1163 |   char* c A non-safe LaTeX string.
    1164 |
    1165 |   The function can only be called four times in each fprintf() since it returns one of only four static strings.
    1166 |   ++++++++++++++++++++++++++++++++++++++*/
    1167 |
    1168 | static char* latex(char* c)
    1169 | {
    1170 |  static char safe[4][256],*malloced[4]={NULL,NULL,NULL,NULL};
    1171 |  static int which=0;
    1172 |  int copy=0,skip=0;
    1173 |  int i=0,j=0,delta=13,len=256-delta;
    1174 |  char* ret;
    1175 |
    1176 |  which=(which+1)%4;
    1177 |  ret=safe[which];
    1178 |
    1179 |  safe[which][0]=0;
    1180 |
    1181 |  if(malloced[which])
    1182 |    {Free(malloced[which]);malloced[which]=NULL;}
    1183 |
    1184 |  if(c)
    1185 |     while(1)
    1186 |        {
    1187 |        for(;j<len && c[i];i++)
    1188 |          {
    1189 |           if(copy)
    1190 |             {ret[j++]=c[i]; if(c[i]=='\n') copy=0;}
    1191 |           else if(skip)
    1192 |             {               if(c[i]=='\n') skip=0;}
    1193 |           else
    1194 |              switch(c[i])
    1195 |                {
    1196 |                case '<':
    1197 |                case '>':
    1198 |                 ret[j++]='$';
    1199 |                 ret[j++]=c[i];
    1200 |                 ret[j++]='$';
    1201 |                 break;
    1202 |                case '\\':
    1203 |                 strcpy(&ret[j],"$\\backslash$");j+=12;
    1204 |                 break;
    1205 |                case '~':
    1206 |                 strcpy(&ret[j],"$\\sim$");j+=6;
    1207 |                 break;
    1208 |                case '^':
    1209 |                 strcpy(&ret[j],"$\\wedge$");j+=8;
    1210 |                 break;
    1211 |                case '#':
    1212 |                case '$':
    1213 |                case '%':
    1214 |                case '&':
    1215 |                case '_':
    1216 |                case '{':
    1217 |                case '}':
    1218 |                 ret[j++]='\\';
    1219 |                 ret[j++]=c[i];
    1220 |                 break;
    1221 |                default:
    1222 |                 ret[j++]=c[i];
    1223 |                }
    1224 |           if(c[i]=='\n')
    1225 |              i+=CopyOrSkip(c+i,"latex",&copy,&skip);
    1226 |          }
    1227 |
    1228 |        if(c[i])                 /* Not finished */
    1229 |          {
    1230 |           if(malloced[which])
    1231 |              malloced[which]=Realloc(malloced[which],len+delta+256);
    1232 |           else
    1233 |             {malloced[which]=Malloc(len+delta+256); strncpy(malloced[which],ret,(unsigned)j);}
    1234 |           ret=malloced[which];
    1235 |           len+=256;
    1236 |          }
    1237 |        else
    1238 |          {ret[j]=0; break;}
    1239 |       }
    1240 |
    1241 |  return(ret);
    1242 | }