From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX"  4-AUG-1989 00:26
To:	MRGATE::"ARISIA::EVERHART"
Subj:	VMS MORE V1.00   2 of 5

Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Thu,  3 AUG 89 20:49:07 PDT
Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Thu, 3 Aug 89 20:32:40 PDT
Received: by ucbvax.Berkeley.EDU (5.61/1.37)
	id AA15337; Thu, 3 Aug 89 20:26:35 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 3 Aug 89 19:42:16 GMT
From: haven!aplcen!jhunix!ins_bxs@purdue.edu  (Xuning Shan)
Organization: The Johns Hopkins University - HCF
Subject: VMS MORE V1.00   2 of 5
Message-Id: <2192@jhunix.HCF.JHU.EDU>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

VMS MORE V1.00 2 of 5:



-+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+
X                                `123
X                                        line_count = 1;
X                                        win`091++wc`093 = ftell(fp);
X                                `125
X                        `125
X                        if (pat_found)
X                        `123
X                                putchar('\r');
X                                ClrEOL();
X                                standout ();
X                                fputs(a_line, stdout);
X                                standend ();
X                                win`091++wc`093 = ftell(fp);
X                        `125
X                        line_ct +=(Screen_Height-2);
X                        if (!prwindow(fp, Screen_Height - 2, Screen_Width))
X                                return(101);
X                        break;
X                case 't':
X                case 'g':
X                        line_ct=0;
X                        if (wc > 0)
X                        `123
X                           wc = 0;
X                           fseek(fp, win`091wc`093, 0);
X                           line_ct +=(Screen_Height-1);
X                           if (!prwindow(fp, Screen_Height - 1,Screen_Width)
V)
X                                        return(101);
X                        `125
X                        break;
X                case 'b':
X                        if (wc > 0)
X                        `123
X                           wc -= factor;
X                           wc = wc < 0 ? 0 : wc;
X                           fseek(fp, win`091wc`093, 0);
X                           line_ct -=(Screen_Height-1);
X                           if (!prwindow(fp, Screen_Height - 1,Screen_Width)
V)
X                                        return(101);
X                        `125
X                        factor=1;
X                        break;
X                case 'h':
X                case '?':
X                        more_help ();
X                        fseek(fp, win`091wc`093, 0);
X                        if (!prwindow(fp, Screen_Height - 1, Screen_Width))
X                                return(101);
X                        break;
X                case '!':
X                        spawn(); clrs();
X                        fseek(fp, win`091wc`093, 0);
X                        if (!prwindow(fp, Screen_Height - 1, Screen_Width))
X                                return(101);
X                        break;
X                case '#':
X                        return(110); /* ASCII n : next file */
X                case 'q':
X                        putchar('\n');
X                        exit();
X                case '=':
X                        printf("  %d ",line_ct);
X                        break;
X                default:
X                        ding();
X                        putchar('\r');
X                        break;
X                `125
X        `125
X`125  /* more */
X`032
Xbool prwindow(fp, height, width)
XFILE *fp;
Xint height;
Xint width;
X`123
X        int i;
X        char *fgets(), str`091BUFSIZ`093;
X        bool got_line = FALSE;
X`032
X        putchar('\r'); ClrEOL();
X        if(flag && (!search)) clrs();
X        if(search==TRUE) search=FALSE;
X        for (i = 0; i < height; i++)
X        `123
X                if (fgets(str, BUFSIZ, fp) == NULL)
X                        break;
X                got_line = TRUE;
X                fix_string(str);
X                printf("%s", str);
X                i += str_lines (str, width);
X        `125
X        return got_line && !(feof(fp));
X`125  /* prwindow */
X`032
Xbool prline(fp,n)
XFILE *fp;
Xint n;
X`123
X        char *fgets(), str`091BUFSIZ`093;
X`032
X        putchar('\r'); ClrEOL();
X        while(n--)
X        `123
X                if (fgets(str, BUFSIZ, fp) == NULL)
X                        return FALSE;
X                fix_string (str);
X                printf("%s", str);
X        `125
X        return TRUE;
X`125  /* prline */
X`032
X/* get_pattern
X     Read pattern to be search for from the user's keyboard.
X*/
Xget_pattern(pat)
Xchar *pat;
X`123
X        int i = 0;
X`032
X        while ((pat`091i++`093 = getchar()) != '\n')
X                ;
X        pat`091i - 1`093 = EOS;
X`125  /* get_pattern */
X`032
X/* find
X     Find starting index of the first string within the second.
X     Return FALSE if not there.  Horribly slow!
X*/
Xint find(t, s)
Xchar *t, *s;
X`123
X        int i, n;
X#ifdef REXPRESSIONS
X        if( re_exec(s))
X                return TRUE;
X        return FALSE;
X#else
X        n = strlen(t);
X        for (i = 0; s`091i`093 != EOS; i++)
X                if (strncmp(s+i, t, n) == 0)
X                        return TRUE;
X        return FALSE;
X#endif REXPRESSIONS
X`125  /* find */
X`032
Xspawn()
X`123
X        $DESCRIPTOR(prompt,"more% ");
X        putchar('\r');ClrEOL();
X        standout();
X        printf("\nSpawning subprocess ... logout to  return to MORE.\n");
X        standend();
X        lib$spawn (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &prompt);
X`125  /* spawn */
X`032
X`032
X/*  -------------------------------------------------------------------
X    Contains terminal-handling routines using the SMG routines.
X    Author: Robert J. Drabek, Curtis Smith
X    Date: Winter 1987
X    -------------------------------------------------------------------  */
X`032
X#define NULL_STR (char *)0
X#define BEL_STR  "\07"
X`032
X/*  These would normally come from iodef.h and ttdef.h  */
X#define IO$_SENSEMODE 0x27    /* Sense mode of terminal */
X#define TT$_UNKNOWN 0x00    /* Unknown terminal   */
X`032
X/* Local routines. */
Xstatic void  vmsgtty();
Xstatic char *tgetstr();
X`032
X/* -------------------------------------------------------------------- */
Xstatic char  *CE   = NULL_STR;
Xstatic char  *SO   = NULL_STR;
Xstatic char  *SE   = NULL_STR;
Xstatic char  *CLS  = NULL_STR;
Xstatic char  *HC   = NULL_STR;
Xstatic char  *BLD  = NULL_STR;
Xstatic char  *BLDE = NULL_STR;
X`032
Xstatic unsigned int Kb;
X`032
Xstatic int termtype;
X`032
X#define SMG$K_BEGIN_REVERSE     0x1bf
X#define SMG$K_END_REVERSE       0x1d6
X#define SMG$K_ERASE_TO_END_LINE 0x1d9
X#define SMG$K_ERASE_WHOLE_DISPLAY 474   /*Apr 1989, added by Shan */
X#define SMG$K_HOME                476
X#define SMG$K_BEGIN_BOLD          443
X#define SMG$K_END_BOLD            466
X`032
X`032
X/***
X *  tgetstr  -  Get an SMG string capability by name
X *
X *  Returns:  Escape sequence
X *    NULL  No escape sequence available
X ***/
Xstatic char *tgetstr(request_code)
Xint request_code;
X`123
X        register char * result;
X        static char seq_storage`0911024`093;
X        static char * buffer = seq_storage;
X        static int arg_list`0912`093 = `123`032
X                1, 1    `125;
X        int max_buffer_length, ret_length;
X`032
X        /*  Precompute buffer length */
X`032
X        max_buffer_length = (seq_storage + sizeof(seq_storage)) - buffer;
X`032
X        /* Get terminal commands sequence from master table */
X`032
X        if ((smg$get_term_data(     /* Get terminal data   */
X        &termtype,         /* Terminal table address  */
X        &request_code,     /* Request code    */
X        &max_buffer_length,/* Maximum buffer length */
X        &ret_length,       /* Return length   */
X        buffer,            /* Capability data buffer  */
X        arg_list)          /* Argument list array */
X            & 1) == 0 &&
X            /* If that didn't work, try again with no arguments */
X`032
X        (smg$get_term_data(     /* Get terminal data    */
X        &termtype,         /* Terminal table address */
X        &request_code,     /* Request code     */
X        &max_buffer_length,/* Maximum buffer length */
X        &ret_length,       /* Return length    */
X        buffer)            /* Capability data buffer */
X            & 1) == 0)
X                /* Return NULL pointer if capability is not available */
X                return NULL;
X`032
X        /* Check for empty result */
X        if (ret_length == 0)
X                return NULL;
X`032
X        /* Save current position so we can return it to caller */
X        result = buffer;
X`032
X        /* NIL terminate the sequence for return */
X        buffer`091ret_length`093 = 0;
X`032
X        /* Advance buffer */
X        buffer += ret_length + 1;
X`032
X        /* Return capability to user */
X        return result;
X`125  /* tgetstr */
X`032
X`032
X/** I/O information block definitions **/
Xtypedef struct `123    /* I/O status block     */
X        short i_cond;     /* Condition value      */
X        short i_xfer;     /* Transfer count     */
X        long  i_info;     /* Device information     */
X`125 iosb;
X`032
Xtypedef struct `123    /* Terminal characteristics   */
X        char  t_class;    /* Terminal class     */
X        char  t_type;     /* Terminal type      */
X        short t_width;    /* Terminal width in characters   */
X        long  t_mandl;    /* Terminal's mode and length   */
X        long  t_extend;   /* Extended terminal characteristics  */
X`125  termchar;
X`032
Xstatic termchar tc; /* Terminal characteristics   */
X`032
X`032
X/***
X  *  vmsgtty - Get terminal type from system control block
X  *
X  *  Nothing returned
X  ***/
Xstatic void vmsgtty()
X`123
X        short fd;
X        int status;
X        iosb iostatus;
X`032
X        $DESCRIPTOR(devnam, "SYS$COMMAND");
X`032
X        /* Assign input to a channel */
X        status = sys$assign(&devnam, &fd, 0, 0);
X        if ((status & 1) == 0)
X                exit(status);
X`032
X        /* Get terminal characteristics */
X        status = sys$qiow(           /* Queue and wait   */
X        0,           /* Wait on event flag zero  */
X        fd,           /* Channel to input terminal  */
X        IO$_SENSEMODE,   /* Get current characteristic */
X        &iostatus,       /* Status after operation */
X        0, 0,            /* No AST service   */
X        &tc,             /* Terminal characteristics buf */
X        sizeof(tc),      /* Size of the buffer   */
X        0, 0, 0, 0);     /* P3-P6 unused     */
X`032
X        /* De-assign the input device */
X        if ((sys$dassgn(fd) & 1) == 0)
X                exit(status);
X`032
X        /* Jump out if bad status */
X        if ((status & 1) == 0)
X                exit(status);
X        if ((iostatus.i_cond & 1) == 0)
X                exit(iostatus.i_cond);
X`125  /* vmsgtty */
X`032
X`032
X/* Terminal_Open
X  *   Get terminal type and open terminal.
X */
Xbool Terminal_Open()
X`123
X`032
X        smg$create_virtual_keyboard(&Kb);
X`032
X        /* Get terminal type */
X        vmsgtty();
X        if (tc.t_type == TT$_UNKNOWN)
X                return FALSE;
X`032
X        /* Access the system terminal definition table for the  */
X        /* information of the terminal type returned by IO$_SENSEMODE */
X        if ((smg$init_term_table_by_type(&tc.t_type, &termtype) & 1) == 0)
X                return FALSE;
X`032
X        /* Set sizes */
X        Screen_Height = ((unsigned int) tc.t_mandl >> 24);
X        Screen_Width = tc.t_width;
X`032
X        /* Get some capabilities */
X        SO   = tgetstr(SMG$K_BEGIN_REVERSE);
X        SE   = tgetstr(SMG$K_END_REVERSE);
X        CE   = tgetstr(SMG$K_ERASE_TO_END_LINE);
X        CLS  = tgetstr(SMG$K_ERASE_WHOLE_DISPLAY);
X        HC   = tgetstr(SMG$K_HOME);
X        BLD  = tgetstr(SMG$K_BEGIN_BOLD);
X        BLDE = tgetstr(SMG$K_END_BOLD);
X`032
X        setbuf(stdout, 0);
X`032
X        return TRUE;
X`125  /* Terminal_Open */
X`032
X`032
X/* ClrEOL
X      Clears from (and including) the current cursor position to the
X      end of the line.
X */
Xvoid ClrEOL()
X`123
X        if (CE != NULL)
X                printf("%s",CE);
X        else
X        `123
X                int i;
X                for (i = 0; i < Screen_Width - 1; i++)
X                        putchar(' ');
X                putchar('\r');
X        `125
X`125  /* ClrEOL */
X`032
X`032
Xvoid clrs()
X`123
X        if(HC!=NULL) printf("%s%s",HC);
X        if(CLS!=NULL) printf("%s%s",CLS);
X`125    `032
X`032
X/* standout
X */
Xvoid standout()
X`123
X        if (SO != NULL) printf("%s",SO);
X        if (BLD != NULL) printf("%s",BLD);
X`032
X`125  /* standout */
X`032
X`032
X/* standend
X */
Xvoid standend()
X`123
X        if (SE != NULL) printf("%s",SE);
X        if (BLDE != NULL) printf("%s",BLDE);
X`125  /* standend */
X`032
X/* -------------------------------------------------------------------- */
X`032
X/* getkey
X     Read in a keystroke in raw noecho mode.
X */
Xint getkey()
X`123
X        static short int ch;
X`032
X        smg$read_keystroke(&Kb, &ch);
X        return ch;
X`125  /* getkey */
X`032
X`032
X/* -------------------------------------------------------------------- */
X`032
X/* fix_string
X     Fixes a string so that it doen't have any control characters in it,
X other than one at the end (\n).
X  */
Xvoid fix_string(str)
Xchar *str;
X`123
X        int i, len;
X        len=strlen(str)-1;
X        for (i = 0; i < len; i++)
X                if ((! isprint(str`091i`093) && ! isspace(str`091i`093)) `12
V4`124 str`091i`093 == '\f')
X                        str`091i`093 = '`094';
X`125
X`032
X/* -------------------------------------------------------------------- */
X/* str_lines
X     Determines how many lines a string would take up if it were printed.
X It assumes 8 space tabs (BAD).  It returns the number of extra lines that
X will be printed.  It also assumes that integer truncation will occur.
X  */
Xint str_lines (str, width)
Xchar *str;
X`123
X        int spaces;
X        char *walker;
X`032
X        spaces = 0;
X        walker = str;
X        while (*walker)
X        `123
X                if (*walker == '\t')
X                        spaces = ((spaces / 8) + 1) * 8; /* Int truncation *
V/
X                else
X                        spaces++;
X                walker++;
X        `125
X        if (*walker == '\n')
X                spaces--;
X`032
X        if (((spaces + width - 1) / width) - 1 < 0)
X        `123
X                fprintf (stderr, "We have a problem.... spaces = %d\n");
X                return (0);
X        `125
X`032
X        return (((spaces + width - 1) / width) - 1);
X`125
X`032
Xmore_help()
+-+-+-+-+-+-+-+-  END  OF PART 2 +-+-+-+-+-+-+-+-

