/*  efr.c  -- (main in efr)  Copyright © 1989 by William F. Hammond  */
#ifndef TDM_H
#include "tdm.h"
#endif
/*********************************************************************/
void main(argc, argv)
USHORT argc;
UBYTE *argv[];
{
static UBYTE welcome[] =
" Etale File Reader by William F. Hammond, Copyright ‹ 1989-freely distributable ";
static UBYTE caution[] =
"   Reading standard input; to quit enter \"<Control>-c\"                          ";
struct Screen *screen;
struct FileHandle *stdinh;
struct IntuiMessage *imsg;
ULONG flags, ilock;
LONG golinea;
USHORT type;
SHORT code, proc, wherefile, jfr;
BYTE goloop;
UBYTE igtch, kill;
if(argc <= 0) exit(0);            /*   call from WorkBench not allowed   */
stream = stdin;
filearg = NULL;
proc = argc;
while(proc)
   {
   if(proc > 3)
      {
/*  Usage:  efr [t] file  OR  efr < file [t]  OR  efr < golist g file  */
      errsp[0] = (UBYTE *)"Usage:  ";
      errsp[1] = argv[0];
      errsp[2] = (UBYTE *)" [t] file  OR  ";
      errsp[3] = argv[0];
      errsp[4] = (UBYTE *)" < file [t]  OR  ";
      errsp[5] = argv[0];
      errsp[6] = (UBYTE *)" <golist g file\xa";
      strcpy(errstr, errsp[0]);
      for(jfr = 1; jfr < 7; jfr ++) strcat(errstr, errsp[jfr]);
      fputs(errstr, stderr);
      exit(10);
      }
   wherefile = 0; gflag = NULB; tflag = NULB;
   if(proc == 3)
      {
      if( strlen(argv[1]) !=1 ) proc = 4;
      else
         {
         if( (argv[1][0] | 0x20) == 'g') gflag = ONEB;
         if( (argv[1][0] | 0x20) == 't') tflag = ONEB;
         if( (gflag | tflag) == 0 ) proc = 4;
         if(proc == 3) wherefile = 2;
         }
      }
   if(proc ==2)
      {
      wherefile = 1;
      if(strlen(argv[1]) == 1)
         {
         if( argv[1][0] == '?' ) {wherefile = 0; proc = 4;}
         if( (argv[1][0] | 0x20) == 't') {wherefile = 0; tflag = ONEB;}
         }
      }
   if(wherefile)
      {
      filearg = fopen(argv[wherefile], "r");
      if(filearg == NULL)
         {
         errsp[0] = (UBYTE *)"Cannot open file \"";
         errsp[1] = argv[wherefile];
         errsp[2] = (UBYTE *)"\"\xa";
         strcpy(errstr, errsp[0]);
         for(jfr = 1; jfr < 3; jfr ++) strcat(errstr, errsp[jfr]);
         fputs(errstr,stderr);
         exit(10);
         }
      stream = filearg;
      }
   if(proc < 4) proc = 0;
   }        /*  end of "proc" loop  */
IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library", 33L);
if (IntuitionBase == NULL)
   {
   fputs("main: Cannot open intuition library, v. 33\xa", stderr);
   if(filearg) fclose(filearg);
   exit(21);
   }
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 33L);
if (GfxBase == NULL)
   {
   fputs("main: Cannot open graphics library, v. 33\xa", stderr);
   CloseLibrary(IntuitionBase);
   if(filearg) fclose(filearg);
   exit(22);
   }
flags = ACTIVATE|BORDERLESS|SMART_REFRESH|NOCAREREFRESH;
type = 0x000F;   /*  Aztec says CUSTOMSCREEN = 0x000FL  */
ilock = LockIBase(0L);
screen = IntuitionBase->ActiveScreen;
mw = makewindow(0,0,screen->Width,screen->Height,"",flags,screen,type);
UnlockIBase(ilock);
if (mw == NULL)
   {
   fputs("main: Cannot open window\xa", stderr);
   CloseLibrary(GfxBase);
   CloseLibrary(IntuitionBase);
   if(filearg) fclose(filearg);
   exit(24);
   }
kill = NULB;
rp = mw->RPort;
SetAPen(rp, 1L);
SetBPen(rp, 0L);
Move(rp, 0L, 0L);
SetDrMd(rp, (LONG)JAM2);
ClearScreen(rp);
enable = AskSoftStyle(rp);
style = (ULONG)FS_NORMAL;
savestyle = SetSoftStyle(rp, style, enable);
SetDrMd(rp, (LONG)(JAM2|INVERSVID));
Move(rp, 0L, (LONG)(rp->TxBaseline));
Text(rp, welcome, (ULONG)strlen(welcome));
maxrowpix = (mw->Height) + (rp->TxBaseline) - (rp->TxHeight);
maxline = (maxrowpix - rp->TxBaseline)/rp->TxHeight;
if(strcmp(argv[0],"efr"))Delay(25L);
if(maxline < 3)
   {
   fputs("Font too tall for this reader on this screen\xa", stderr);
   kill = ONEB;
   }
ModifyIDCMP(mw, VANILLAKEY);
if( (filearg == NULL) || gflag )
   {
   Move(rp, 0L, (LONG)(rp->TxBaseline + rp->TxHeight));
   Text(rp, caution, (ULONG)strlen(caution));
   stdinh = Input();
   if(stdinh == NULL)
      {
      fputs("Standard input handle unavailable\xa", stderr);
      kill = ONEB;
      }
   if(!kill)
      {
      if(IsInteractive(stdinh))
         {
         fputs("Using standard input; enter \"<Control>-\\\" to quit\xa",
                stderr);
         while( (!kill) && (!WaitForChar(stdinh, 5L)) )
            {
            igtch = NULB;
            while(imsg = (struct IntuiMessage *)GetMsg(mw->UserPort))
               {
               if(imsg->Class == VANILLAKEY) igtch = (UBYTE)imsg->Code;
               ReplyMsg(imsg);
               }
            if(igtch == 0x03) kill = ONEB;
            }
         }                         /*   if   IsInteractive(stdinh)   */
      }                         /*   if   !kill                     */
   }                         /*   if  filearg == NULL  OR  gflag   */
delta = ( (4 * rp->TxHeight) + 5)/10;
instr = AllocMem((LONG)(MAXSTRLN+1), MEMF_CLEAR);
pvstr = AllocMem((LONG)(MAXSTRLN+1), MEMF_CLEAR);
if ( (instr == NULL) || (pvstr == NULL) )
   {
   fputs("main: Insufficient memory for line buffers\xa", stderr);
   kill = ONEB;
   }
linesize = 0L;
txtline = 0L;
golinet = 1L;
code = 1;
if(gflag)
   {
   code = -1;
   }
if(kill) code = 0;
while (code)
   {
   if(code < 0)      /*  pick up golinet from stdin  */
      {
      goloop = ONEB;
      while(goloop)
         {
         if( (bfgets(instr, MAXSTRLN , stdin)) == NULL )
            {
            goloop = NULB;
            gflag = 0;   /*  use current line passed in golinet  */
            }
         else
            {
            instr[MAXSTRLN] = '\0';
            golinea = tnump(instr);
            if(golinea > 0L)
               {
               golinet = golinea;
               goloop = NULB;
               }
            }
         }
      }
   golinem = golinet;              /*  golinet is line requested by user  */
   if (golinem <= 0L) golinem = 1L;
   if (golinem <= txtline)      /*  txtline itself has already been read  */
      {
      if (stream != filearg) 
         {
         fputs("Cannot back up standard input\xa", stderr);
         break;
         }
      else     /*  The stream must be rewound  */
         {
         txtline = 0;
         fseek(stream, 0L, 0);
         }
      }
   code = txttw();
   }
ModifyIDCMP(mw, NULL);
FreeMem(instr, (LONG)(MAXSTRLN+1));
FreeMem(pvstr, (LONG)(MAXSTRLN+1));
CloseWindow(mw);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
if(filearg) fclose(filearg);
exit(0);
}
/*********************************************************************/
struct Window *makewindow(x,y,w,h,name,flags,screen,type)
SHORT x, y, w, h;
UBYTE *name;
ULONG flags;
struct Screen *screen;
USHORT type;
{
struct Window *mw;
struct NewWindow new, *nw;
nw = &new;
new.LeftEdge = x; new.TopEdge = y;
new.Width = w; new.Height = h;
new.DetailPen = (UBYTE)1; new.BlockPen = (UBYTE)0;
new.IDCMPFlags = NULL;
new.Flags = flags;
new.FirstGadget = NULL;
new.CheckMark = NULL;
new.Title = (UBYTE *)name;
new.Screen = screen;
new.BitMap = NULL;
new.MinWidth = 0; new.MinHeight = 0;
new.MaxWidth = 0; new.MaxHeight = 0;
new.Type = type;
mw = OpenWindow(nw);
return mw;
}
