andrew@tvcent.uucp (Andrew Cowie) (12/20/89)
This is SEE, a program I was asked to write in order to view oversized files in two dimentions. Several people found it very useful and asked me to post. More information from the 'I' command. -- Andrew F. Cowie at TVC Enterprises, Toronto, Canada. uunet!mnetor!lethe!tvcent!andrew andrew@tvcent.uucp #! /bin/sh # This is a shell archive, meaning: # 1. Remove anything before this line. # 2. Save it. # 3. Execute it with /bin/sh. (not csh) # If this archive is complete, you will see the following at the end: # "End of shell archive." # Contents: see.c Makefile # Wrapped by andrew@tvcent on Tue Dec 19 20:48:20 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f see.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"see.c\" else echo shar: Extracting \"see.c\" \(7900 characters\) sed "s/^X//" >see.c <<'END_OF_see.c' X/* X * see.c -- view wide files with left/right scrolling (don't wrap) X * X * Written by X * Andrew F.Cowie, 88/08/31 <andrew@tvcent.uucp> X * with the help of X * Drew Sullivan, 89/Jan/06 <drew@lethe.uucp> X * X * This program is in the public domain, do what you want with it, X * but please tell me about it. (see I information) X */ X X/* X * M_MSDOS and M_MACintosh imply nothing. However, this code works around here, X * and it has been tested on some of the machines at the University of Waterloo X * running BSD 4.2, so I hope that it will work wherever you are. X */ X X#define VERSION "1.1" X X/* I hope to make it handle larger files in the future */ X X#ifndef MAXLINES X#define MAXLINES 1000 X#endif X X#ifndef MAXCOLS X#define MAXCOLS 400 X#endif X X#include <curses.h> /* for curses... */ X#include <stdio.h> /* for FILE... */ X#if M_MSDOS X#include <stdlib.h> /* for exit */ X#endif X#include <string.h> /* for strdup... */ X#include <ctype.h> /* for isascii */ X#include <stdlib.h> /* for calloc, free */ X#include <signal.h> /* ^C handling */ X X#ifdef M_MAC X#include "getarg.h" X#endif X X/* function declarations */ X X/* if you compiler gives you trouble about the prototypes, change to a 0 */ X#define PROTO 1 X#if PROTO X#define P(x) x X#else X#define P(x) X#endif X Xextern void loads P((void)); Xextern void docmd P((int)); Xextern void print P((void)); Xextern void display P((int, int)); Xextern int main P((int, char **)); Xextern void usage P((void)); Xextern void help P((void)); Xextern void done P((void)); Xextern char * strdup P((char *)); Xextern void signon P((void)); Xextern void information P((void)); X Xextern int optind; /* for getopt */ X X/* global variables */ X Xchar *Progname; Xchar **Lines; Xchar **Files; Xint NumLines; Xint CurLine; /* current top line in file */ Xint CurOff; /* current left column in file */ Xint JumpLines = 24; /* number lines to move by */ Xint JumpCols = 80; /* number cols to move by */ Xint LineCols = 0; /* display line columns */ Xint LineEnds = 0; /* display '~' at end of lines */ X X#define control(c) ((c)-'@') X#define EOS '\0' X Xint main(argc, argv) int argc; char *argv[]; { X int c; X X CurLine = CurOff = 0; X Progname = argv[0]; X#ifdef M_MAC X if (argc <= 1) { X usage(); X argv = av_getargs(); X argc = av_argcnt(argv); X } X#endif X while ((c=getopt(argc, argv, "c")) != EOF) switch (c) { X case 'c': X LineCols = !LineCols; X break; X default: X usage(); X return 1; X } X X Files = argv + optind; X Files[-1] = NULL; X if (*Files == NULL) { X fprintf(stderr, "%s: No files specified\n", Progname); X usage(); X return 2; X } X X signal(SIGHUP, done); X signal(SIGINT, done); X X if (initscr() == NULL) { X fprintf(stderr, "Can't initilise curses\n"); X exit(1); X } X X crmode(); X noecho(); X X loads(); X X for (;;) { X move(LINES-1, 0); X printw("%s%s%s [%d:%d] Command (? for help): ", X Files[-1] ? "-- " : "", X *Files, X Files[1] ? " ++" : "", X CurLine+1, CurOff+1); X clrtoeol(); X refresh(); X docmd(getch()); X } X endwin(); X return (0); X} X Xvoid done() { X endwin(); X exit(0); X} X X Xvoid loads() { X char *p, buf[MAXCOLS]; X int i = 0; X FILE *fp; X X clear(); X X if (Lines == NULL) { X Lines = (char **)calloc(MAXLINES, sizeof(char *)); X } else { X for (i=0 ; i < NumLines; ++i) { X if (Lines[i]) free(Lines[i]); X Lines[i] = NULL; X } X } X if ((fp=fopen(*Files, "r")) == NULL) { X Lines[1] = strdup("Can't open file"); X Lines[2] = strdup(*Files); X NumLines = 3; X print(); X return; X } X X for (i = 0; fgets(buf,MAXCOLS,fp); ++i) { X if ((p=strchr(buf, '\n')) != NULL) { X *p = EOS; X } else { X strcat(buf,""); /* cause strcat to append a \0 */ X } X X/* X * Version 2 (hopefully) will contain an ability to go beyond MAXLINES X */ X if (i == MAXLINES) { X move(LINES-1,0); X printw("%s: Warning: file too long, only partially (first %d lines) loaded...\n",Progname,MAXLINES); X refresh(); X getch(); X break; X } X if ((Lines[i] = strdup(buf)) == NULL) { X break; X } X } X NumLines = i; X fclose(fp); X print(); X} X X Xvoid signon() { X printw("See Version %s by Andrew Cowie with Drew Sullivan.--", VERSION); X} X Xvoid print() { X int h = 0; X int x; X X if (LineCols) { X move(0, 0); X x = CurOff; X for (h=0; h < COLS; ++h) { X switch(++x % 10) { X case 0: addch((x / 10) % 10 + '0'); break; X case 5: addch('+'); break; X default: addch('-'); break; X } X } X h = 1; X } X for (x = CurLine; x < NumLines && h < LINES-1; ) { X display(x, h); X clrtoeol(); X ++x; X ++h; X } X clrtobot(); X} X Xvoid docmd(c) int c; { X switch(c) { X case '?': X help(); X break; X X case 'q': X case 'Q': X endwin(); X printf("\n"); X exit(0); X X case 'N': X if (Files[1]) ++Files; X loads(); X return; X X case 'P': X if (Files[-1]) --Files; X loads(); X return; X X case 'h': X CurOff--; X if (CurOff <= 0) CurOff = 0; X break; X case '<': X CurOff -= 10; X if (CurOff <= 0) CurOff = 0; X break; X X case 'H': X case 'b': X CurOff -= JumpCols; X if (CurOff <= 0) CurOff = 0; X break; X X case 'j': X if (CurLine >= NumLines-1) return; X CurLine++; X break; X X case 'J': X case ' ': X case 'd': X CurLine += JumpLines; X if (CurLine >= NumLines) CurLine = NumLines-1; X break; X X case 'p': X CurLine = CurOff = 0; X break; X X case 'k': X if (CurLine <= 0) return; X CurLine--; X break; X X case 'K': X case 'u': X CurLine -= JumpLines; X if (CurLine < 0) CurLine = 0; X break; X X case 'l': X CurOff++; X break; X case '>': X CurOff += 10; X break; X case 'L': X case 'w': X CurOff += JumpCols; X break; X X case '+': X LineEnds = !LineEnds; X break; X case '-': X LineCols = !LineCols; X break; X X case control('L'): X clear(); X break; X X case 'v': X move(LINES-1, 0); X clrtoeol(); X signon(); X refresh(); X getch(); X break; X X case 'I': X information(); X break; X X default: X#ifndef M_BSD X beep(); X#endif X return; X X } X print(); X} X Xvoid display(x, h) int x,h; { X char *p,*s; X static char buf[MAXCOLS+2]; /* saftey */ X X move(h, 0); X clrtoeol(); X X if (Lines[x] == NULL) { X return; X } X X p = Lines[x]; X s = buf; X X for (;*p; ++p) { X if (!isascii(*p)) { X *s++ = *p; X continue; X } X if (isprint(*p)) { X *s++ = *p; X continue; X } X X if (*p == '\t') { X int blanks; X X blanks = 8 - ((s - buf) & 0x7); X while (blanks--) { X *s++ = ' '; X } X continue; X } X *s++ = '^'; X *s++ = *p+'@'; X } X if (LineEnds) { X *s++ = '^'; X *s++ = 'J'; X } X *s = EOS; X if (CurOff > strlen(buf)) return; X printw("%.*s", COLS-1, buf+CurOff); X} X Xvoid help() { X clear(); X printw("Movement:\n\th\tmove one column left\n"); X printw("\tj\tmove one line down\n\tk\tmove one line up\n"); X printw("\tl\tmove one column right\n"); X X printw("\n\t<>\tjump 10 columns left/right\n"); X printw("\tb\tjump %d columns left\n", JumpCols); X printw("\td\tjump %d lines down\n", JumpLines); X printw("\tu\tjump %d lines up\n",JumpLines); X printw("\tw\tjump %d columns right (forWards)\n", JumpCols); X printw("\tp\ttop of file\n"); X X printw("\nOther:\n"); X printw("\t-\ttoggle column bar\n\t+\ttoggle end of lines\n"); X printw("\tv\tversion\n\tI\tinformation\n\t^L\trefresh screen\n"); X printw("\tq\tquit\n\tN\tnext file\n\tP\tprevious file\n"); X refresh(); X getch(); X clear(); X} X Xvoid information() { X clear(); X signon(); X printw("\n\n\tSee was writen in response to the need for a program that could\n"); X printw("view an printer ouput file that was more than 80 columns wide in two\n"); X printw("directions without word wrap. This program is in the Public Domain, so\n"); X printw("do what you want with it, but please send me a copy of your changes,\n"); X printw("or bug fixes. Also, any ideas for improvement would be welcome.\n"); X printw("\n\tThank you.\n"); X X printw("\nReply to (uucp):\n"); X printw("\nAndrew Cowie:\t...!uunet!mnetor!lethe!tvcent!andrew or andrew@tvcent.uucp\n"); X refresh(); X getch(); X clear(); X} X Xvoid usage() { X fprintf(stderr, "Usage: %s [-c] filenames...\n",Progname); X fprintf(stderr, "Options:\n"); X fprintf(stderr, " -c Display columns indicator at the top\n"); X fprintf(stderr, "When running, type '?' to get help\n"); X} END_OF_see.c if test 7900 -ne `wc -c <see.c`; then echo shar: \"see.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f Makefile -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"Makefile\" else echo shar: Extracting \"Makefile\" \(376 characters\) sed "s/^X//" >Makefile <<'END_OF_Makefile' X# X# Makefile for see - XENIX X# X XCFLAGS= -O -DM_TERMINFO -DM_XENIX X#CFLAGS= $(CFLAGS) -DMAXCOLS=400 -DMAXLINES=1000 X Xinstall: X cp see /usr/local/bin/see X Xsee: see.o X cc -o see see.o -ltinfo -lx X Xsee.o: see.c X cc $(CFLAGS) -c see.c X Xshar: X shar see.c Makefile >see.sh X X# X#The following was used on a BSD 4.2 system. X# X#see: see.c X# gcc see.c -DM_BSD -lcurses -ltermcap -o see X END_OF_Makefile if test 376 -ne `wc -c <Makefile`; then echo shar: \"Makefile\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of shell archive. exit 0