home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
usenet
/
altsrcs
/
3
/
3574
< prev
next >
Wrap
Internet Message Format
|
1991-07-02
|
11KB
From: slamont@network.ucsd.edu (Steve Lamont)
Newsgroups: alt.sources
Subject: Replacement MORE for MeSs-DOS
Message-ID: <5542@network.ucsd.edu>
Date: 2 Jul 91 16:27:51 GMT
Here is a replacement for the MeSs-DOS parody of MORE that understands input
from either standard input or as a list of files from the command line.
It is intended as a better MS-DOS MORE and not as an accurate mimic of the
Un*x more(1) command, so there are features missing, such as regular expression
searching, and so forth.
I hereby bequeath this monstrosity to the public domain. Share and enjoy.
spl (the p stands for
parody of a parody)
------------------------ gnaw on dotted line and feed to sh ------------------
#!/bin/sh
# shar: Shell Archiver (v1.22)
#
# Run the following text with /bin/sh to create:
# makefile
# more.c
#
sed 's/^X//' << 'SHAR_EOF' > makefile &&
X#
X# In case it isn't painfully obvious, this is a makefile for use with
X# the bizarre parody of MAKE that comes with Microsoft C. If you use
X# something other than MSC, then you'll probably have to come up with
X# your own.
X#
X
XCC = cl
XOPT = -Ox
X#DEBUG = -Zi
XCFLAGS = $(OPT) $(DEBUG)
X
X#
X# We include \lib\setargv.obj here to replace the default setargv,
X# which has insufficient brains to expand the rather simple globbing
X# that MeSs-DOS inflicts -- er -- I mean, provides. The /noe option
X# suppresses LINK's complaints about duplicate object modules.
X#
X
XLFLAGS = \lib\setargv.obj -link /noe
X
Xmore.obj: more.c makefile
X $(CC) $(CFLAGS) more.c -c
X
Xmore.exe: more.obj
X $(CC) $(CFLAGS) more.obj -o more.exe $(LFLAGS)
SHAR_EOF
chmod 0644 makefile || echo "restore of makefile fails"
sed 's/^X//' << 'SHAR_EOF' > more.c &&
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#include <varargs.h>
X#include <ctype.h>
X
X/*
X * MSC specific includes.
X */
X
X#include <graph.h>
X#include <dos.h>
X
X/*
X * More: a replacement pager for MeSs-DOS.
X *
X * Copyright relinquished and placed in the public domain by Steve Lamont,
X * July 2, 1991, at the Naval Postgraduate School, Monterey, CA 93943.
X * Use at your own risk.
X *
X * This program will read from either standard input or from a file or
X * files specified on the command line. While it sort of acts like Un*x
X * more(1) it is not intended to be a complete or accurate emulation.
X *
X * I guess, in reality, upon reviewing the code, it is kind of a hack,
X * written while in bed with a Zenith laptop on my stomach. Really!
X *
X * This more supports a limited collection of paging options at the prompt:
X *
X * Pressing the space bar, the enter key, and the 'N' or 'n' keys all page
X * forward one screen.
X *
X * Pressing the 'p' or 'P' key will cause more to page backward one page.
X *
X * Pressing 'x' or 'X' will cause the pager to quit paging the current file
X * and if there is another specified on the command line, the next file will
X * then be displayed.
X *
X * 'Q', 'q', or Ctrl-C all terminate paging immediately.
X *
X * This code is designed to compile under Microsoft C 5.1 (or, probably,
X * later) and has a couple of MSC dependencies in it.
X *
X * MSC library functions used:
X *
X * _getvideoconfig() - fetches the monitor adaptor width and height,
X * among other things.
X *
X * int86() - calls a BIOS function via the interrupt vector.
X * In this case, it reads directly from the keyboard.
X *
X * If ported to another compiler, these dependencies will obviously have
X * to be corrected.
X */
X
X#if !defined( TRUE )
X#define TRUE ( 1 == 1 )
X#define FALSE ( 1 == 0 )
X#endif
X
Xchar *me = "?";
Xint fatal = FALSE;
X
X/*
X * Page dimensions, etc.
X */
X
X#define PAGES ( 5 )
X
Xint pagelines;
Xint buffsize;
X
Xint maxlines;
X
X#define BAIL ( TRUE )
X
X/*
X * Page buffers.
X */
X
Xchar **ring;
Xint pmax;
X
Xchar *fgetbuffer();
X
Xmain( argc, argv )
X
X int argc;
X char **argv;
X
X{
X
X int i;
X FILE *f;
X extern char *me;
X
X me = argv[0];
X
X setup();
X
X /*
X * Work our way through files specified on the command line.
X */
X
X for ( i = 1; i < argc; i++ )
X if ( f = fopen( argv[i], "r" ) )
X process( f, argv[i] );
X else
X abend( "%s %s", sys_errlist[errno], argv[i] );
X
X /*
X * If there is input from stdin from a file, page it. If there is
X * neither a file specified via stdin or any command line arguments,
X * print a usage message.
X */
X
X if ( !isatty( fileno( stdin ) ) )
X process( stdin, "stdin" );
X else if ( argc == 1 )
X usage( "[files]" );
X
X exit( 0 );
X
X}
X
X/*
X * Fish up the video configuration.
X *
X * Herein lies an MSC dependency.
X */
X
Xsetup()
X
X{
X
X struct videoconfig config;
X
X _getvideoconfig( &config );
X
X /*
X * Allow for the prompt.
X */
X
X pagelines = config.numtextrows - 1;
X buffsize = config.numtextcols;
X maxlines = pagelines * PAGES;
X
X /*
X * Allocate the page buffers.
X */
X
X ring = ( char **) malloc( sizeof( char *) * maxlines );
X if ( !ring )
X abend( "Whoops! Out of memory!" );
X
X return;
X
X}
X
XclearRing()
X
X{
X
X int n;
X
X for ( n = 0; n < maxlines; n++ )
X ring[n] = ( char *) NULL;
X
X return;
X
X}
X
Xprocess( f, fn )
X
X FILE *f;
X char *fn;
X
X{
X
X int current = 0;
X int bail = FALSE;
X
X clearRing();
X
X /*
X * If we're piped out to something else, then just act like a cat(1)
X * function.
X */
X
X if ( !isatty( fileno( stdout ) ) )
X cat( f );
X else {
X
X int n;
X char *buffer = ( char *) malloc( sizeof( char ) * buffsize );
X int current;
X int newline = TRUE;
X int wasWrap = FALSE;
X
X pmax = 0;
X n = 0;
X while ( fgetbuffer( buffer, buffsize, f ) ) {
X
X int ll = strlen( buffer );
X
X /*
X * If the line is long, then wrap it around and adjust our
X * buffer appropriately.
X */
X
X wasWrap = !newline;
X if ( newline = ( buffer[ll - 1] == '\n' ) )
X buffer[--ll] = '\0';
X
X if ( ll || ( !wasWrap && !ll ) ) {
X
X current = n % maxlines;
X
X if ( ring[current] )
X free( ring[current] );
X ring[current] = strdup( buffer );
X
X if ( !( ++n % pagelines ) && ( bail = view( current, fn ) ) )
X break;
X
X }
X
X }
X if ( ( n % pagelines ) && !bail )
X view( current, fn );
X
X dropRing();
X
X }
X fclose( f );
X
X return;
X
X}
X
XdropRing()
X
X{
X
X int i;
X
X for ( i = 0; i < maxlines; i++ )
X if ( ring[i] ) {
X
X free( ring[i] );
X ring[i] = ( char *) NULL;
X
X }
X
X return;
X
X}
X
Xint view( lastLine, fn )
X
X int lastLine;
X char *fn;
X
X{
X
X int bottomLine = lastLine;
X int amount;
X int topLine;
X int l;
X union REGS regs;
X int pcount;
X int doSomething = TRUE;
X
X if ( pmax < PAGES )
X pmax++;
X pcount = pmax;
X
X while ( TRUE ) {
X
X if ( doSomething ) {
X
X amount = bottomLine % pagelines;
X if ( !amount )
X amount = pagelines;
X topLine = bottomLine - amount;
X if ( topLine < 0 )
X topLine = 0;
X
X for ( l = topLine; l <= bottomLine; l++ )
X printf( "%s\n", ring[l] );
X
X printf( "[more] %s:", fn );
X fflush( stdout );
X
X } else
X doSomething = TRUE;
X
X regs.h.ah = 0x00;
X int86( 0x16, ®s, ®s ); /* Read directly from keyboard */
X switch ( regs.h.al ) {
X
X case 'q':
X case 'Q':
X case 0x03: {
X
X printf( "\r\t\t\t\t\t\t\r" );
X exit( 0 );
X
X }
X case 'x':
X case 'X': {
X
X printf( "\r\t\t\t\t\t\t\r" );
X return( BAIL );
X
X }
X case 'p':
X case 'P': {
X
X if ( --pcount ) {
X
X bottomLine = topLine - 1;
X if ( bottomLine < 0 )
X bottomLine = maxlines - 1;
X printf( "\r\t\t\t\t\t\t\r" );
X
X } else {
X
X printf( "\rCan't scroll back further\t\t\t\r" );
X fflush( stdout );
X pcount = 1;
X doSomething = FALSE;
X
X }
X break;
X
X }
X case '\r':
X case ' ':
X case 'n':
X case 'N': {
X
X printf( "\r\t\t\t\t\t\t\r" );
X if ( ++pcount < pmax ) {
X
X bottomLine += pagelines;
X bottomLine %= maxlines;
X
X } else if ( pcount == pmax )
X bottomLine = lastLine;
X else
X return( !BAIL );
X
X break;
X
X }
X default: {
X
X doSomething = FALSE;
X break;
X
X }
X
X }
X
X }
X
X}
X
Xcat( f )
X
X FILE *f;
X
X{
X
X int ch;
X
X while ( ( ch = fgetc( f ) ) != EOF )
X putchar( ch );
X
X return;
X
X}
X
Xchar *fgetbuffer( buffer, buflen, f )
X
X char *buffer;
X int buflen;
X FILE *f;
X
X{
X
X static int tab = 0;
X char *b = buffer;
X static int eoffed = FALSE;
X
X if ( eoffed )
X return( ( char *) NULL );
X
X while ( b < buffer + buflen - 1 ) {
X
X if ( tab ) {
X
X *b++ = ' ';
X tab--;
X
X } else {
X
X int ch;
X
X switch ( ch = fgetc( f ) ) {
X
X case '\n': {
X
X *b++ = ch;
X *b = '\0';
X return( buffer );
X
X }
X case '\t': {
X
X *b = '\0';
X tab = 8 - ( strlen( buffer ) % 8 );
X break;
X
X }
X case EOF: {
X
X eoffed = TRUE;
X *b = '\0';
X return( buffer );
X
X }
X default: {
X
X *b++ = ch;
X break;
X
X }
X
X }
X
X }
X
X }
X
X *b = '\0';
X
X return( buffer );
X
X}
X
Xabend( va_alist )
X
X va_dcl
X
X{
X
X va_list ap;
X char *fmt;
X#if defined( MSDOS )
X char *parseMe();
X
X me = parseMe( me );
X#endif
X fprintf( stderr, "%s: ", me );
X va_start( ap );
X fmt = va_arg( ap, char *);
X vfprintf( stderr, fmt, ap );
X fprintf( stderr, "\n" );
X va_end( ap );
X
X if ( fatal ) {
X
X#if !defined( MSDOS )
X fprintf( stderr,
X "We're gonna dump core here, just in case we need it.\n" );
X#endif
X ( void ) abort();
X
X } else
X exit( 1 );
X
X }
X
Xusage( va_alist )
X
X va_dcl
X
X{
X
X va_list ap;
X char *fmt;
X extern char *me;
X#if defined( MSDOS )
X char *parseMe();
X
X me = parseMe( me );
X#endif
X fprintf( stderr, "Usage: %s ", me );
X va_start( ap );
X fmt = va_arg( ap, char *);
X vfprintf( stderr, fmt, ap );
X fprintf( stderr, "\n" );
X va_end( ap );
X
X exit( 1 );
X
X}
X
X#if defined( MSDOS )
Xchar *parseMe( me )
X
X char *me;
X
X{
X
X char drive[_MAX_DRIVE];
X char path[_MAX_PATH];
X static char fname[_MAX_FNAME];
X char ext[_MAX_EXT];
X char *f = fname;
X
X _splitpath( me, drive, path, fname, ext );
X while ( *f ) {
X
X if ( isupper( *f ) )
X *f = tolower( *f );
X ++f;
X
X }
X
X return( &fname[0] );
X
X}
X#endif
SHAR_EOF
chmod 0644 more.c || echo "restore of more.c fails"
exit 0
--
Steve Lamont, SciViGuy -- (408) 646-2752 -- a guest at network.ucsd.edu --
NPS Confuser Center / Code 51 / Naval Postgraduate School / Monterey, CA 93943
I have discovered a truly marvelous demonstration which this .signature is too
small to contain...