From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 19-AUG-1989 03:52
To:	MRGATE::"ARISIA::EVERHART"
Subj:	VMS MORE 6 OF 7

Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Fri, 18 AUG 89 22:12:19 PDT
Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Fri, 18 Aug 89 22:08:45 PDT
Received: by ucbvax.Berkeley.EDU (5.61/1.37)
	id AA29357; Fri, 18 Aug 89 21:53:08 -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: 19 Aug 89 03:59:31 GMT
From: gem.mps.ohio-state.edu!ginosko!aplcen!jhunix!jhuvms.bitnet@tut.cis.ohio-state.edu  (Xuning Shan)
Organization: Dept. of Chemical Engineering, The Johns Hopkins University
Subject: VMS MORE 6 OF 7
Message-Id: <2325@jhunix.HCF.JHU.EDU>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

-+-+-+-+-+-+-+-+ START OF PART 6 -+-+-+-+-+-+-+-+
X                        case CHR:
X                                c = *(ap + 1);
X                                while (*lp && c == *lp)
X                                        lp++;
X                                n = CHRSKIP;
X                                break;
X                        case CCL:
X                        case NCL:
X                                while (*lp && (e = pmatch(lp, ap)))
X                                        lp = e;
X                                n = CCLSKIP;
X                                break;
X                        default:
X                                re_fail("closure: bad dfa.", *ap);
X                                return (0);
X                        `125
X                        ap += n;
X    `032
X                        while (lp >= are) `123
X                                if (e = pmatch(lp, ap))
X                                        return (e);
X                                --lp;
X                        `125
X                        return (0);
X                default:
X                        re_fail("re_exec: bad dfa.", op);
X                        return (0);
X                `125
X        return (lp);
X`125
X/* re_modw: add new characters into the word table to change the re_exec's
X * understanding of what a word should look like. Note that we only accept
X * additions into the word definition.
X *
X * If the string parameter is 0 or null string, the table is reset back to t
Vhe
X * default, which contains A-Z a-z 0-9 _. `091We use the compact bitset
X * representation for the default table`093 */
X    `032
Xnoshare static char deftab`09116`093 = `123
X        0, 0, 0, 0, 0, 0, 377, 003, 376, 377, 377, 207,
X        376, 377, 377, 007
X`125;
X    `032
Xvoid re_modw(s)
X        register char  *s;
X`123
X        register int    i;
X        if (!s `124`124 !*s) `123
X                for (i = 0; i < MAXCHR; i++)
X                        if (!isinset(deftab, i))
X                                iswordc(i) = 0;
X        `125 else
X                while (*s)
X                        iswordc(*s++) = 1;
X`125
X    `032
X/* re_subs: substitute the matched portions of the src in dst.
X *
X * &    substitute the entire matched pattern.
X *
X * \digit    substitute a subpattern, with the given tag number. Tags are
X * numbered from 1 to 9. If the particular tagged subpattern does not exist,
X * null is substituted. */
Xint re_subs(src, dst)
X        register char  *src;
X        register char  *dst;
X`123
X        register char   c;
X        register int    pin;
X        register char  *bp;
X        register char  *ep;
X        if (!*src `124`124 !bopat`0910`093)
X                return (0);
X        while (c = *src++) `123
X                switch (c) `123
X                case '&':
X                        pin = 0;
X                        break;
X                case '\\':
X                        c = *src++;
X                        if (c >= '0' && c <= '9') `123
X                                pin = c - '0';
X                                break;
X                        `125
X                default:
X                        *dst++ = c;
X                        continue;
X                `125
X    `032
X                if ((bp = bopat`091pin`093) && (ep = eopat`091pin`093)) `123
X                        while (*bp && bp < ep)
X                                *dst++ = *bp++;
X                        if (bp < ep)
X                                return (0);
X                `125
X        `125
X        *dst = (char) 0;
X        return (1);
X`125
X/* re_fail: internal error handler for re_exec.
X * should probably do something like a longjump to recover gracefully.*/
Xvoid re_fail(s, c)
X        char           *s;
X        char            c;
X`123
X        printf("\n%s `091opcode %o`093\n", s, c);
X        exit(0);
X`125
$ CALL UNPACK REG.C;1 107616656
$ create/nolog 'f'
XSYS$LIBRARY:VAXCRTLG/SHARE
$ CALL UNPACK RTL.OPT;1 152306956
$ create/nolog 'f'
X/*VMS MORE V1.5 */
X#include descrip
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
$ CALL UNPACK SPAWN.C;1 1748776198
$ create/nolog 'f'
X/*VMS MORE V1.5*/
X#include stdio
X#include ctype
X#include string
X#define EOS '\0'
Xextern  int Screen_Width,line_ct;
Xextern  int  case_sensitive;
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 = getkey()) != '\r')`123
X`009`009if(isprint(pat`091i`093))`123
X`009`009`009 putchar(pat`091i++`093);
X`009`009`009 continue;
X`009`009`125
X`009`009else if( pat`091i`093=='\177') `123
X`009`009`009if(i!=0) `123
X`009`009`009`009i--;
X`009`009`009`009printf("\b \b");
X`009`009`009`125
X`009`009`125
X         `125
X        pat`091i`093 ='\0';
X`125  /* get_pattern */
X`032
X/*find a pattern in string */
Xvoid lower_str();
Xvoid lower_line();
Xint find(pattern, string)
Xchar *pattern, *string;
X`123
X        int  n,i=0;
X`009char *ptr,strtmp`091240`093;
X`009strcpy(strtmp,string);
X`009if(!case_sensitive) `123
X`009`009lower_str(pattern);
X`009`009lower_line(strtmp);
X`009`125
X#ifdef REXPRESSIONS
X        if( re_exec(strtmp))
X                return TRUE;
X        return FALSE;
X#else
X`009ptr=strtmp;
X`009n=strlen(pattern);
X`009while( (ptr=strchr(ptr,*pattern))!=NULL )`123
X                if (strncmp(ptr, pattern, n) == 0)`123
X`009`009`009  return TRUE;
X`009`009`125
X`009`009ptr++;
X`009`125
X        return FALSE;
X#endif REXPRESSIONS
X`125  /* find */
X`032
X`032
X/* conv_nonprt:  convert nonprintable character to `094 */
Xvoid conv_nonprt(str)
Xchar *str;
X`123
X`009while(*str)`123
X`009`009if((!isprint(*str)) && (!isspace(*str)))`123
X`009`009`009*str='`094';
X`009`009`125
X`009`009str++;
X`009`125
X`125
X
X`032
X/* lower_str() --- Converts a string to lower case and terminates the
X *                      string at the first space. */
X`032
Xvoid lower_str (st)
Xchar *st;
X`123
X        while(*st && *st != ' ')
X        `123
X                *st = _tolower(*st);
X                st++;
X        `125
X        if (*st == ' ')
X                *st = EOS;
X`125    /* end of lower_str () */
X
Xvoid lower_line (line)
Xchar *line;
X`123
X        while(*line)
X        `123
X                *line = tolower(*line);
X                line++;
X        `125
X`125  `032
X`032
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)
Xchar *str;
X`123
X
X`009int ct=0,ctt=0;`032
X        while (*str)
X        `123
X                if (*str == '\t')`123
X`009`009`009ct=ct+8; /* haven't found better way to do this*/
X`009`009`009ctt=ctt+8;
X`009`009`125
X                else`123
X`009`009`009if(*str!='\n')`123
X`009`009`009`009 ct++;
X`009`009`009`009 ctt++;
X`009`009`009`125
X`009`009`125
X
X`009`009if(ct==Screen_Width)`123
X`009`009`009line_ct--;  /* this is global */
X`009`009`009ct=0;
X`009`009`125
X                str++;
X      `125
X`032
X        return ((ctt-1)/Screen_Width+1);
X`125/* this function is bad. */
$ CALL UNPACK STRING.C;1 1008745049
$ create/nolog 'f'
X/*VMS MORE V1.5*/
X/*  -------------------------------------------------------------------
X    Contains terminal-handling routines using the SMG routines.
X    Author: Robert J. Drabek, Curtis Smith
X    Date: Winter 1987`032
X    Latest revision: Aug. 1989   Xuning Shan    ins_bxs@jhuvms.bitnet
X    -------------------------------------------------------------------  */
X#include stdio`032
X#include descrip
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 IO$_SETMODE   0x23    /* set mode */
X#define TT$_UNKNOWN 0x00    /* Unknown terminal   */
X
Xextern   int Screen_Height,Screen_Width;`032
X/* Local routines. */
Xstatic void  vmsgtty();
Xstatic char *tgetstr();
X`032
Xstatic int   wide_width();
Xvoid         cursor();
Xstatic char  *CE   = NULL;
Xstatic char  *SO   = NULL;
Xstatic char  *SE   = NULL;
Xstatic char  *CLS  = NULL;
Xstatic char  *HC   = NULL;
Xstatic char  *BLD  = NULL;
Xstatic char  *BLDE = NULL;
X
Xstatic char  *WSCREEN = NULL;
Xstatic char  *NSCREEN = NULL;
Xstatic char  *SCROLLR = NULL;
Xstatic unsigned int Kb;
X`032
Xstatic int termaddr;
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  `032
X#define SMG$K_HOME                476
X#define SMG$K_BEGIN_BOLD          443
X#define SMG$K_END_BOLD            466
X#define SMG$K_SCROLL_REVERSE      562
X#define SMG$K_WIDTH_NARROW        581
X#define SMG$K_WIDTH_WIDE          582`032
X#define SMG$K_TRM_UP 274
X#define SMG$K_TRM_DOWN 275
X#define SMG$K_TRM_PREV_SCREEN 315       /* E5
V                               */
X#define SMG$K_TRM_NEXT_SCREEN 316       /* E6
V                               */
X#define SMG$K_SET_CURSOR_ABS      570
X
X/***
X *  tgetstr  -  Get an SMG string capability by name
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 1, 1 `125;
X        int max_buffer_length, ret_length;
X         /*  Precompute buffer length */
X`009max_buffer_length=sizeof(seq_storage);`032
X        /* Get terminal commands sequence from master table */
X        if ((smg$get_term_data(     /* Get terminal data   */
X        &termaddr,         /* 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        &termaddr,         /* 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        /* Check for empty result */
X        if (ret_length == 0)
X                return NULL;
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/** 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/***
X  *  vmsgtty - Get terminal type from system control block
X  *  Nothing returned
X  ***/
Xstatic void vmsgtty()
X`123
X        short fd;
X        int status;
X        iosb iostatus;
X        $DESCRIPTOR(devnam, "SYS$COMMAND");
X        /* Assign input to a channel */
X        status = sys$assign(&devnam, &fd, 0, 0);
X        if ((status & 1) == 0)
X                exit(status);
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        /* De-assign the input device */
X        if ((sys$dassgn(fd) & 1) == 0)
X                exit(status);
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/* Terminal_Open
X  *   Get terminal type and open terminal.
X */
Xchar Terminal_Open()
X`123
X        smg$create_virtual_keyboard(&Kb);
X        /* Get terminal type */
X        vmsgtty();
X        if (tc.t_type == TT$_UNKNOWN)
X                return FALSE;
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, &termaddr) & 1) == 0)
X                return FALSE;
X        /* Set sizes */
X        Screen_Height = ((unsigned int) tc.t_mandl >> 24);
X        Screen_Width = tc.t_width;
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);
+-+-+-+-+-+-+-+-  END  OF PART 6 +-+-+-+-+-+-+-+-

