From:	CSBVAX::MRGATE!info-vax-request@kl.sri.com@SMTP  1-DEC-1987 18:50
To:	ARISIA::EVERHART
Subj:	Simple less-like pager (c. 300 lines)     Type "J" to skip.


Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Tue 1 Dec 87 09:10:08-PST
Received: by ucbvax.Berkeley.EDU (5.58/1.26)
	id AA22398; Tue, 1 Dec 87 09:00:27 PST
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: 1 Dec 87 04:55:03 GMT
From: aplcen!jhunix!ins_bxs@mimsy.umd.edu  (Xuning Shan)
Organization: Johns Hopkins Univ. Computing Ctr.
Subject: Simple less-like pager (c. 300 lines)     Type "J" to skip.
Message-Id: <5718@jhunix.UUCP>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

Since the program is a simple less-like pager, it only supports
some essential features. The program has been tested with VAXC V2.2.

Shan Xuning
ins_bxs@jhuvms.BITNET
ins_bxs%jhuvms.BITNET@wiscvm.ARPA

----------------------------------------CUT HERE---------------------
/*Shan Xuning, Dept. of Chem. Engr, JHU   18/11/87  */
/*No warranty of any kind, either expressed or implied.*/
/* options:     f==>skip forward 22 lines;
		t==>top of the file;
		b==>skip backward;
		h==>help message;
		q==>quit;
		+==>print next line;
	        !==>spawn subprocess;
		/string==> search forward for string. The question
mark "?"  matches any characters. The string found will be
printed as first word on the next screen. The search ignores cases.

		<cr> and all other characters not listed above
	print next screen.

Send comments and revisions to ins_bxs@jhuvms.BITNET*/
#include <stdio.h>
#include <ctype.h>
#include <descrip.h>
#define T               1
#define F               0
FILE *fp,*fopen();
main(argc, argv)
int argc;
char **argv;
{
	if (argc < 2) {
		printf("File:");
		scanf("%s",argv[1]);
	}

	if ((fp = fopen(argv[1], "r")) == NULL) {
		printf("can't open %s\n", argv[1]);
		exit();
	}
	less(fp);
}

less(fp)
FILE *fp;
{

	char c,psign='%',*pcmd,cmd[40],string[80],str1[160],str2[160];
	char term[40],*tp,*getenv();
	static char vt100[10]="vt100",vt52[10]="vt52";
	int i = 0,j=0,k=0,wc=1,test=0,dev1=0,dev2=0;
	int ftell(),fseek(),getpattern(),find();
	int win[150],temp=0,info=0,sizet=0;
	win[0]=0;
	fseek(fp,0,2);
	sizet=ftell(fp);
	tp=(&term[0]);
	tp=getenv("TERM");
	fseek(fp,0,0);
/* I use vt100 series termial. If you use different type, the 
escape sequences for writing in reverse mode should be changed
in the message line. If you don't care, just use plain
message line. */
	dev1=find(vt100,tp);
	dev2=find(vt52,tp);
	prwindow(fp);
	while(T){
		info=ftell(fp);
		win[wc++]=info;
		temp=(float)info/(float)sizet*100.0;
		if(dev1){
			printf("\033[7mless...%d%c\033[0m",temp,psign);
		}
		else if(dev2){
			printf("\033\010less...%d%c\033\007",temp,psign);
		}
		/*add your terminal type here*/
		else {
			printf("less...%d%c",temp,psign);
		}
		getline(cmd);
		switch(cmd[0]){
			case '+':
				prline(fp);
				break;
			case '\n':
				prwindow(fp);
				break;
			case '!':
				spawn();
				wc=wc-2;
				if(wc<=0){
					wc=1;
					fseek(fp,0,0);
					prwindow(fp);
					}
				else{
					fseek(fp,win[wc],0);
					prwindow(fp);
				}
				break;
			case 'b':
				wc=wc-3;
				if(wc<=0){
					wc=1;
					fseek(fp,0,0);
					prwindow(fp);
					}
				else{
					fseek(fp,win[wc],0);
					prwindow(fp);
				}
				break;
			case 't':
				fseek(fp,0,0);
				wc=1;
				prwindow(fp);
				break;
			case 'q':
				printf("\n\n");
				exit();
			case 'f':
				j=0;
				printf("\nSkipping forward 22 lines.\n");
				while(j<=22){
					if(fgets(str1,160,fp)==NULL){
						printf("\n\nEND OF FILE\n");
						exit();
					}
					j++;
			        }
				break;
			case '/':
				k=1;
				while(k<=39){
					string[k-1]=cmd[k];
					k++;
				}
				getpattern(str2,fp);
				while(!(test=find(string,str2))){
					if(!getpattern(str2,fp)){
						wc=wc-2;
						if(wc<0)wc=1;
						fseek(fp,win[wc],0); 
					printf("\nPattern not found.\n");
					sleep(-2);
					break;
					}	
				}
				if(test){
					printf("%s",str2);
				}
				prwindow(fp);
				break;
			case 'h':
				printf("\n\n\tt:  top of the file;\n");
				printf("\tf:  skip forward;\n");
				printf("\tb:  skip backward;\n");
				printf("\th:  print this message;\n");
				printf("\t!:  spawn subprocess;\n");
				printf("\t\\string:  search forward;\n");
				printf("\tq:  quit for now.\n\n");
				printf("type <return> to continue\n");
				getchar();
				break;
			default:
				prwindow(fp);
				break;			
		}
	}	
}

prwindow(fp)
FILE *fp;
{
	int i=0;
	char *fgets(),str[160];
	printf("\n");
	while(i<22){
		if(fgets(str,160,fp)==NULL) {
			printf("\nEND OF FILE\n");
			exit();
		}
		printf("%s",str);
		i=i+1;
	}
}

prline(fp)
FILE *fp;
{
	char *fgets(),str[160];
	if(fgets(str,160,fp)==NULL){
		printf("\nEND OF FILE\n");
		exit();
	}
	printf("%s",str);
}

getline(cmd)
char *cmd;
{
	int i=0;
	char c;
	while((c=getchar())!='\n') {
		if(isspace(c)){
			continue;
		}
		cmd[i++]=tolower(c);
/*eliminate spaces, ignore cases */
	}
	cmd[i]='\0';
}

int len(str)
char *str;
{	
	int i=0;
	while(*str++) i++;
	return(i);
}


int getpattern(str,fp)
char *str;
FILE *fp;
{
	int c,i=0;
	while(T){
		c=getc(fp);
		if(c==EOF){
			return(F);
		}
		if(isalnum(c)) break;
	}		
	*str++=tolower(c);
	while(i++<=80){
		c=getc(fp);
		if(c==EOF) return(F);
		if(isspace(c)) break;
		*str++=tolower(c);
	}		
	*str='\0';
	return(T);	
}

int find(str1,str2)
char *str1,*str2;
{
	int i=0,len1=0,len2=0,strlen();
	char  *temp;
	temp=str1;
	len1=strlen(str1);
	len2=strlen(str2);
	if(len1>len2) return(F);
	while((*temp)!='\0'){
		if((*str2=='\0')) return(F);	
		if(*temp=='?') {
			temp++;	
			str2++;
			continue;
		}
		if((*temp++)!=(*str2++)) temp=str1;
	}
	return(T);
}


spawn()
{
    	static char cmd[10]="spawn\0";
	$DESCRIPTOR(cmddesc,cmd);
	printf("Spawning subprocess......");
    	lib$spawn(&cmddesc);
}
---------------------------END HERE------------------------------
