diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/xtexshell/tfc.cc |
Initial commit
Diffstat (limited to 'support/xtexshell/tfc.cc')
-rw-r--r-- | support/xtexshell/tfc.cc | 499 |
1 files changed, 499 insertions, 0 deletions
diff --git a/support/xtexshell/tfc.cc b/support/xtexshell/tfc.cc new file mode 100644 index 0000000000..206bdc7dec --- /dev/null +++ b/support/xtexshell/tfc.cc @@ -0,0 +1,499 @@ +//***************************************************************************** +//****************** TFC.CC: Text Format Conversion Utility ******************* +//***************************************************************************** +//************************** <C> 1991 by M.Hofmann **************************** +//***************************************************************************** + +//*** 18.01.1994 21:34:18 + +//*** How To Compile: +//*** Use C++ Compiler! +//*** IBM-DOS: Compile with TINY-model +//*** Borland-C: bcc -mt -O -G -lt -Z -d -w tfc.cc +//*** UNIX: GNU-C++: g++ -O2 -m486 -o /usr/bin/tfc tfc.cc +//*** VMS: DEC-CXX: cxx /DEFINE=VMS /OPTIMIZE tfc.cc + +#define TFC + +#ifdef __TURBOC__ + #ifndef __TINY__ + #error compile only with tiny model !! + #endif +#else + #ifdef VMS + #define unlink(a) remove(a) + #else + #include <unistd.h> + #endif +#endif + +// Include standard header files + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +//***************************************************************************** +//******** Messages and error messages **************************************** +//***************************************************************************** + +char license_msg[] = + { "This program is free software; you can redistribute it and/or modify\n" + "it under the terms of the GNU General Public License as published by\n" + "the Free Software Foundation; either version 2 of the License, or\n" + "(at your option) any later version.\n\n" + + "This program is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "GNU General Public License for more details.\n\n" + + "You should have received a copy of the GNU General Public License\n" + "along with this program; if not, write to the Free Software\n" + "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n"}; + +char help_msg[] = + { "\n TFC converts text files between various file formats \n\n" + " Syntax: TFC [-ADELPUVX?] [-T [n]] [-N [n]] input_file [output_file]\n\n" + " -u : DOS -> Unix: Replace all CR/LF with LF, delete Ctrl-Z\n" + " -d : Unix -> Dos: Replace all LF with CR/LF\n" + " -a : DOS -> ASCII: Change DOS-Format to 7 Bit-ASCII-Format\n" + " -n [n]: Number lines: Number output lines. n: start line number\n" + " -t [n]: Expand tabs: Convert tabs to spaces. n: tab spacing (default 8)\n" + " -v : Text -> LaTeX: Generate a LaTeX verbatim list\n" + " -x : DOS -> LaTeX: Convert DOS special characters to LaTeX format\n" + " -p : par mode Check parentheses\n\n" + " -l : license Show software license\n" + " -q : quiet: No output on screen during operation\n\n" + " This is free software, and you are welcome to redistribute it\n" + " under certain conditions; type `tfc -l' for details.\n" + " If ouput_file is omitted, output is sent to input_file. This overwrites\n" + " input_file, so be careful! Return Code: 0 on success\n"}; + +#define MsgTitle1 "\nTFC: Text Format Conversion Utility\n" +#define MsgTitle2 "Version 1.3 <C> Copyright " __DATE__ " by M.Hofmann\n" + +#define MsgOk "\nProgram completed with no errors\n\n" +#define MsgOpenF "\n\nOpening files:\n" +#define MsgIFile "\n Input file ======> (buffer length: %4XH) %s" +#define MsgOFile "\n Output file ====> (buffer length: %4XH) %s" +#define MsgRen "\n Output file will be renamed to %s after completion" +#define MsgConv "\n\n\nConverting data:\n\n" +#define MsgLComp "\r %i lines completed" + +#define MsgOpenPar "WARNING: Unequal number of parentheses found (%i more '%c' than '%c')...\x07\n" +#define MsgOddQuot "WARNING: Odd number of \x22 detected...\x07\n" + +#define ErrNoArg "Wrong number of arguments" +#define ErrNoOpt "Unknown Option specified" +#define ErrNoInFile "Can't open input file" +#define ErrNoInName "No input file name specified" +#define ErrNoOutFile "Can't open output file" +#define ErrClFile "Can't close files" +#define ErrReadF "Error reading file" +#define ErrWrtF "Error writing file" +#define ErrNoRename "Can't rename file" + +//***************************************************************************** +//******** Some useful definitions ******************************************** +//***************************************************************************** + +#define true (-1) +#define false (0) + +typedef unsigned char byte; // 8 bits +typedef unsigned int word; // 16 bits + +//***************************************************************************** +//******* Variables *********************************************************** +//***************************************************************************** + +// Input / Output files + +char iname[100],oname[100]; +FILE *ifile, *ofile; +int renflag = false; + +// Line / column counting + +int lstart = 1; +int lcount = 0; // actual line of output text +int pos = 0; // actual column of output text + +// Flags for operation modes + +int unixmode = false; // Flags for conversion modes +int dosmode = false; +int texlistmode = false; +int nummode = false; +int ascmode = false; +int texmode = false; +int qmode = false; +int parmode = false; +int tabmode = false; +int tabdist = 8; + +// Conversion tables + +char dos2unix[256][10]; +char dos2tex[256][10]; + +char cr_str[10]; // String with proper CR/ CR/LF sequence + +// Other global variables + +int parenum = 0, pargnum = 0, parrnum = 0; // number of open braces +int quotenum = 0; // number of double quotes (") + +//***************************************************************************** +//******* Input / Output functions ******************************************** +//***************************************************************************** + +void ExitErr(char *errmsg,int ErrNum) + +/*** Show an error message and quit program ***/ + +{ + fflush (stdout); + fprintf (stderr, "\n\nError: %s !!!\n\n", errmsg); + fprintf (stderr, "Aborting program (ERC>0)....\n\n"); + fprintf (stderr, "Syntax: TFC [-ADELPUVX?] [-T [n]] [-N [n]] input_file [output_file]\n"); + fprintf (stderr, " TFC -? for help\n\n"); + exit(ErrNum); +} + +void title() + +/*** Print title ***/ + +{ + if (!qmode) { + printf (MsgTitle1); // Print title + printf (MsgTitle2); + } +} + +void help() + +/*** Print Help page and exit ***/ + +{ + printf(help_msg); + exit(0); +} + +void license() + +/*** Print license and exit ***/ + +{ + printf("\n\nLICENSE:\n\n%s", license_msg); + exit(0); +} + +//***************************************************************************** +//****** File I/O ************************************************************* +//***************************************************************************** + +void fileo(char *iname, char *oname) + +/*** Open files iname and oname for reading and writing. If oname=="", ***/ +/*** write to file temp and rename temp to iname when closing files ***/ + +{ + renflag = (oname[0]==0); + if (renflag) strcpy(oname, "temp"); + + if (!qmode) { + printf (MsgOpenF); + printf (MsgIFile MsgOFile,20000,iname,20000,oname); + if (renflag) printf (MsgRen, iname); + } else { + printf ("TFC: %s \t %s", iname, oname); + if (renflag) printf (" --> %s", iname); + printf ("\n"); + } + if ((ifile=fopen(iname,"rb"))==NULL) ExitErr(ErrReadF,1); + if ((ofile=fopen(oname,"wb"))==NULL) ExitErr(ErrWrtF,1); + setvbuf(ifile,NULL,_IOFBF,20000); // Faster with buffers + setvbuf(ofile,NULL,_IOFBF,20000); +} + +void filec() + +/*** Close files and replace input file if inputfile=outputfile ***/ + +{ + if (fclose(ofile)) ExitErr(ErrClFile,1); + if (fclose(ifile)) ExitErr(ErrClFile,1); + + if (renflag) { + if (0!=unlink(iname)) ExitErr(ErrNoRename,1); + if (0!=rename(oname,iname)) ExitErr(ErrNoRename,1); + } +} + +void fp(byte c) + +/*** Write byte c to outputfile. Handle CR / LF ***/ + +{ + switch (c) { + case '\n' : if (EOF==fputs(cr_str,ofile)) ExitErr(ErrWrtF,1); + pos = 0; + lcount++; + break; + case 13 : break; + default : if (EOF==fputc(c,ofile)) ExitErr(ErrWrtF,1); + pos++; + break; + } +} + +void fps(char *s) + +/*** Write string s to outputfile ***/ + +{ + while(*s) fp(*s++); +} + +//***************************************************************************** +//****** System Initialization ************************************************ +//***************************************************************************** + +void setuptables() + +/*** Setup translation tables ***/ + +{ + int i; + + for (i=0; i<127; i++) { + sprintf (dos2unix[i], "%c",i); + sprintf (dos2unix[i+128],"_"); + sprintf (dos2tex[i], "%c",i); + sprintf (dos2tex[i+128], "_"); + } + + strcpy (dos2unix[148], "oe"); strcpy (dos2unix[132], "ae"); + strcpy (dos2unix[129], "ue"); strcpy (dos2unix[153], "Oe"); + strcpy (dos2unix[142], "Ae"); strcpy (dos2unix[154], "Ue"); + strcpy (dos2unix[225], "ss"); + + strcpy (dos2tex[ 21], "\\s{}"); strcpy (dos2tex[135], "\\c{c}"); + strcpy (dos2tex[160], "\\'a"); strcpy (dos2tex[133], "\\`a"); + strcpy (dos2tex[131], "\\^a"); strcpy (dos2tex[130], "\\'e"); + strcpy (dos2tex[136], "\\^e"); strcpy (dos2tex[137], "\x22""e"); + strcpy (dos2tex[138], "\\`e"); strcpy (dos2tex[147], "\\^o"); + strcpy (dos2tex[163], "\\'u"); strcpy (dos2tex[151], "\\`u"); + strcpy (dos2tex[150], "\\^u"); strcpy (dos2tex[139], "\x22""i"); + strcpy (dos2tex[140], "\\^i"); strcpy (dos2tex[148], "\x22""o"); + strcpy (dos2tex[132], "\x22""a"); strcpy (dos2tex[129], "\x22""u"); + strcpy (dos2tex[153], "\x22""O"); strcpy (dos2tex[142], "\x22""A"); + strcpy (dos2tex[154], "\x22""U"); strcpy (dos2tex[164], "\\~n"); + strcpy (dos2tex[165], "\\~N"); strcpy (dos2tex[168], "?`"); + strcpy (dos2tex[173], "!`"); strcpy (dos2tex[225], "\x22""s"); + strcpy (dos2tex[224], "$\\alpha$"); strcpy (dos2tex[248], "$^0$"); + +// Determine proper LF sequence (DOS needs CR/LF) + + #ifdef __MSDOS__ // + strcpy (cr_str,"\x0D\x0A"); + #else + strcpy (cr_str,"\x0A"); + #endif + if (dosmode) + strcpy (cr_str,"\x0D\x0A"); + if (unixmode) + strcpy (cr_str,"\x0A"); +} + +//***************************************************************************** +//******* Translate Input File ************************************************ +//***************************************************************************** + +void convchar(int c) + +/*** Translates the character c and writes it to the output file ***/ + +{ +// Check for ASCII Control codes (c<20h) + + if (unixmode && c==26) return; + + if (tabmode && c==9) { + do { fp (' '); } while (pos % tabdist); + return; + } + +// Check brace level + + if (parmode) { + switch(c) { + case 34 : quotenum++;break; /* " */ + case 40 : parrnum++;break; /* ( */ + case 41 : parrnum--;break; /* ) */ + case 91 : parenum++;break; /* [ */ + case 93 : parenum--;break; /* ] */ + case 123 : pargnum++;break; /* { */ + case 125 : pargnum--;break; /* } */ + } /* while */ + } + +// ASCII-Translation ? + + if (ascmode) { + fps (dos2unix[c]); + return; + } + +// TeX-Translation ? + + if (texmode) { + fps (dos2tex[c]); + return; + } + +// No Translation ! + + fp(c); +} + +void convtext() + +{ + int register c = 0; + char s[10]; + + if (!qmode) + printf (MsgConv); // print message + + if (texlistmode) { // if Latex List mode: print start commands + fps ("%***\n"); + fps ("%*** File: "); fps (iname); + fps ("\n%*** Formatted for: LaTeX by TFC V1.3 ("__DATE__")\n%***\n"); + fps ("{\\scriptsize\n\\begin{verbatim}\n"); + lstart-=lcount; + } + + while (EOF!=(c=fgetc(ifile))) { + if (c==26) break; + +// Start of a new line ? + + if (pos==0) { + if (!((lcount-1) % 64) && !qmode) // Print line number + printf(MsgLComp,lcount); + + if (nummode) { // Number lines in output file + sprintf(s,"%5i: ",lcount+lstart); + fps(s); + } + } + +// Translate and output character + + convchar (c); + } /* while */ + +// Ok, the whole file was translated. Print messages to user + + if (!qmode) { + printf(MsgLComp,lcount); + printf ("\n\n"); + } + if (ferror(ifile)) ExitErr(ErrReadF,1); + + if (texlistmode) // End of LaTeX environment + fps ("\\end{verbatim}\n}"); + + if (parmode) { + if (quotenum % 2) printf (MsgOddQuot); // Even Number of quotes? + if (pargnum>0) printf (MsgOpenPar, pargnum,'{','}'); // All Braces closed? + if (pargnum<0) printf (MsgOpenPar,-pargnum,'}','{'); + if (parenum>0) printf (MsgOpenPar, parenum,'[',']'); + if (parenum<0) printf (MsgOpenPar,-parenum,']','['); + if (parrnum>0) printf (MsgOpenPar, parrnum,'(',')'); + if (parrnum<0) printf (MsgOpenPar,-parrnum,')','('); + } +} + +//***************************************************************************** +//****** Main program ********************************************************* +//***************************************************************************** + +int main (int argc, char *argv[]) + +{ + int i, j; + char c; + + iname[0] = oname[0] = '\0'; // No filenames so far + +// Scan input line + + for (i=1; i<argc; i++) { // Scan input line for arguments + if (argv[i][0] == '-') { // is it an option ? + for (j = 1; j > 0 && 0 != (c=toupper(argv[i][j])); j++) { + switch(c) { + case ('U') : unixmode = true; break; + case ('D') : dosmode = true; break; + case ('A') : ascmode = true; break; + case ('P') : parmode = true; break; + case ('Q') : qmode = true; break; + case ('V') : texlistmode = true; break; + case ('X') : texmode = true; break; + case ('H') : + case ('?') : title();help(); break; + case ('L') : title();license(); break; + case ('N') : nummode = true; + if (1 == sscanf (argv[i+1], "%d", &lstart)) { + i++; j = -1; + } + break; + case ('T') : tabmode = true; + if (1 == sscanf (argv[i+1], "%d", &tabdist)) { + i++; j = -1; + } + break; + default : title(); + ExitErr(ErrNoOpt,1); + } /* switch */ + } + } else { // Seems to be a file name + if (iname[0]==0) { + strcpy(iname,argv[i]); + } else { + if (oname[0]!=0) + ExitErr(ErrNoArg,1); + strcpy(oname,argv[i]); + } + } /* if */ + } /* for */ + +// Print Title + + title(); // Print title message + +// Check parameters and options + + if (!iname[0]) ExitErr(ErrNoInName,1); + +// Initialize system + + setuptables(); + +// Convert text file + + fileo(iname,oname); // Open files + convtext(); // Convert input file + filec(); // Close file + +// No error occurred: Prepare for exit + + if (!qmode) + printf (MsgOk); + exit(0); +} |