home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR24
/
MORE_20B.ZIP
/
SOURCE.ZIP
/
MORE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-12
|
10KB
|
441 lines
/* "A better More" version 1.1
(C) 1993 Stephen M. Lacy
This program still needs a bit of refinement and addition of options,
although its kind of nice for now.
Revision history:
Version 1.0: Well, sort of. This was used by only me for about two
days. Bugs: Defaulted to 80x24, and printed the last line twice
Version 1.1: First release version. The 0-9 keys were added, along,
with the 'q' key to quit. The last line problem was fixed, and I added
some code to see how big the window was, it used to default to 80x24.
Version 2.0: Completely ignores carriage return characters, but on a
line feed, does both line feed and carriage return.
KNOWN BUGS:
Version 1.1: The disappering cursor thingy. Icky formatting issues.
*/
/* #define INCL_DOS */
#define INCL_VIO
#define INCL_KBD
#include <os2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _dllist {
char *string;
struct _dllist *next,*previous;
} dllist, *pdllist, **ppdllist;
#define CONTROL_S 19
#define PROMPT "-- MORE v2.0ß (C)1993 --"
#define EOF_STRING "-- EOF --"
#define CELLSIZE 2
#define DEFAULT_SCROLLUP 4
#define DEFAULT_TABSIZE 4
#define DEFAULT_ATTRIB 0x07
#define DEFAULT_BOLD 0x0f
#define DEFAULT_PROMPT 0x1e
#define DEFAULT_UNDERSCORE 0x0e
#define MORE_EOF 1
int tabsize,options,scrollup;
CHAR bright[2],attrib[2],blankcell[2],colorcell[2],underscore,bold;
void add_dllist(ppdllist first, ppdllist prev, ppdllist new) {
if (*prev) {
(*new)->next=(*prev)->next;
(*new)->previous=(*prev);
(*prev)->next=(*new);
(*prev)=(*new);
}
else {
(*new)->next=NULL;
(*new)->previous=NULL;
*prev=*new;
*first=*new;
}
}
char *get_single_line(FILE *input,int width) {
char *result,readin;
int counter,j,end,reread;
result=(char*)malloc((width+1)*2*sizeof(char));
for (counter=0;counter<width*2;counter++) {
result[counter++]=' ';
result[counter]=attrib[0];
}
counter=0;
end=FALSE;
reread=TRUE;
while(counter<width*2 && !end) {
if (reread) readin=fgetc(input);
switch (readin) {
case '\t':
for (j=0;j<tabsize;j++) {
result[counter]=' ';
counter+=CELLSIZE;
}
break;
case '\b':
readin=fgetc(input);
switch(result[counter-CELLSIZE]) {
case '_':
result[counter-CELLSIZE+1]=underscore;
break;
default:
result[counter-CELLSIZE+1]=bold;
break;
}
result[counter-CELLSIZE]=readin;
break;
case '\r':
break;
case '\n':
end=TRUE;
break;
default:
result[counter]=readin;
counter+=CELLSIZE;
break;
}
}
return(result);
}
int get_screenful(FILE *input,
ppdllist first,
ppdllist after,
int width,
int height) {
int counter;
char *temp;
pdllist new_element;
counter=0;
while (counter<height && !feof(input)) {
new_element=(pdllist)malloc(sizeof(dllist));
new_element->string=get_single_line(input,width);
add_dllist(first,after,&new_element);
counter++;
}
return(counter);
}
void display_screenful(pdllist first,int height,int width, int read) {
int i;
char *display;
pdllist current;
int counter,j;
USHORT row,col;
VioGetCurPos(&row,&col,0);
display=(char*)malloc(2*(height+1)*(width+1)*sizeof(char));
current=first;
counter=0;
j=0;
while (current && j<height ) {
memcpy((&display[counter]),current->string,width*2);
counter+=width*2;
current=current->next;
j++;
}
if (-read==height) read=-read;
if (read<0) {
read=-read;
VioScrollDn(0,0,height-1,width,read,blankcell,0);
VioWrtCellStr(display,width*read*2,0,0,0);
} else if (row+read<height) {
VioSetCurPos(row+read,0,0);
VioWrtCellStr(display,width*read*2,row,0,0);
} else if (row+read>height && read<height) {
if (first->previous!=NULL) display+=width*2*(height-read);
VioScrollUp(0,0,height,width,abs(read-(height-row)),blankcell,0);
VioWrtCellStr(display,width*read*2,height-read,0,0);
VioSetCurPos(height,0,0);
} else {
VioWrtCellStr(display,width*height*2,0,0,0);
VioSetCurPos(height,0,0);
}
free(display);
}
int backup(ppdllist which, int n) {
int i=0;
while ((*which)->previous && n) {
(*which)=(*which)->previous;
n--;
i++;
}
return(i);
}
void forward_search(ppdllist list,
ppdllist end_of_list,
FILE *input,
char *string,
int rows,
int cols,
int *offscreen) {
char expanded[600];
INT counter,i;
pdllist new_element;
counter=0;
for (i=0;i<512;) {
expanded[i++]=string[counter++];
expanded[i++]=attrib[0];
}
while(1) {
if (strstr((*list)->string,expanded)) break;
if (feof(input) && (*end_of_list)->next==NULL) break;
if ((*list)->next) {
(*list)=(*list)->next;
(*offscreen)--;
} else {
new_element=(pdllist)malloc(sizeof(dllist));
new_element->string=get_single_line(input,cols);
add_dllist(list,end_of_list,&new_element);
}
}
backup(end_of_list,rows);
}
void more_file(FILE *input) {
PVIOMODEINFO vmi;
KBDKEYINFO kbdi;
SHORT rows,cols;
CHAR string[255],searchbuffer[255],*tempstr;
CHAR *display;
/* CHAR searchstring[255],previous_search[255]; */
STRINGINBUF stringbuf;
pdllist whole_list,current,end_of_list;
int i,val,read,lines,offscreen;
USHORT rc,upval,r,c;
KBDINFO kbdinfo;
KbdGetStatus(&kbdinfo,0);
vmi=(PVIOMODEINFO)malloc(sizeof(VIOMODEINFO));
vmi->cb=sizeof(VIOMODEINFO);
rc=VioGetMode(vmi,0);
if (rc!=0) {
printf("Error doing VioGetMode! %d\n",rc);
exit(0);
}
rows=vmi->row-1;
cols=vmi->col;
whole_list=NULL;
end_of_list=NULL;
lines=rows;
offscreen=0;
while (options&MORE_EOF?1:!feof(input)) {
if (lines-offscreen>0) {
read=get_screenful(input,
&whole_list,
&end_of_list,
cols,
lines-offscreen);
if (read!=lines-offscreen)
backup(&whole_list,lines-offscreen-read);
display_screenful(whole_list,rows,cols,read);
} else {
display_screenful(whole_list,rows,cols,lines);
}
if (lines>0) offscreen-=lines;
if (offscreen<0) offscreen=0;
if (options&MORE_EOF?1:!feof(input)) {
if (feof(input))
VioWrtCharStrAtt(EOF_STRING,strlen(EOF_STRING),
rows,0,bright,0);
else VioWrtCharStrAtt(PROMPT,strlen(PROMPT),rows,0,bright,0);
KbdCharIn(&kbdi,0,0);
if (kbdi.fbStatus & 0x0002) {
switch (kbdi.chScan) {
case 72:
/* Up arrow */
lines=scrollup;
offscreen+=lines=backup(&whole_list,lines);
lines=-lines;
break;
case 80:
/* Down Arrow */
lines=scrollup;
break;
case 73:
/* Page up */
lines=rows;
offscreen+=lines=backup(&whole_list,lines);
lines=-lines;
break;
case 81:
/* Page Down */
lines=rows;
break;
default:
if (feof(input)) return;
break;
}
} else
switch(kbdi.chChar) {
/* case '/':
lines=0;
VioWrtNCell(colorcell,cols,rows,0,0);
stringbuf.cb=255;
kbdinfo.fsMask|=KEYBOARD_ASCII_MODE;
kbdinfo.fsMask&=~KEYBOARD_BINARY_MODE;
KbdSetStatus(&kbdinfo,0);
KbdStringIn(searchstring,&stringbuf,0,0);
searchstring[strlen(searchstring)-1]='\0';
kbdinfo.fsMask&=~KEYBOARD_ASCII_MODE;
kbdinfo.fsMask|=KEYBOARD_BINARY_MODE;
KbdSetStatus(&kbdinfo,0);
if (strcmp(searchstring,"\0D"))
forward_search(&whole_list,
&end_of_list,
input,
searchstring,
rows,
cols,
&offscreen);
else if (strcmp(previous_search,"\0D"))
forward_search(&whole_list,
&end_of_list,
input,
previous_search,
rows,
cols,
&offscreen);
strcpy(previous_search,searchstring);
break;
*/
case 'f':
case 'F':
lines=scrollup;
break;
case 'b':
case 'B':
lines=scrollup;
offscreen+=lines=backup(&whole_list,lines);
lines=-lines;
break;
case 13:
lines=scrollup;
break;
case 'n':
case 'N':
while (input==stdin && !feof(input)) fgetc(input);
fclose(input);
VioWrtNCell(blankcell,cols,rows,0,0);
KbdFlushBuffer(0);
return;
break;
case 'q':
case 'Q':
while (input==stdin && !feof(input)) fgetc(input);
fclose(input);
VioWrtNCell(blankcell,cols,rows,0,0);
KbdFlushBuffer(0);
return;
default:
lines=rows;
if (feof(input)) return;
break;
}
for (i=0;i<lines && whole_list->next;i++)
whole_list=whole_list->next;
}
}
KbdFlushBuffer(0);
}
char *strupper(char *string) {
int i;
char *original;
original=string;
while (*string) {
if (*string>='a' && *string<='z')
*string-='a'-'A';
string++;
}
return(original);
}
void main (int argc, char *argv[]) {
FILE *input;
USHORT row, col;
pdllist file_list,current,new;
HDIR hdirDir;
ULONG file_attrib,searchCount,infoLevel;
USHORT rc;
FILEFINDBUF3 ffbData;
CHAR prompt[128];
CHAR result[255];
PSZ temp;
KBDKEYINFO kbdi;
KBDINFO kbdinfo;
INT i;
tabsize=DEFAULT_TABSIZE;
scrollup=DEFAULT_SCROLLUP;
underscore=DEFAULT_UNDERSCORE;
bold=DEFAULT_BOLD;
attrib[0]=DEFAULT_ATTRIB;
bright[0]=DEFAULT_PROMPT;
blankcell[0]=' ';
blankcell[1]=DEFAULT_ATTRIB;
colorcell[0]=' ';
colorcell[1]=DEFAULT_ATTRIB;
options=MORE_EOF;
file_list=current=NULL;
KbdGetStatus(&kbdinfo,0);
kbdinfo.fsMask&=~KEYBOARD_ASCII_MODE;
kbdinfo.fsMask|=KEYBOARD_BINARY_MODE;
KbdSetStatus(&kbdinfo,0);
if (argc==1) {
more_file(stdin);
}
else {
for (i=1;i<argc;i++) {
input=fopen(argv[i],"r");
if (input==NULL) {
printf("Error opening file '%s'.\n",argv[i]);
printf("Most likely, file non-existant.\n");
exit(0);
}
more_file(input);
if (i<argc-1) {
sprintf(prompt,"-- BEGIN FILE %s --",strupper(argv[i+1]));
VioGetCurPos(&row,&col,0);
VioWrtCharStrAtt(prompt,strlen(prompt),row,0,bright,0);
VioWrtNCell(blankcell,col,row,0,0);
KbdCharIn(&kbdi,0,0);
switch(kbdi.chChar) {
case 'q':
case 'Q':
VioGetCurPos(&row,&col,0);
VioSetCurPos(row-1,0,0);
exit(0);
}
}
}
}
VioGetCurPos(&row,&col,0);
VioSetCurPos(row-1,0,0);
}