[comp.sources.misc] PEP filter program part 1 of 5

gisle@ifi.uio.no (Gisle Hannemyr) (12/30/89)

Posting-number: Volume 9, Issue 92
Submitted-by: gisle@ifi.uio.no (Gisle Hannemyr)
Archive-name: pep/part01

# This is a shell archive [ part 1 of of 5 ]
# Remove everything above and including the cut line.
# Then run the rest of the file through /bin/sh (not csh).
#--cut here-----cut here-----cut here-----cut here-----cut here-----cut here--#
#!/bin/sh
# shar: Shell Archiver
# Execute the following text with /bin/sh to create the file(s):
#	Doc/aaaread.me
#	Doc/header.txt
#	ansi.c
# This archive created: Fri Dec 29 14:56:49 1989
# Wrapped by: Gisle Hannemyr (gisle@ifi.uio.no)
echo shar: extracting aaaread.me
sed 's/^XX//' << \SHAR_EOF > aaaread.me
XXRELEASE-NOTES
XX=============
XX
XXName:	     pep, ver. 2.1
XXAuthor:	     Gisle Hannemyr, Brageveien 3A, N-0452 Oslo, Norway.
XX	     EAN:  gisle@nr.uninett
XX	     Inet: gisle@ifi.uio.no
XX	     UUCP: ..!mcvax!ifi!gisle
XXPurpose:     Detergent for "dirty" files
XXLanguage:    K&R C
XXEnvironment: Fairly generic (CP/M, MS-DOS, UNIX, VMS)
XXFiles:	     PEP21.ARC
XX	     Contents:
XX		aaaread.me   -- this file
XX		header.txt   -- advice about portability of pep
XX		pep.1l	     -- manual page (nroff source)
XX		Makefile.dos -- commands to make distribution (MS-DOS)
XX		Makefile.unx -- commands to make distribution (Unix)
XX		Makevms.com  -- DCL script to compile and link (VMS)
XX		ansi.c	     -- ansi terminal interpreter
XX		bdmg.c	     -- DUCOS brain damage compensation
XX		main.c	     -- root module
XX		plain.c	     -- standard filter module
XX		bdmg.h	     -- bdmg.c types and functions
XX		pep.h	     -- types and functions for pep
XX		mac2ibm	     -- sample conversion table
XX		ibm2mac	     -- sample conversion table
XX		ebc2ns7	     -- conv.-table EBCDIC to NS 4551
XX		ibm2ro8	     -- conv.-table IBM-PC to ROMAN8
XX		ro82ibm	     -- ditto
XX		ibm2iso	     -- conv.-table CP 850 to ISO 8859/1
XX		iso2ibm	     -- ditto
XX
XX
XXDescription:
XX   Pep is a general purpose filter and file cleaning program.
XX   It is named after an excellent Norwegian detergent.	Pep may
XX   be used to expand/compress tabs; convert to and from several
XX   character sets; to interprete ANSI escape sequences; and to
XX   remove unanted line noise from files.  See the file pep.doc
XX   for a complete description.
XX
XX
XXInstallation:
XX   The steps required to install pep are:
XX
XX   1) Print the manual page pep.doc on paper, and read it.
XX   2) Compile the source file pep.c to a executable file.
XX   3) Install the executable file.
XX   4) Install the conversion tables.
XX   5) Modify your startup profile as required.
XX
XX   In more detail:
XX
XX   1) If you have troff or ptroff, you may want to typeset the manual.
XX      The troff command is: troff -man pep.1l .
XX
XX   2) One executable file (pep.exe) for MS-DOS systems is included
XX      in the distribution archive.  If you are able to use this,
XX      you may skip the compilation.
XX
XX      If you want to install pep on another operating system, you must
XX      first compile it.	 Instructions for compilation on several common
XX      systems are at the start of the source file. A makefile is
XX      also supplied.  Pep is fairly generic and should compile with
XX      almost any C-compiler after very little tweaking.	 Read the file
XX      "header.txt" for advise about what pep expect to find in the
XX      header files.
XX
XX   3) The executable will be named pep.exe, pep.com, pep.cmd or just
XX      pep, depending upon which operating system you are using.	 See
XX      operating system notes below for recommended placement.
XX
XX   4) This are the files named mac2ibm, ro82ibm, ibm2ro8, etc.
XX      You may want to add your conversion tables, which should be
XX      installed in the same directory as those in the distribution.
XX      As with executables, see the notes below for hints about where
XX      tables should be installed on different systems.
XX
XX   5) Pep uses one environment variable: PEP, which should be defined
XX      in the startup profile if possible.
XX
XX
XXOperating system notes:
XX   Below is some notes on points pertaining to the different operating
XX   systems:
XX
XX   * CP/M systems:
XX     Install the executable file and the conversion filters under
XX     user 0.  CP/M does not have a startup profile or environment
XX     variables.
XX
XX   * MS-DOS systems:
XX     Install PEP.EXE in a directory that is defined in your PATH
XX     environment variable, and define an environment variable PEP
XX     pointing to the directory where the conversion filters are
XX     installed.	 If this is "c:\usr\lib" your startup profile
XX     AUTOEXEC.BAT should contain a line like this:
XX
XX	set PEP=c:\usr\lib
XX
XX     Alternatively, you may put the conversion tables in the same
XX     directory as you put the executables.  If you use this alternative,
XX     it is not necessary to define the PEP environment variable.
XX
XX   * UNIX systems:
XX     Install the executable file pep in a directory that is defined
XX     in your PATH environment variable (a canonical place will be
XX     /usr/local/bin).  Install the conversion table in a directory of
XX     your choice (a canonical place will be /usr/local/lib).
XX     Define an environment variable PEP pointing to the directory where
XX     the conversion filters are installed.  If this is "/usr/local/lib"
XX     your startup profile (.login on BSD systems, .profile on SYS-V)
XX     should contain a line like this:
XX
XX	setenv PEP /usr/local/lib
XX
XX     Also, Unix users may want to install the manpage "pep.1l" in the
XX     online manual.  The canonical placement is /usr/man/manl.
XX
XX   * VMS systems:
XX     Pep need to be installed as a "foreign command", and you need
XX     to define a symbol pointing to the conversion filters.  If both
XX     the executable file and the filters is placed in directory named
XX     "disk_daf:<d_progbib.vms>", you need to have the following two
XX     lines in your startup profile LOGIN.COM.
XX
XX	$ pep :== $disk_daf:<d_progbib.vms>pep
XX	$ define PEP "disk_daf:<d_progbib.vms>"
XX
XX     Incidently, this is where pep is installed on the University of
XX     Oslo VMS Vax cluster.  If you have an account on one of the
XX     machines in this cluster, having the two lines above in your
XX     LOGIN.COM is all you need to use pep on these machines.
XX
XX     Also note that VMS does not support pipes and redirection, and
XX     it is therefore awkward to use pep as a filter under VMS.	The
XX     distributed version does not even try to run as a filter under
XX     VMS, it has the -o option (write output back on file named as
XX     input file) permanently enabled.
XX
XX
XXVersion 2.1, news:
XX   * The -u option is expanded to allow user's to specify canonical
XX     line terminator.
XX   * New option: -v, to make pep generate hard line terminators only
XX     between paragraphs.
XX   * New conversion table "ebc2ns7" for EBCDIC and DisplayWrite.
XX   * Some old conversion tables are expanded.
XX   * Bugfixes.
XX
XX..EOF
SHAR_EOF
if test 6074 -ne "`wc -c aaaread.me`"
then
echo shar: error transmitting aaaread.me '(should have been 6074 characters)'
fi
echo shar: extracting header.txt
sed 's/^XX//' << \SHAR_EOF > header.txt
XX(( Last edit: 1 dec 89 ))
XX
XX
XX            Microcomputer C header files assumptions
XX            ========================================
XX
XXTo avoid having my C programs looking like a  tangle  of  macroes
XXand ifdefs,  I've started canonizing  the  header  files  for the
XXdifferent C compilers I use.  My starting point is the draft ANSI
XXC standard,  with generous influence  from  Borlands  Turbo-C 2.0
XXand Microsoft C 5.1.
XX
XXBelow is what my programs assume about the standard header files.
XXIf your compiler has  trouble  compiling  a  program  written  or
XXsupported by me, the assumptions below should help you a long way
XXtowards successful compilation.
XX
XX(( If you don't want to hack the standard headers  supplied  with
XXyour compiler,  you may create an extra  header named  "gh.h"  or
XXsomething, put everything in it, and include that. ))
XX
XX
XXDOS.H
XX=====
XX
XX* There should exist a header named dos.h, which  should  contain
XX  macro definitions,  function declarations and  type definitions
XX  for the operating system functions.
XX
XX* Dos.h is supplied with Turbo C and  Microsoft  C.  AZTEC  users
XX  should copy (or rename) IO.H to DOS.H.
XX
XX* Dos.h  should  define  symbolic  names  for  the  file   system
XX  attribute flags.
XX
XX  For MS-DOS, this should look like:
XX
XX  #ifdef __MSDOS__
XX  #define _A_NORMAL 0x00 /* Normal (r/w) file         */
XX  #define _A_RDONLY 0x01 /* Read only attribute       */
XX  #define _A_HIDDEN 0x02 /* Hidden file               */
XX  #define _A_SYSTEM 0x04 /* System file               */
XX  #define _A_LABEL  0x08 /* Volume label              */
XX  #define _A_DIREC  0x10 /* Directory                 */
XX  #define _A_ARCH   0x20 /* Archive                   */
XX  #endif
XX
XX
XXSTDIO.H
XX=======
XX
XX* Stdio.h  should  define  symbolic  names  for   standard   file
XX  descriptors (see ref. 1, sec. 8.1, p. 160) as follows:
XX
XX  #define STDIN  (0)
XX  #define STDOUT (1)
XX  #define STDERR (2)
XX
XX
XXReferences
XX----------
XX
XX1) Brian W. Kernighan and Dennis M. Ritchie (1st edition):  The C
XX   Programming Language; Prentice-Hall, New Jersey, 1978.
XX
XX2) Richard Relph:  Preparing for ANSI C; Dr. Dobb's Journal, vol.
XX   12, issue 7,  p. 16-23, M&T Publishing,  Redwood City,  August
XX   1987.
XX
XX3) ISO/TC97/SC22/WG14-C, N369;   Programming  Language  C  (Final
XX   Working Draft), ISO, August 1987.
XX
XX                                                         -gisle h
XX
XXComments, suggestions or flames to:
XX   smail: Gisle Hannemyr, Brageveien 3A, N-0452 Oslo, Norway.
XX   EAN:	  gisle@nr.uninett
XX   Inet:  gisle@ifi.uio.no
XX   UUCP:  ..!mcvax!ifi!gisle
XX   BBS:	  a number of Oslo based BBS's
XX
XX..EOF
SHAR_EOF
if test 2579 -ne "`wc -c header.txt`"
then
echo shar: error transmitting header.txt '(should have been 2579 characters)'
fi
echo shar: extracting ansi.c
sed 's/^XX//' << \SHAR_EOF > ansi.c
XX/* ansi.c  1989 december 10 [gh]
XX+-----------------------------------------------------------------------------
XX| Abstract:
XX|    Ansi terminal interpreter.
XX|
XX| Authorship:
XX|    Copyright (c) 1988, 1989 Gisle Hannemyr.
XX|    Permission is granted to hack, make and distribute copies of this module
XX|    as long as this notice and the copyright notices are not removed.
XX|    If you intend to distribute changed versions of this module, please make
XX|    an entry in the "history" log (below) and mark the hacked lines with your
XX|    initials. I maintain the module, and shall appreiciate copies of bug
XX|    fixes and new versions.
XX|    Flames, bug reports, comments and improvements to:
XX|       snail: Gisle Hannemyr, Brageveien 3A, 0452 Oslo, Norway
XX|       email: X400: gisle@nr.uninett
XX|              RFC:  gisle@ifi.uio.no
XX|              (and several BBS mailboxes in the Oslo area).
XX|
XX| Access programs:
XX|    void doansi() : Interprete one file.
XX|
XX| History:
XX|     4 jun 89 [gh] Latest update.
XX|
XX| Bugs:
XX|    * Currently, highlighting etc. in ANSI sequences is removed. It might be
XX|      fun to translate the lot into Postscript.
XX|    * Not all ANSI sequences are implemented so far.  It should cover
XX|      ANSI.SYS, but some exotic stuff are left out, as well as the NANSI.SYS
XX|      extensions.  All unknown sequences produces an error message.  Users
XX|      who can explain the exact sematics of such sequences are encouraged
XX|      to contact author.
XX|
XX| See main module for more comments.
XX+---------------------------------------------------------------------------*/
XX
XX#include <stdio.h>
XX#include "pep.h"
XX#include <ctype.h>
XX
XX
XX/*---( defines )------------------------------------------------------------*/
XX
XX#define MAXPAR      3                   /* Max no. of ANSI param's to store */
XX#define MAXX        80                  /* ANSI terminal screen width       */
XX#define MAXY        25                  /* ANSI terminal screen height      */
XX
XX/*---( variables )----------------------------------------------------------*/
XX
XXstatic unsigned char Screen[MAXX][MAXY];    /* Output ANSI terminal screen  */
XXstatic int  GuardL;                         /* ANSI overwrite guard level   */
XXstatic int  LineYy = 0;                     /* ANSI terminal cursor pos.    */
XX
XX
XX/*---( housekeeping )-------------------------------------------------------*/
XX
XX/*
XX| Abs: Display ansi warning message.
XX*/
XXstatic void amess(err,cc)
XXint err, cc;
XX{
XX   fprintf(stderr,"\ransi (%ld): ",LCount);
XX   switch(err) {
XX      case  1: fprintf(stderr,"exepected 5bh  (got <%02xh>)",cc); break;
XX      case  2: fprintf(stderr,"unknown ANSI command <%02xh>",cc); break;
XX      case  3: fprintf(stderr,"unknown control code <%02xh>",cc); break;
XX      case  4: fputs("X right of screen edge",     stderr);       break;
XX      case  5: fputs("X left of screen edge",      stderr);       break;
XX      case  6: fputs("Y above screen edge",        stderr);       break;
XX      case  7: fputs("auto line wrap (warning)",   stderr);       break;
XX      case  8: fputs("cursor outside screen",      stderr);       break;
XX      default: fputs("unknown error",              stderr);       break;
XX   } /* switch */
XX   putc('\n',stderr);
XX} /* amess */
XX
XX
XX/*---( ansi emulation )-----------------------------------------------------*/
XX
XX/*
XX| Abs: Erase entire screen and send cursor home.
XX*/
XXstatic void clearscreen()
XX{
XX   int xx, yy;
XX
XX   for (xx = 0; xx < MAXX; xx++) for (yy = 0; yy < MAXY; yy++)
XX      Screen[xx][yy] = ' ';
XX   LineXx = 0;
XX   LineYy = 0;
XX} /* clearscreen */
XX
XX
XXstatic void docrlf()
XX{
XX   if      (EndOLn == -1) { putc('\r',Fdo); putc('\n',Fdo); }
XX   else if (EndOLn != -2)   putc(EndOLn,Fdo);
XX} /* docrlf */
XX
XX
XX/*
XX| Abs: Print a horizontal line,
XX*/
XXstatic void horline()
XX{
XX   int xx;
XX   for (xx = 0; xx < (MAXX-1); xx++) putc('=',Fdo); docrlf();
XX} /* horline */
XX
XX
XX/*
XX| Abs: Print screen image.
XX*/
XXstatic void printscreen(frame)
XXint frame;
XX{
XX   int xx, yy;
XX   static int oldframe = FALSE;
XX
XX   if (oldframe) horline();
XX   for (yy = 0; yy < MAXY; yy++) {
XX      xx = MAXX-1;
XX      while ((xx) && (Screen[xx][yy] == ' ')) { Screen[xx][yy] = '\0'; xx--; }
XX      xx = 0;
XX      while (Screen[xx][yy]) { putc(Screen[xx][yy],Fdo); xx++; }
XX      docrlf();
XX      showprogress();
XX   }
XX   if (oldframe) horline();
XX   oldframe = frame;
XX   clearscreen();
XX} /* printscreen */
XX
XX
XXstatic void pputc(cc)
XXchar cc;
XX{
XX   if (LineXx >= MAXX) {
XX      LineXx = 0; LineYy++;
XX      amess(7); /* auto line wrap (warning) */
XX   } else if ((LineXx < 0) || (LineYy >= MAXY) || (LineYy < 0)) {
XX      amess(8); /* cursor outside screen */
XX      printscreen(FALSE);
XX   }
XX   switch (GuardL) {
XX      case 2: if (Screen[LineXx][LineYy] != ' ') break;
XX      case 1: if (cc == ' ') break;
XX      case 0: Screen[LineXx][LineYy] = cc;
XX   }
XX   LineXx++;
XX} /* pputc */
XX
XX
XX/*
XX| Abs: Interprete ANSI command after ESC CSI.
XX*/
XXstatic void esccsi()
XX{
XX   int ii, jj, cc, dd;
XX   int pp[MAXPAR];
XX   static int oldxx, oldyy;
XX
XX   for (ii = 0; ii < MAXPAR; ii++) pp[ii] = 0; dd = ii = 0;
XX   while ((cc = getc(Fdi)) != EOF) {
XX      if (isdigit(cc)) { pp[ii] = pp[ii] * 10 + cc - '0'; dd++; }
XX      else if (cc == ';') {
XX         if (!dd) pp[ii] = 1; /* default to 1 */
XX         dd = 0;
XX         if (ii < MAXPAR-1) ii++;
XX      }
XX      else break;
XX   }
XX   if (dd) ii++; /* We've one parameter that's not terminated */
XX   for (jj = ii; jj < MAXPAR; jj++) pp[jj] = 1;    /* Default */
XX   /* Exotic stuff we do not attempt to interprete       *
XX   |  case 'h': break; /* + SM  -- set   mode            *
XX   |  case 'l': break; /* + RM  -- reset mode            *
XX   |  case 'p': break; /* + KKR -- keyboard key reassign *
XX   |  case 'R': break; /* + CPR -- cursor position rep.  *
XX   |
XX   |  NANSI stuff for future implementation              *
XX   |  case '@': /*   ICH -- insert characters            *
XX   |  case 'L': /*   IL  -- insert lines                 *
XX   |  case 'M': /*   DL  -- delete lines                 *
XX   |  case 'P': /*   DCH -- delete characters            *
XX   |  case 'y': /*   OCT -- output chr. translate        *
XX   */
XX   switch (cc) {
XX      case 'A': /* + CUU -- cursor up             */
XX         LineYy -= pp[0];
XX         if (LineYy < 0) { amess(6); LineYy = 0; } /* Y above screen edge  */
XX         break;
XX      case 'B': /* + CUD -- cursor down           */
XX         LineYy += pp[0];
XX         if (LineYy >= MAXY) printscreen(FALSE);
XX         break;
XX      case 'C': /* + CUF -- cursor forward        */
XX         LineXx += pp[0];
XX         if (LineXx >= MAXX) { amess(4); LineXx = MAXX - 1; } /* X right of screen */
XX         break;
XX      case 'D': /* + CUB -- cursor backward       */
XX         LineXx -= pp[0];
XX         if (LineXx < 0) { amess(5); LineXx = 0; } /* X left of screen edge */
XX         break;
XX      case 'H': /* + CUP -- cursor position       */
XX         LineXx = pp[1] - 1; LineYy = pp[0] -1;
XX         break;
XX      case 'J': /* + ED  -- erase display         */
XX         if (pp[0] == 2) printscreen(TRUE);
XX         else { amess(2,cc); pputc(cc); } /* unknown ANSI command */
XX         break;
XX      case 'K': /* + EL  -- erase in line         */
XX         if (!GuardL) while (LineXx < MAXX) Screen[LineXx++][LineYy] = ' ';
XX         break;
XX      case 'f': /*   HVP -- cursor position       */
XX         LineXx = pp[1] - 1; LineYy = pp[0] - 1;
XX         break;
XX      case 'n': /* + DSR -- device staus report   */
XX         break;
XX      case 'm': /* + SGR -- set graphic rendition */
XX         break;
XX      case 's': /* + SCP -- save cursor position  */
XX         oldxx = LineXx;
XX         oldyy = LineYy;
XX         break;
XX      case 'u': /* + RCP -- restore cursor pos.   */
XX         LineXx = oldxx;
XX         LineYy = oldyy;
XX         break;
XX      default: amess(2,cc); pputc(cc); /* unknown ANSI command */
XX   } /* switch */
XX   /*
XX   if (hack) {
XX      printf("CSI: ");
XX      for (jj = 0; jj < ii; jj++) printf("%d;",pp[jj]);
XX      printf("%c\n",cc);
XX   }
XX   */
XX} /* esccsi */
XX
XX
XX/*---( file loop )----------------------------------------------------------*/
XX
XX/*
XX| Abs: Read (and write) one complete ANSI-file.
XX| Par: guardl = ANSI overwrite guard level.
XX*/
XXvoid doansi(guardl)
XXint guardl;
XX{
XX   int cc;
XX
XX   GuardL = guardl;
XX   clearscreen();
XX   while ((cc = getc(Fdi)) != EOF) {
XX      if ((cc >= 0x20) && (cc <= 0xff)) pputc(cc);
XX      else if (cc == 0x07) ; /* BELL    */
XX      else if (cc == '\b') { /* BS      */
XX         LineXx--;
XX         if (LineXx < 0) { amess(5); LineXx = 0; } /* X left of screen edge */
XX      }
XX      else if (cc == '\t') LineXx = (LineXx / ITabSz + 1) * ITabSz;
XX      else if (cc == '\n') { LineYy++; if (LineYy >= MAXY) printscreen(FALSE); }
XX      else if (cc == '\r') LineXx = 0;
XX      else if (cc == 0x1b) { /* ESC     */
XX         cc = getc(Fdi);
XX         if (cc == 0x5b) esccsi(); else amess(1,cc); /* exepected 5bh */
XX      }
XX      else amess(3,cc); /* unknown control code */
XX   } /* while */
XX   printscreen(FALSE);
XX} /* doansi */
XX
XX/* EOF */
SHAR_EOF
if test 8911 -ne "`wc -c ansi.c`"
then
echo shar: error transmitting ansi.c '(should have been 8911 characters)'
fi
#	End of shell archive
exit 0