home *** CD-ROM | disk | FTP | other *** search
/ Dream 57 / Amiga_Dream_57.iso / Amiga / Programmation / c / Docs / cxref-1.4a.lha / latex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-12-07  |  35.8 KB  |  1,276 lines

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