/*        Forth2LaTeX  --  A Forth code pretty-printer for LaTeX                                (c) 1994, Ronald T. Kneusel, all rights reserved.                Internet: kneusel@studsys.mscs.mu.edu                  See the Forth2LaTeX manual for information about using this program.  This code is compatible with Unix, VMS, MS-DOS, and Macintosh computers.    This code maybe distributed freely as long as all notices remain intact.  For profit distribution allowed only with the written consent of the   author.    Please pardon this messy and _very_ direct port from the Modula-2 original!      Last Mod:  01/05/95  */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#define TRUE  1#define FALSE 0#define last 32766         /* for use in string functions */#define MAX  256           /* longest string *//************************************************************************     This code runs on Macintosh, MS-DOS, Unix, and VMS.  Simply define     the appropriate system below:     *************************************************************************/#define MACINTOSH    /* choose one: MACINTOSH, VAX, UNIX, or MSDOS */#ifdef MACINTOSH#include <console.h>#endif/* Globals */FILE  *f, *g, *w, *t;           /* file pointers */int DONE,TOC,UP,INDEX,BOLD;     /* switches */int RA,QUOTE,SECTIONS;int COMMENTS,FIRST;int NOBRACKET;struct tree         /* binary tree for defined word list */{	long int  line;          /* line number of definition */	char name[MAX];          /* name of defined word      */	struct tree *left;       /* left and right subtrees   */	struct tree *right;} ;struct tree *root;              /* root of the tree */char  infile[MAX], outfile[MAX];     /* source and dest file names *//* if your compiler needs prototypes, include this file: */#include "proto.c"/************************************************************************/main(int argc, char *argv[]){ #ifdef MACINTOSH  argc = ccommand(&argv);#endif  Header();  Init();  root = NULL;  switch(argc){    case 1: helpScreen();             break;    case 2: ShowSwitches();            ConvertFile(argv[1]);             break;    default: setSwitches(argv[2]);             ShowSwitches();             ConvertFile(argv[1]);  }  #ifndef VAX   return 0;#endif}/*************************************************************************     Functions - these are for the most part direct translations of the                 original Modula-2 functions, including the names                 *************************************************************************/void helpScreen(void){	printf("Quick help:\n\n");	printf("Command line:  Forth2LaTeX <infile> [<switch settings>]\n\n");	printf("Switches:  -xxx where presence of character 'x' is on\n\n");	printf("  u  -- uppercase code\n");	printf("  l  -- comments LATEX (default is FORTH)\n");	printf("  t  -- generate table of contents\n");	printf("  i  -- index of defined words\n");	printf("  b  -- bold colon definition names\n");	printf("  r  -- style is REPORT (default is ARTICLE)\n");	printf("\nExample: -ibr is INDEX, BOLD, and REPORT on, others off or ");	printf("default\n\n");	printf("See the manual for more information.\n\n");	printf("Author contact: kneusel@studsys.mscs.mu.edu\n\n");}void Init(void)/* default settings */{   UP = FALSE;  COMMENTS = FALSE;  TOC = FALSE;   INDEX = FALSE; BOLD = FALSE;  RA = FALSE;}void setSwitches(char *s)/* set the command line switches */{  int i;    for(i=1;i<strlen(s);i++)    switch(up1(s[i])){       case 'U': UP       = TRUE;  break;       case 'L': COMMENTS = TRUE;  break;       case 'T': TOC      = TRUE;  break;       case 'I': INDEX    = TRUE;  break;       case 'B': BOLD     = TRUE;  break;       case 'R': RA       = TRUE;  break;       default : break; /* ignore */     }     }void ShowSwitches(void)/* show the current switch settings */{  printf("Switches on: ");  if (UP) printf("UPPERCASE  ");  if (COMMENTS) printf("LATEX  ");  if (TOC) printf("TABLE-OF-CONTENTS  ");  if (INDEX) printf("INDEX  ");  if (BOLD) printf("BOLD  ");  if (RA) printf("REPORT");   printf("\n\n");  }/********************************************* *                                           * *  C versions of Modula-2 string functions  * *                                           * *********************************************/int Len(char *s){  /* length of the string s */  return strlen(s);}void Append(char *s1, char *s2)/* append s2 to s1 */{   s1 = strcat(s1,s2);}void AppendCh(char *s, int c)/* append character c to s */{     char nullstr[2];      nullstr[1] = '\0';   nullstr[0] = c;   s = strcat(s,nullstr);}int Equal(char *s1, char *s2)/* true if s1 == s2 */{  return ( strcmp(s1,s2) == 0 ) ? TRUE : FALSE; }void Copy(char *d, char *s, int st, int len)/* copy len chars from s into d starting at position st of s */{  if (st+len <= strlen(s)) {    strncpy(d,s+st,len);    d[len] = '\0';   } else {    strncpy(d,s+st,strlen(s)-st);    d[strlen(s)-st]='\0';  }}int Same(char *s, int st, int len, char *t)/* is t the same as s from st length len? */{  if (st <= strlen(s))    return (strncmp(t,s+st,len) == 0) ? TRUE : FALSE;}int Occurs(char *s, int st, char *t)/* does t occur in s starting at or after st? return index */{  int i;    for(i=st; i<strlen(s); i++)  {    if (strncmp(s+i,t,strlen(t))==0)      return i;  }  return last;   /* no string will be larger than this */}void Del(char *s,int st, int len)/* delete the len characters from s starting at st */{  int i,j,n;    n = strlen(s);  if (st+len-1 >= n)  len = n - st;   /* keep in range */    for(i=st, j=st+len; j<=n; i++, j++)    s[i] = s[j];}/************************************************************/void WriteTheString(FILE *f, char *s)     /* write a string to disk */{  fprintf(f,"%s\n",s);}int ReadTheString(FILE *f, char *s)       /* read a string from disk */{ int c,i;  i=0;  c=fgetc(f);  while ((c!=EOF) && (c!='\n')) {    s[i] = c;    i++;    c = fgetc(f);  }  s[i]='\0';  return (c == EOF) ? TRUE : FALSE;}int up1(int c)/* make c uppercase */{     return (c >= 'a' && c <= 'z') ? c+'A'-'a' : c;}void Upper(char *s)       /* make s uppercase, ignores " " and \ ... */{  int i, quoted;    quoted = FALSE;  i = 0;  while (i <= strlen(s))  {    if (s[i] == '\\') {      i = strlen(s)+10;    }    if (quoted == FALSE) {      s[i] = up1(s[i]);    }    if (s[i] == '"') {      quoted = (quoted == TRUE) ? FALSE : TRUE;    }    ++i;  }}void Upper0(char *s)    /* make s uppercase, ignores nothing */{  int i;    for(i=0;i<strlen(s);i++)    s[i] = up1(s[i]);}void Dispose(struct tree *p)  /* Pascal "Dispose" */{  free(p);}void Insert(struct tree *f, struct tree **r)/* insert a tree node */{  if (*r==NULL)    *r = f;   else {    if (strcmp(f->name, (*r)->name) < 0 )      Insert(f, &(*r)->left);    else      Insert(f,&(*r)->right);  }}void strclr(char *s)/* set the string s to the empty string */{  s[0] = '\0';}void addName(char *s, long int line)/* add a name and line number to the tree */{  struct tree *p;    if (root == NULL) {    root = (struct tree *) malloc(sizeof(struct tree));    if (root != NULL) {      strcpy(root->name,s);      root->line = line;      root->left = NULL;      root->right= NULL;    } else {      printf("Sorry, but there is not enough memory available.\n\n");      exit(1);    }  } else {    p = (struct tree *) malloc(sizeof(struct tree));    if (p != NULL) {      strcpy(p->name,s);      p->line = line;      p->left = NULL;      p->right= NULL;    } else {      printf("Sorry, but there is not enough memory available.\n\n");      exit(1);    }    Insert(p,&root);  }}void StripSuffix(char *s, char *w)/* strips the file suffix if present */{  int i;  char t[MAX];    strcpy(t,s);  Upper(t);  i = Occurs(t,0,".4TH");  if (i != last)    Copy(w,s,0,i);  else {    i = Occurs(t,0,".FORTH");    if (i != last)      Copy(w,s,0,i);    else {      i = Occurs(t,0,".FTH");      if (i != last)         Copy(w,s,0,i);      else        strcpy(w,s);    }  }}void Header(void)/* startup header */{  printf("\n\n");  printf("** Forth2LaTeX 1.9c **    ");  printf("Ronald T. Kneusel, 1994.  This program is freeware\n");  printf("--------------------------");  printf("--------------------------------------------------\n\n");}void GetProgramInfo(void)/* get the title page info */{  int done,ok,n;  char str[MAX],prog[MAX],auth[MAX],start[MAX],       modif[MAX],modby[MAX],sum[MAX],t[MAX];  long int c;    done = FALSE;  strclr(str); strclr(prog); strclr(auth); strclr(start);  strclr(modif); strclr(modby); strclr(sum); strclr(t);  c = 1;  done = ReadTheString(f,str);  while (!done)   {     if ((n=Occurs(str,0,"\\ Program:")) != last) {       Del(str,0,n+10); strcpy(prog,str); }     else if ((n=Occurs(str,0,"\\ Author:")) != last) {       Del(str,0,n+9);  strcpy(auth,str); }     else if ((n=Occurs(str,0,"\\ Started:")) != last) {       Del(str,0,n+10);  strcpy(start,str); }     else if ((n=Occurs(str,0,"\\ Modified:")) != last) {       Del(str,0,n+11);  strcpy(modif,str); }     else if ((n=Occurs(str,0,"\\ Modify By:")) != last) {       Del(str,0,n+12);  strcpy(modby,str); }     else if ((n=Occurs(str,0,"\\ Summary:")) != last) {       Del(str,0,n+10);  strcpy(sum,str); }     else if (Occurs(str,0,"\\ Comments:") != last)        if (Occurs(str,0,"LATEX") != last)         COMMENTS = TRUE;       else if (Occurs(str,0,"FORTH") != last)         COMMENTS = FALSE;     else if (Occurs(str,0,"\\ Uppercase:") != last)        if (Occurs(str,0,"ON") != last)         UP = TRUE;       else if (Occurs(str,0,"OFF") != last)         UP = FALSE;     else if (Occurs(str,0,"\\ Table of Contents:") != last)        if (Occurs(str,0,"ON") != last)         TOC = TRUE;       else if (Occurs(str,0,"OFF") != last)         TOC = FALSE;     else if (Occurs(str,0,"\\ Index:") != last)        if (Occurs(str,0,"ON") != last)         INDEX = TRUE;       else if (Occurs(str,0,"OFF") != last)         INDEX = FALSE;     else if (Occurs(str,0,"\\ Bold:") != last)        if (Occurs(str,0,"ON") != last)         BOLD = TRUE;       else if (Occurs(str,0,"OFF") != last)         BOLD = FALSE;     else if (Occurs(str,0,"\\ Style:") != last)        if (Occurs(str,0,"ON") != last)         RA = TRUE;       else if (Occurs(str,0,"OFF") != last)         RA = FALSE;     done = ReadTheString(f,str);     if ((Occurs(str,0,"ection:")==last) || (Occurs(str,0,"hapter:")==last))       ++c;   } /* while */   strcpy(str,"\\title{{\\bf ");  Append(str,prog);  Append(str,"}}");   WriteTheString(g,str);   strcpy(str,"\\author{{\\small "); Append(str,auth); Append(str,"}}");   WriteTheString(g,str);   WriteTheString(g,"\\date{{\\small \\today}}");   WriteTheString(g,"\\maketitle");   strcpy(str,"\\vspace{4in} \\hfil \\break {\\large{\\bf Program Information:}}");   Append(str," \\hfil \\break");   WriteTheString(g,str);   WriteTheString(g,"\\hfil \\break");   strcpy(str,"{\\bf Summary:}\\ \\ "); Append(str,sum);  Append(str,"\\hfil \\break");   WriteTheString(g,str);   strcpy(str,"{\\bf Author:}\\ \\ "); Append(str,auth); Append(str,"\\hfil \\break");   WriteTheString(g,str);   strcpy(str,"{\\bf Modified:}\\ \\ "); Append(str,modif); Append(str,"\\hfil \\break");   WriteTheString(g,str);   strcpy(str,"{\\bf Modify By:}\\ \\ "); Append(str,modby); Append(str,"\\hfil \\break");   WriteTheString(g,str);   sprintf(t,"%ld",c-1);   strcpy(str,"{\\bf Lines:}\\ \\ "); Append(str,t); Append(str,"\\hfil \\break \\clearpage");   WriteTheString(g,str);}  /* GetProgramInfo */void CopyHeader(void)/* setup the document */{  char s[MAX];    strcpy(s,"\\documentstyle[12pt]{");  if (RA)    Append(s,"report");  else    Append(s,"article");  Append(s,"}");  WriteTheString(g,s);  WriteTheString(g,"\\voffset=-0.8in");  WriteTheString(g,"\\hoffset=-0.5in");  WriteTheString(g,"\\textheight=9in");  WriteTheString(g,"\\textwidth=6.5in");  WriteTheString(g,"\\parindent=0pt");  WriteTheString(g,"\\begin{document}");  WriteTheString(g,"\\pagestyle{plain}");  WriteTheString(g,"\\pagenumbering{roman}");}void HandleComment(int *i, char *str, char *out)/* process the comment portion of a line */{  int latex, q;    Del(str,0,*i);    /* remove leading characters */  if (str[2]=='.') {  /* a \ . comment */    Del(str,0,3);    strcpy(out,str);    NOBRACKET = TRUE;  } else {    Append(out,"}{\\it");  latex = FALSE;    if (!COMMENTS) {      for(q=0;q<strlen(str);q++)       {         if (!latex) {           switch(str[q]){             case ' '  : Append(out,"\\ "); break;  /* convert special LaTeX */             case '_'  : Append(out,"\\_"); break;  /* characters            */             case '\11': Append(out,"\\ \\ \\ \\ "); break;             case '\\' : Append(out,"$\\backslash$"); break;             case '#'  : Append(out,"\\#"); break;             case '&'  : Append(out,"\\&"); break;             case '$'  : Append(out,"\\$"); break;             case '%'  : Append(out,"\\%"); break;             case '}'  : Append(out,"\\}"); break;             case '{'  : Append(out,"\\{"); break;             case '<'  : Append(out,"$<$"); break;             case '>'  : Append(out,"$>$"); break;             case '^'  : Append(out,"$\\uparrow$"); break;             case '`'  : latex = !latex;  break; /* LaTeX escape character */             case '~'  : Append(out,"$\\tilde{ }$"); break;           default:             AppendCh(out,str[q]);           }         } else {           if (str[q] != '`')             AppendCh(out,str[q]);           else             latex = !latex;         }       }      } else {        Append(out,str);      }    }    *i = last;  /* force loop to quit */ } /* HandleComment */ void HandleFunction(int *i, char *str, char *out, long int *c)/* process a colon definition */{   int q,old,s,k;   char name[MAX], t[MAX], w[MAX];   if (((((*i>0) && (str[*i-1]==' ')) && (str[*i+1]==' ')) ||      ((*i==0) && (str[1]==' '))) && (!QUOTE)) {      if (BOLD || INDEX) {        old = *i;        ++(*i);        while ((*i<strlen(str)) && (str[*i]==' '))           ++(*i);        s = *i;        while ((*i<strlen(str)) && (str[*i]!=' '))          ++(*i);        Copy(w,str,s,*i-s);  /* word name */        if (UP) {          strcpy(t,w);          Upper(t);          strcpy(w,t);        }        strclr(name);        for(k=0;k<strlen(w);k++){          switch(w[k]){             case ' '  : Append(name,"\\ "); break;             case '_'  : Append(name,"\\_"); break;              case '\11': Append(name,"\\ \\ \\ \\ "); break;             case '\\' : Append(name,"$\\backslash$"); break;             case '#'  : Append(name,"\\#"); break;             case '&'  : Append(name,"\\&"); break;             case '$'  : Append(name,"\\$"); break;             case '%'  : Append(name,"\\%"); break;             case '}'  : Append(name,"\\}"); break;             case '{'  : Append(name,"\\{"); break;             case '<'  : Append(name,"$<$"); break;             case '>'  : Append(name,"$>$"); break;             case '^'  : Append(name,"$\\uparrow$"); break;             case '~'  : Append(name,"$\\tilde{ }$"); break;           default:             AppendCh(name,w[k]);          }        }        addName(name,*c);   /* add to the tree */        if (BOLD) {          Append(out,":\\ {\\bf ");          Append(out,name);          Append(out,"}\\ ");        } else {          Append(out,":");          *i = old;        }      } else        Append(out,":");      } else        Append(out,":"); } /* HandleFunction */void ProcessString(char *str, char *out, long int *c)/* process a single string character by character */{  char s[MAX];  int  i;    NOBRACKET = FALSE;  strcpy(out,"\\leftline{{\\tt ");#ifndef VAX  sprintf(s,"%5.5li",*c);#endif#ifdef VAX  sprintf(s,"%5.5ld",*c);  for(i=0;i<strlen(s);i++)    if ( s[i]==' ' )      s[i]='0';#endif  Append(out,s);  Append(out,"\\ -\\ ");  i = 0; QUOTE = FALSE;  while (i<strlen(str))   {     switch(str[i]){       case ' '  : Append(out,"\\ "); break;       case '_'  : Append(out,"\\_"); break;       case '\11': Append(out,"\\ \\ \\ \\ "); break;       case '\\' : HandleComment(&i,str,out); break;       case '#'  : Append(out,"\\#"); break;       case '&'  : Append(out,"\\&"); break;       case '$'  : Append(out,"\\$"); break;       case '%'  : Append(out,"\\%"); break;       case '}'  : Append(out,"\\}"); break;       case '{'  : Append(out,"\\{"); break;       case '~'  : Append(out,"$\\tilde{ }$"); break;       case '^'  : Append(out,"$\\uparrow$"); break;       case ':'  : HandleFunction(&i,str,out,c); break;       case '"'  : AppendCh(out,'"');  QUOTE = !QUOTE; break;     default:       if (str[i]>' ') {         if ((!UP) || (QUOTE))           AppendCh(out,str[i]);         else           AppendCh(out,up1(str[i]));       }     } /* switch */     i++;   } /* while */  if (!NOBRACKET) {    Append(out,"}}");    NOBRACKET = FALSE;  }} /* process string */void MoreProcessString( char *str, char *out, long int c)/* handle VARIABLE, and such... */{   char ucStr[MAX], s[MAX], name[MAX];   int  n,i,f,ff;      if (Same(str,0,9,"\\leftline")) {     Del(str,strlen(str)-2,2);  /* remove }} */     Append(str,"\\ ");     strcpy(ucStr,str);     Upper0(ucStr);     strclr(out);     do {       f = FALSE;       i = Occurs(str,0,"{\\it$\\backslash");  /* position of any comment */        if ((n=Occurs(ucStr,0," CREATE\\ ")) != last) {         n += 7;  f = TRUE; }       else if ((n=Occurs(ucStr,0," VARIABLE\\ ")) != last) {         n += 9;  f = TRUE; }       else if ((n=Occurs(ucStr,0," CONSTANT\\ ")) != last) {         n += 9;  f = TRUE; }       else if ((n=Occurs(ucStr,0," FVARIABLE\\ ")) != last) {         n += 10;  f = TRUE; }       else if ((n=Occurs(ucStr,0," FCONSTANT\\ ")) != last) {         n += 10;  f = TRUE; }                if (n >= i)  f = FALSE;       if (f) {         Copy(s,str,0,n);  Append(out,s);         /* get name from str */         Del(str,0,n);  Del(ucStr,0,n);         do {           ff = FALSE;           if (Same(str,0,2,"\\ ")) {             Del(str,0,2);  Del(ucStr,0,2);             Append(out,"\\ ");             ff = TRUE;           }         } while( ff );         n = Occurs(str,0,"\\ ");         Copy(name,str,0,n);  /* get the name */         Append(out,"{\\sf ");         Append(out,name);         Append(out,"}");         Del(str,0,n);  Del(ucStr,0,n);         addName(name,c);  /* add name to list */       }     } while( f );     Append(out,str);     Del(out,strlen(out)-2,2);     Append(out,"}}");   } else {      strcpy(out,str);   }} /* MoreProcessString *//* Globals for OutputIndex */int lineCount,i;      /* number of lines, number of items on a line */char outt[MAX];       /* line to output */void Display(struct tree *p)/* display tree data in LaTeX tabular environment */{   char t[MAX],w[MAX];   int  j;      Append(outt,"{\\rm ");  Append(outt,p->name);  Append(outt,"}\\ {\\tt (");#ifndef VAX  sprintf(w,"%5.5li",p->line);#endif#ifdef VAX  sprintf(w,"%5.5ld",p->line);  for(j=0;j<strlen(w);j++)    if ( w[j]==' ' )      w[j]='0';#endif   Append(outt,w);   if (i<2) {     Append(outt,")} & ");     i++;   } else {     i=0;     Append(outt,")} \\\\");     WriteTheString(g,outt);     strclr(outt);  lineCount++;     if (lineCount>35) {       WriteTheString(g,"\\end{tabular}");       WriteTheString(g,"\\clearpage");       WriteTheString(g,"\\begin{tabular}{lllll}");       lineCount = 0;     }   }} /* display */void WalkTree(struct tree *p)/* Inorder traversal of name tree */{   if (p != NULL) {     WalkTree(p->left);     Display(p);      WalkTree(p->right);   }} /* WalkTree */void OutputIndex(void)/* print the index of names */{   int q;      strclr(outt);  i = 0;  lineCount = 0;   if ( (!RA) || ((RA) && (!TOC)) ) {  /* article */     WriteTheString(g,"\\clearpage");     if (SECTIONS)       WriteTheString(g,"\\section{Index} \\vspace{0.5in}");     else       WriteTheString(g,"\\begin{center} {\\huge Index} \\end{center} \\vspace{0.5in}");     WriteTheString(g,"\\vspace{0.5in}");     WriteTheString(g,"\\hfil \\break");   } else {                            /* report */     WriteTheString(g,"\\appendix");     WriteTheString(g,"\\chapter{Index of User-Defined Names}");   }   WriteTheString(g,"\\begin{tabular}{lllll}");   WalkTree(root);   if (i != 0) {     for(q=1;q<=3-(i+1);q++)       Append(outt," & ");     Append(outt," \\\\");     WriteTheString(g,outt);   }   WriteTheString(g,"\\end{tabular}");} /* outputIndex */void Convert(char *infile, long int *count)/* do the conversion */{   char str[MAX],out[MAX],date[MAX],time[MAX];   int  done,n;      if (FIRST) {     CopyHeader();     GetProgramInfo();     if (TOC)       WriteTheString(g,"\\tableofcontents \\clearpage");     WriteTheString(g,"\\pagestyle{plain}");     WriteTheString(g,"\\pagenumbering{arabic}");     WriteTheString(g,"\\setcounter{page}{1}");     WriteTheString(g,"\\small");     fclose(f);     FIRST = FALSE;     f = fopen(infile,"r");     *count = 0;   }   done = FALSE;   done = ReadTheString(f,str);   strclr(out);   while (!done) {     if ( ((n=Occurs(str,0,"\\ Section:")) != last) && (TOC) ) {       Del(str,0,n+10);       strcpy(out,"\\section{"); Append(out,str);  Append(out,"}");       SECTIONS = TRUE; }     else if ( ((n=Occurs(str,0,"\\ Subsection:")) != last) && (TOC) ) {       Del(str,0,n+13);       strcpy(out,"\\subsection{"); Append(out,str);  Append(out,"}");       SECTIONS = TRUE; }     else if ( ((n=Occurs(str,0,"\\ Subsubection:")) != last) && (TOC) ) {       Del(str,0,n+16);       strcpy(out,"\\subsubsection{"); Append(out,str);  Append(out,"}");       SECTIONS = TRUE; }     else if (Same(str,0,8,"\\ latex:")) {       Del(str,0,8);  WriteTheString(g,str); }  /* \ latex: form */     else if ( (RA) && (TOC) && ((n=Occurs(str,0,"\\ Chapter:"))!=last) ) {       Del(str,0,n+10);       strcpy(out,"\\chapter{"); Append(out,str);  Append(out,"}"); }     else {       ProcessString(str,out,count);       strcpy(str,out);       MoreProcessString(str,out,*count);       (*count)++;     }     WriteTheString(g,out);     out[0]='\0'; str[0]='\0';     done = ReadTheString(f,str);   } /* while */} /* convert */void KillTree(struct tree *p)/* kill the old tree */{   if (p != NULL) {     KillTree(p->left);     KillTree(p->right);     Dispose(p);   }} /* KillTree */void UpdateCount(char *c, char *outfile)/* Kludge to update the count when using multiple files */{   int done;   char str[MAX],*t;      done = FALSE;   f = fopen(outfile,"r");   t = "dpp6113909294.tmp";   g = fopen(t,"w");   done = ReadTheString(f,str);   while (!done) {     if (Occurs(str,0,"{\\bf Lines:}") != last) {       strcpy(str,"{\\bf Lines:}\\ \\ "); Append(str,c);       Append(str," \\hfil \\break \\clearpage");     }     WriteTheString(g,str);     done = ReadTheString(f,str);   }   fclose(f);   fclose(g);   f = fopen(t,"r");   g = fopen(outfile,"w");   done = FALSE;   done = ReadTheString(f,str);   while (!done) {     WriteTheString(g,str);     done = ReadTheString(f,str);   }   fclose(f);  fclose(g);   remove(t);}void CommandFile(char *cmdfile)/* process a .f2l command file */{   int  done,skip,b,n,i;   char str[MAX],outfile[MAX],infile[MAX],t[MAX];   long int c;      printf("Command file: %s\n\n",cmdfile);   w = fopen(cmdfile,"r");   done = FALSE;   strcpy(outfile,"a.tex");   done = ReadTheString(w,str);   while (!done) {     if ((n=Occurs(str,0,"# Output: "))!=last) {       Del(str,0,n+10);       done = TRUE;       strcpy(outfile,str);     }     done = ReadTheString(w,str);   }   fclose(w);   g = fopen(outfile,"w");   printf("Output file : %s\n\nProcessing file...\n\n",outfile);   w = fopen(cmdfile,"r");   c = 0;   done = FALSE;  FIRST = TRUE;   done = ReadTheString(w,str);   while (!done) {     skip = FALSE;       infile[0]='\0';     if ( str[0]!='\0' ) {       n = 0;       while( (str[n]==' ') || (str[n]=='\11') )         n++;       for(i=n;i<strlen(str);i++)         if ( (str[i]!='#') && (!skip) && (str[i]!=' ') )           AppendCh(infile,str[i]);         else           skip = TRUE;     }     if (!Equal(infile,"")) {  /* process this file */       f = fopen(infile,"r");       printf("      %s\n",infile);       Convert(infile,&c);       fclose(f);     }     done = ReadTheString(w,str);   }   if (INDEX)  OutputIndex();   WriteTheString(g,"\\end{document}");   fclose(g);  fclose(w);   sprintf(t,"%ld",c-1);   UpdateCount(t,outfile);   printf("\n\n%s lines total.\n\n",t);} /* CommandFile */void ConvertFile(char *infile)/* handle the source and dest files and convert */{   char t[MAX],outfile[MAX];  long int c;      if ( (Occurs(infile,0,".f2l")!=last) || (Occurs(infile,0,".F2L")!=last) )     CommandFile(infile);   else {     StripSuffix(infile,outfile);     Append(outfile,".tex");     printf("\nStarting conversion...\n\n");     g = fopen(outfile,"w");     FIRST = TRUE;     f = fopen(infile,"r");     Convert(infile,&c);     if (INDEX)       OutputIndex();     fclose(f);     WriteTheString(g,"\\end{document}");     fclose(g);     printf("Conversion complete, %ld lines.\n\n",c);   }   KillTree(root);   root = NULL;} /* ConvertFile */