home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hot Shareware 32
/
hot34.iso
/
ficheros
/
DTOOL
/
INTER57E.ZIP
/
INTSUM16.ZIP
/
LISTFILE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-10-13
|
25KB
|
785 lines
//********************************************************************
// LISTFILE.CPP - Handle ListFile display, searching, etc.
//
// Copyright (c) 1996 Daniel D. Miller
//
// Last Update: 09-04-95 11:17pm
//
// Compile with makefile
//
//********************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include "intsum.hpp"
#include "err_exit.hpp"
#include "keycodes.h"
// #include <memcheck.h>
static char srchstr[81] ;
//*****************************************************************
static void fill_list_buffers(fpos_t pos);
static int search_list_buffers(void);
static void search_list_file(void);
static void back_up_list1(void);
//*****************************************************************
void process_list_file(int list_mode, char *save_file)
{
char sfile[128], sname[13] ;
char lstr[sizeof(sum_conv)+1] ;
unsigned j, ref_bfr ;
int_sum_line *iptr = (int_sum_line *) lstr ;
dprints(0, 2, LOGO, list_header) ;
dprints(0, 3, LOGO, list_dividerd) ;
// initialize list-file variables which are not
// otherwise later set up.
list.offset = 0 ;
list.cur_bfr = 0 ;
list.hdptr[0] = 0L ;
// figure out which line in ref file was selected
ref_bfr = (unsigned) ref.cur_bfr ;
unsigned currow = ref.offset + ivideo.currow - DATA_TOP ;
if (currow > (ref.lines[0] + ref.lines[1]))
return ;
if (ref.cur_bfr == 0 && currow > ref.lines[0])
{
ref_bfr = 1 ;
currow -= ref.lines[0] ;
}
else if (ref.cur_bfr == 1 && currow > ref.lines[1])
return ;
// read appropriate data into list-file struct.
strcpy(lstr, ref.bfr[ref_bfr][currow].instr) ;
if (iptr->file == ' ')
{
_makepath(sfile, ildrive, ilpath, "interrup", "lst") ;
strcpy(sname,"interrup.lst") ;
}
else
{
char c2s[5] ;
c2s[0] = iptr->file ;
c2s[1] = NULL ;
_makepath(sfile, ildrive, ilpath, "interrup", c2s) ;
_makepath(sname, NULL, NULL, "interrup", c2s) ;
}
// determine file offset
iptr->null_term = 0 ;
fpos_t loffset = strtol(iptr->foffset, NULL, 16) ;
// open the file
lfile = fopen(sfile, "rb") ;
if (lfile == NULL)
error_exit(NO_READ_FILE, sfile) ;
fill_list_buffers(loffset) ; // fill the list buffers
// now, determine whether this is a "print topic" call
// or a normal "display" call
if (list_mode == 1)
{
// open the output file
FILE* outfile = fopen(save_file, "wt") ;
if (outfile == NULL)
{
strupr(save_file) ;
sprintf(tempstr, "cannot open %s", save_file) ;
message_show(tempstr) ;
fclose(lfile) ;
dprints(0, 2, LOGO, header) ;
dprints(0, 3, LOGO, dividerd) ;
return ;
}
// write the data into it
ref_bfr = 0 ; // overloading this variable
j=0 ;
do {
fprintf(outfile, "%s\n", list.bfr[ref_bfr][j].instr) ;
if (++j > list.lines[ref_bfr])
{
j = 0 ;
if (++ref_bfr == 2)
{
fill_list_buffers(list.tlptr[1]) ; // refill the list buffers
ref_bfr = 0 ;
}
}
}
while (strncmp(list.bfr[ref_bfr][j].instr, "--------", 8) != 0) ;
// close files and exit
fclose(outfile) ;
fclose(lfile) ;
dprints(0, 2, LOGO, header) ;
dprints(0, 3, LOGO, dividerd) ;
return ;
}
// display current filename on screen
dprints(1, 2, FILENAME, sname) ;
// display the first buffer of data
ivideo.currow = DATA_TOP ;
display_list_file() ;
// list-file keyboard handler
srchstr[0] = 0 ; // reset the search string
unsigned rtemp ;
int count ;
int done = 0 ;
while (!done)
{
mark_cursor_line(ivideo.currow, SELECTED) ;
unsigned indata = get_key() ;
mark_cursor_line(ivideo.currow, MAIN_TEXT) ;
switch (indata)
{
case Key_UP:
scroll_list_down() ;
break;
case Key_PGUP:
rtemp = ivideo.currow ;
ivideo.currow = DATA_TOP ;
for (j=0; j<window_rows; j++)
scroll_list_down() ;
ivideo.currow = rtemp ;
break;
case Key_DOWN:
scroll_list_up() ;
break;
case Key_PGDN:
rtemp = ivideo.currow ;
ivideo.currow = screen_rows - 1 ;
for (j=0; j<window_rows; j++)
scroll_list_up() ;
ivideo.currow = rtemp ;
break;
case Key_HOME:
loffset = 0 ;
fill_list_buffers(loffset) ;
list.offset = 0 ;
list.cur_bfr = 0 ;
ivideo.currow = DATA_TOP ;
display_list_file() ;
break;
case Key_END:
// seek end of file
fseek(lfile, 0L, SEEK_END) ;
fgetpos(lfile, &loffset) ;
loffset -= REV_SIZE ;
// adjust input-file position, then
// read one line and re-position file pointer to full line
fsetpos(lfile, &loffset) ;
count = seek_next_line(lfile) ;
if (count < 0)
error_exit(BAD_SEARCH, NULL) ;
loffset += count ;
fill_list_buffers(loffset) ;
// now, figure out which line is top of (end of screen)
if (list.lines[1] < window_rows)
{
list.cur_bfr = 0 ;
list.offset = list.lines[0] + list.lines[1] - window_rows ;
}
else
{
list.cur_bfr = 1 ;
list.offset = list.lines[1] - window_rows ;
}
ivideo.currow = DATA_TOP ;
display_list_file() ;
break;
case Key_F1:
case Key_h:
case Key_H: // display help screen
display_help() ;
display_logo() ;
dprints(0, 2, LOGO, list_header) ;
display_list_file() ;
break;
case Key_F2:
case Key_s:
case Key_S: // search for string
if (message_read("Enter string to search for: ", srchstr) == 0)
{
if (search_list_buffers() != 0)
search_list_file() ;
}
// redraw current filename on screen
dprints(0, 2, LOGO, list_header) ;
dprints(1, 2, FILENAME, sname) ;
break;
case Key_F3:
case Key_r:
case Key_R: // repeat last string search
if (strlen(srchstr) == 0)
message_show("There is no current search string") ;
else if (search_list_buffers() != 0)
search_list_file() ;
// redraw current filename on screen
dprints(0, 2, LOGO, list_header) ;
dprints(1, 2, FILENAME, sname) ;
break;
case Key_ESC:
fclose(lfile) ;
dprints(0, 2, LOGO, header) ;
dprints(0, 3, LOGO, dividerd) ;
done = 1 ;
break;
default:
break;
} // keyboard switch
} // while not done
}
//*****************************************************************
void fill_list_buffers(fpos_t pos)
{
// adjust input-file position
fsetpos(lfile, &pos) ;
list.hdptr[0] = pos ;
// read data and fill list_list buffer 0
list.lines[0] = fill_list_bfr(0) ; // fill forward buffer
// read data and fill list_list buffer 1
list.hdptr[1] = list.tlptr[0] ;
list.lines[1] = fill_list_bfr(1) ; // fill aft buffer
}
//*****************************************************************
// first, search current list buffer(s) starting at list.offset.
//*****************************************************************
int search_list_buffers(void)
{
unsigned sline = list.offset + (ivideo.currow - DATA_TOP) + 1 ;
int srch_done ;
// first, search list.bfr0 if active
if (list.cur_bfr == 0)
{
srch_done = 0 ;
if (sline <= list.lines[0])
{
while (!srch_done)
{
// If string is found, update buffers and move cursor
if (strstri(list.bfr[0][sline].instr, srchstr) == 0)
{
list.offset = sline ;
// I _think_ this is the correct position
search.offset = sline ;
list.offset = sline ;
ivideo.currow = DATA_TOP ;
display_list_file() ;
return 0;
}
// string is not yet found; move along in buffer0
// if at end of buffer, exit and try buffer 1.
else if (++sline >= list.lines[0])
{
srch_done = 1 ;
sline = 0 ;
}
} // while not done searching
} // if first search line actually IS in bfr0
// if search line lapses into bfr1, move there
else
{
sline -= list.lines[0] ;
}
}
// then, search list.bfr1 if active, and nothing found in 0
if (list.lines[1] > 0)
{
srch_done = 0 ;
while (!srch_done)
{
// If string is found, update buffers and move cursor
if (strstri(list.bfr[1][sline].instr, srchstr) == 0)
{
search.offset = sline ;
list.cur_bfr = 1 ;
list.offset = sline ;
ivideo.currow = DATA_TOP ;
display_list_file() ;
return 0;
}
// string is not yet found; move along in buffer1.
// if at end of buffer, exit and try other buffers.
else if (++sline >= list.lines[1])
{
srch_done = 1 ;
sline = 0 ;
}
} // while not done searching
} // if any lines are in buffer1, search it
return -1 ;
}
//*****************************************************************
// current buffers have already been searched, with nothing found.
// Now, search list file starting at list.tlptr[1].
//*****************************************************************
void search_list_file(void)
{
// first, save current file pointer so it
// can be restored if no match is found.
fpos_t oldpos ;
fgetpos(lfile, &oldpos) ;
// position file pointer to current cursor position
search.hdptr = list.tlptr[1] ;
fsetpos(lfile, &search.hdptr) ;
// move past it to current line (if possible)
// fill the readbfr from list file
unsigned rlines = fill_search_buffer(lfile) ;
if (rlines == 0)
{
message_show("Your search string was not found") ;
return ;
}
unsigned sline = 0 ;
int srch_done = 0 ;
while (!srch_done)
{
// If string is found, update buffers and move cursor
if (strstri(search.bfr[sline].instr, srchstr) == 0)
{
// read real data from beginning of current block
fill_list_buffers(search.hdptr) ;
// I _think_ this is the correct position
search.offset = sline ;
list.offset = sline ;
list.cur_bfr = 0 ;
ivideo.currow = DATA_TOP ;
display_list_file() ;
srch_done = 1 ;
}
// string is not yet found; move along in readbfr.
// if at end of buffer, read next buffer or fail.
else if (++sline >= rlines)
{
search.hdptr = search.tlptr ;
rlines = fill_search_buffer(lfile) ;
if (rlines == 0)
{
// restore input-file position
fsetpos(lfile, &oldpos) ;
srch_done = -1 ;
message_show("Your search string was not found") ;
}
else
{
sline = 0 ;
}
}
} // while not done searching
}
//*****************************************************************
void scroll_list_down(void)
{
// if cursor is NOT at top, move cursor
if (ivideo.currow > DATA_TOP)
{
ivideo.currow-- ;
}
// if cursor IS at top, try to move up in current buffer
else if (list.offset > 0) // scroll window down
{
list.offset-- ;
display_list_file() ;
}
// if current buffer is 1, just move back to buffer 0
else if (list.cur_bfr == 1)
{
list.cur_bfr = 0 ;
list.offset = list.lines[0] - 1 ;
display_list_file() ;
}
// if current buffer = 0, see if we're at beginning of file.
// if so, do nothing; otherwise, try to read back in buffer,
// after copying buffer 0 to buffer 1.
else if (list.hdptr[0] > 0)
{
// copy buffer0 values to buffer1
// swap the buffer pointers
lines *b = list.bfr[0] ;
list.bfr[0] = list.bfr[1] ;
list.bfr[1] = b ;
list.lines[1] = list.lines[0] ;
list.hdptr[1] = list.hdptr[0] ;
list.tlptr[1] = list.tlptr[0] ;
// current buffer remains 0.
// list.cur_bfr = 0 ;
// then compute and read new data into buffer0
fill_list_bfr_rev() ; // fill forward buffer
if (list.offset > 0)
list.offset-- ;
display_list_file() ;
}
}
//*****************************************************************
void scroll_list_up(void)
{
// end_line is line number for NEXT line
unsigned end_line = list.offset + window_rows ; // base-0
// if still onscreen, just move cursor
if (ivideo.currow+1 < screen_rows)
{
ivideo.currow++ ;
}
// end of screen...
// see if there's still room in buffer to move cursor
else if (end_line < list.lines[list.cur_bfr])
// ^base-0 ^base-1
{
list.offset++ ;
display_list_file() ;
}
// we are at end of buffer
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// BUFFER 0
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
else if (list.cur_bfr == 0)
// If we're in buffer0, we should be able to slop over
// into buffer1, if there's any data in it.
{
// if we were previously in buffer0, but now (after
// adding one line) we don't fit in buffer0+buffer1,
// there were less than (screen_size) lines in buffer1,
// which means we're at end of file (otherwise, we
// would have read roughly 32Kbytes).
//
// NOTE: we do not currently handle scrolling
// across multiple files.
//
if (end_line >= (list.lines[0] + list.lines[1]))
{
// do nothing for now...
// Later, we'll add multiple-file support.
}
// If there is room in the two combined files, see if
// moving to next line has thrown us COMPLETELY into buffer1.
else if ((list.offset+1) == list.lines[0])
{
list.offset = 0 ;
list.cur_bfr = 1 ;
display_list_file() ;
}
// otherwise, we're overlapping two files,
// which the list function supports internally.
else
{
list.offset++ ;
display_list_file() ;
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// BUFFER 1
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// if NOT at end of buffer 1, update array offset and redraw
else if (end_line < list.lines[1])
// ^base0 ^base1
{
list.offset++ ;
display_list_file() ;
}
// if we reach end of buffer 1,
// copy buffer 1 to buffer 0 and see if
// there's more data to scroll into.
else
{
back_up_list1() ;
if (list.lines[1] > 0)
{
list.offset++ ;
display_list_file() ;
}
}
}
//*****************************************************************
void back_up_list1(void)
{
// swap the buffer pointers
lines *b = list.bfr[0] ;
list.bfr[0] = list.bfr[1] ;
list.bfr[1] = b ;
// copy buffer1 data to buffer0 struct
list.lines[0] = list.lines[1] ;
list.hdptr[0] = list.hdptr[1] ;
list.tlptr[0] = list.tlptr[1] ;
list.cur_bfr = 0 ;
list.hdptr[1] = list.tlptr[0] ;
// read new data into buffer1
list.lines[1] = fill_list_bfr(1) ;
}
//*****************************************************************
void display_list_file(void)
{
// buffer_left is 1-based
unsigned j, buffer_left = list.lines[list.cur_bfr] - list.offset ;
// ^base-1 ^base-1 ^base-0
// if current buffer fits entirely onscreen
if (window_rows <= buffer_left)
{
for (j=0; j<window_rows; j++)
{
dprints(0, DATA_TOP+j, MAIN_TEXT,
list.bfr[list.cur_bfr][list.offset+j].instr) ;
}
}
// if we're currently using buffer 0, just lop over into bfr 1
// Fill any unused lines with blank lines.
else if (list.cur_bfr == 0)
{
if (window_rows > (buffer_left + list.lines[1]))
// ^base1 ^base1 ^base1
{
// draw remainder of buffer0
for (j=0; j<buffer_left; j++)
{
dprints(0, DATA_TOP+j, MAIN_TEXT,
list.bfr[0][list.offset+j].instr) ;
}
// draw all of buffer1
unsigned new_top = DATA_TOP + buffer_left ;
for (j=0; j<list.lines[1]; j++)
{
dprints(0, new_top++, MAIN_TEXT, list.bfr[1][j].instr) ;
}
// draw blank lines
spaces[80] = 0 ;
//for (j=new_top; j<screen_rows; j++)
while (new_top < screen_rows)
{
dprints(0, new_top++, MAIN_TEXT, spaces) ;
}
spaces[80] = ' ' ;
}
else
{
for (j=0; j<buffer_left; j++)
{
dprints(0, DATA_TOP+j, MAIN_TEXT,
list.bfr[0][list.offset+j].instr) ;
}
for (j=0; j<(window_rows-buffer_left); j++)
{
dprints(0, DATA_TOP+buffer_left+j, MAIN_TEXT,
list.bfr[1][j].instr) ;
}
}
}
// we're at end of buffer 1; are we at EOF??
else
{
// copy buffer1 to buffer0,
// then refill buffer 1.
back_up_list1() ;
// recursively call this display routine
display_list_file() ;
}
}
//*****************************************************************
// parse lines from input file.
//*****************************************************************
const unsigned TAB_SIZE = 8 ;
unsigned fill_list_bfr(unsigned bfr_flag)
{
int done = 0 ;
//lint -e740
unsigned offseti = FP_OFF(readptr) ; // init value for byte tfr counter
unsigned offsetf ;
unsigned count = 0, j ;
// fill the readbfr from list file
unsigned rlines = fill_read_buffer(lfile) ;
if (rlines == 0)
return 0;
// now, translate the read buffer into the list-list buffer
unsigned lcount = 0 ; // output_buffer counter
char *sptr = readptr ;
while (!done)
{
unsigned slen = strlen(sptr) ;
if (slen == 0) // insert a blank line
{
spaces[80] = 0 ;
strcpy(list.bfr[bfr_flag][lcount].instr, spaces) ;
spaces[80] = ' ' ;
}
// copy data to list buffer. strcpy() won't do because
// TABs have to be converted from the input files.
//strcpy(list.bfr[bfr_flag][lcount].instr, sptr) ;
else
{
char* cptr = sptr ;
j = 0 ;
while (j < 80 && *cptr != 0)
{
switch (*cptr)
{
case TAB:
do {
if (j < 80)
{
list.bfr[bfr_flag][lcount].instr[j] = ' ' ;
}
j++ ;
}
while ((j % TAB_SIZE) != 0);
cptr++ ; // strip the TAB char from input
break;
default:
list.bfr[bfr_flag][lcount].instr[j++] = *cptr++ ;
break;
} // switch (input char)
}
// if input line is longer than 80 chars, skim ahead to EOL
if (j == 80)
{
while (*cptr != 0) cptr++ ;
}
else
{
// pad short lines with spaces
while (j < 80)
{
list.bfr[bfr_flag][lcount].instr[j++] = ' ' ;
}
}
list.bfr[bfr_flag][lcount].instr[80] = 0 ; // NULL-term the line
// point to next string in buffer
sptr += slen ;
} // copy line to list buffer, expanding TABs
// skip NULLs, which were formerly CR/LF
// Skipping ALL NULLs is not appropriate, as this
// effectively deletes blank lines.
// We should skip at most 2 NULLs, then add all
// further NULL pairs as blank lines.
if (*sptr == NULL) sptr++ ; // skip CR
if (*sptr == NULL) sptr++ ; // skip LF
count++ ;
lcount++ ;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// Determine if we are at end of input data (count),
// or if output buffer is full (lcount)
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
if (lcount == list_lines || count == rlines)
{
done = 1 ;
// set tail-pointer variable in current list struct
offsetf = FP_OFF(sptr) ; //lint !e740
list.tlptr[bfr_flag] = list.hdptr[bfr_flag] + (offsetf - offseti) ;
// adjust input-file position
fpos_t pos = list.tlptr[bfr_flag] ;
fsetpos(lfile, &pos) ;
}
} // while not done filling input buffer
return count;
}
//*****************************************************************
void fill_list_bfr_rev(void)
{
unsigned count ;
int done, icount ;
// make a copy of current line before overwriting it,
// so we can find it again afterwards
strcpy(oldstr, list.bfr[1][list.offset].instr) ;
if (strlen(oldstr) == 0)
error_exit(BAD_FORMAT, NULL) ;
// figure out how far to back up the read pointer
fpos_t pos = IFF (list.hdptr[0] > REV_SIZE)
THENN (list.hdptr[0] - REV_SIZE)
ELSSE 0 ;
// now read one line and re-position file pointer to full line
// (if we're at beginning of file, don't bother)
if (pos > 0)
{
fsetpos(lfile, &pos) ;
icount = seek_next_line(lfile) ;
if (icount < 0)
error_exit(BAD_SEARCH, NULL) ;
pos += icount ;
}
fill_list_buffers(pos) ;
// now that new buffers have been read,
// seek to the current line and update list.offset
count = 0 ;
done = 0 ;
while (!done)
{
if (strcmp(oldstr, list.bfr[0][count].instr) == 0)
{
list.offset = count ;
done = 1 ;
}
else if (++count >= list.lines[0])
error_exit(BAD_SEARCH, NULL) ;
}
}