home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hot Shareware 32
/
hot34.iso
/
ficheros
/
DTOOL
/
INTER57E.ZIP
/
INTSUM16.ZIP
/
INTSUM.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-10-13
|
19KB
|
599 lines
//********************************************************************
// INTSUM.CPP - Display/search program for Ralf Brown's
// Interrupt List.
//
// Copyright (c) 1996 Daniel D. Miller
//
// Last Update: 09-08-95 08:42pm
//
// Compile with makefile
//
//********************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <graph.h>
#include "intsum.hpp"
#include "err_exit.hpp"
#include "keycodes.h"
// #include <memcheck.h>
//*****************************************************************
main(int argc, char** argv)
{
int done, count ;
unsigned j ;
uchar char_attr ;
// make sure at least DOS 3.0 is running
if (_osmajor < 3)
error_exit(OLD_DOS_VERSION, NULL) ;
// get path for executable file
_splitpath(argv[0], inidrive, inipath, NULL, NULL) ;
// calculate video parameters
char_attr = get_char_attr() ;
get_vsize() ;
window_rows = screen_rows - DATA_TOP ; // base-1
select_video_seg(0) ; // auto-detect video segment
// initialize the path for IntList files,
// before reading INI file.
strcpy(ildrive, inidrive) ;
strcpy(ilpath , inipath) ;
// search for/parse INI file
read_ini_file() ;
// allocate raw-data read buffer
readptr = new char[(unsigned) BFR_SIZE] ;
if (readptr == NULL)
error_exit(OUT_OF_MEMORY, NULL) ;
// allocate ref-file buffers
ref.bfr[0] = new sum_conv[isl_lines] ;
if (ref.bfr[0] == NULL)
error_exit(OUT_OF_MEMORY, NULL) ;
ref.bfr[1] = new sum_conv[isl_lines] ;
if (ref.bfr[1] == NULL)
error_exit(OUT_OF_MEMORY, NULL) ;
// allocate ref-search buffer
search.bfr = new sum_conv[isl_lines] ;
if (search.bfr == NULL)
error_exit(OUT_OF_MEMORY, NULL) ;
// allocate list-file buffers
list.bfr[0] = new lines[list_lines] ;
if (list.bfr[0] == NULL)
error_exit(OUT_OF_MEMORY, NULL) ;
list.bfr[1] = new lines[list_lines] ;
if (list.bfr[1] == NULL)
error_exit(OUT_OF_MEMORY, NULL) ;
// search for interrup.idx
// Build it if not present
//
// NOTE: if files are opened in TEXT mode,
// EOLs get translated from CRLF in file to \n in buffer,
// and "bytes read" is not what was asked for.
// This program uses BINARY to solve some of these problems.
_makepath(tempstr, ildrive, ilpath, "interrup", "idx") ;
index = fopen(tempstr, "rb") ;
if (index == NULL)
{
build_index() ;
_makepath(tempstr, ildrive, ilpath, "interrup", "idx") ;
index = fopen(tempstr, "rb") ;
if (index == NULL)
error_exit(NO_READ_FILE, "interrup.idx") ;
}
// leave ref file open
// initialize variables and read first ref buffer
ref.cur_bfr = 0 ;
ref.offset = 0 ;
fpos_t pos = 0 ;
fill_ref_buffers(pos) ;
//****************************************
// hold off building display until
// setup operations are successful.
//****************************************
// hide the cursor
hide_cursor() ;
// display our logo
clear_display(MAIN_TEXT) ;
display_logo() ;
// display the first window
display_ref_file() ;
// main keyboard handler
char srchstr[81] ;
srchstr[0] = 0 ; // reset initial search string
unsigned rtemp ;
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_ENTER: // seek info on current entry
rtemp = ivideo.currow ;
process_list_file(0, NULL) ;
ivideo.currow = rtemp ;
display_ref_file() ;
break;
case Key_UP:
scroll_page_down() ;
break;
case Key_HOME:
// position cursor at beginning of file
pos = 0 ;
fill_ref_buffers(pos) ;
ref.offset = 0 ;
ref.cur_bfr = 0 ;
ivideo.currow = DATA_TOP ;
display_ref_file() ;
break;
case Key_END:
// seek end of file
fseek(index, 0L, SEEK_END) ;
fgetpos(index, &pos) ;
pos -= REV_SIZE ;
// adjust input-file position
fsetpos(index, &pos) ;
ref.hdptr[0] = pos ;
// now read one line and re-position file pointer to full line
count = seek_next_line(index) ;
if (count < 0)
error_exit(BAD_SEARCH, NULL) ;
pos += count ;
fill_ref_buffers(pos) ;
// now, figure out which line is top of (end of screen)
if (ref.lines[1] < window_rows)
{
ref.cur_bfr = 0 ;
ref.offset = ref.lines[0] + ref.lines[1] - window_rows ;
}
else
{
ref.cur_bfr = 1 ;
ref.offset = ref.lines[1] - window_rows ;
}
ivideo.currow = DATA_TOP ;
display_ref_file() ;
break;
case Key_PGUP:
rtemp = ivideo.currow ;
ivideo.currow = DATA_TOP ;
for (j=0; j<window_rows; j++)
scroll_page_down() ;
ivideo.currow = rtemp ;
break;
case Key_DOWN:
scroll_page_up() ;
break;
case Key_PGDN:
rtemp = ivideo.currow ;
ivideo.currow = screen_rows - 1 ;
for (j=0; j<window_rows; j++)
scroll_page_up() ;
ivideo.currow = rtemp ;
break;
case Key_F1:
case Key_h:
case Key_H: // display help screen
display_help() ;
display_logo() ;
display_ref_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_ref_buffers(srchstr) != 0)
search_ref_file(srchstr) ;
}
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_ref_buffers(srchstr) != 0)
search_ref_file(srchstr) ;
break;
case Key_F4:
case Key_t:
case Key_T: // save current topic
char sfile[81] ; // local storage for filename
if (message_read("Enter filename to save to: ", sfile) == 0 &&
strlen(sfile) > 0)
{
rtemp = ivideo.currow ;
process_list_file(1, sfile) ;
ivideo.currow = rtemp ;
display_ref_file() ;
}
break;
case Key_ESC:
// delete buffers explicitly, so the allocations
// aren't shown by memory checkers.
delete readptr ;
delete ref.bfr[0] ;
delete ref.bfr[1] ;
delete search.bfr ;
delete list.bfr[0] ;
delete list.bfr[1] ;
done = 1 ;
break;
default:
break;
}
}
clear_display(char_attr) ;
home_cursor() ;
puts(THANKS_MESSAGE) ;
puts(" Copyright (c) 1995 Dan Miller") ;
puts(" derelict@netcom.com") ;
return 0;
}
//*****************************************************************
// read <UNDERSHOOT> bytes from (infile) into global (rdtemp),
// then scan to beginning of next line and return number
// of bytes to that next line.
//*****************************************************************
int seek_next_line(FILE* infile)
{
int count = 0 ;
fread(rdtemp, 1, UNDERSHOOT, infile) ;
int done = 0 ;
while (!done)
{
if (rdtemp[count] == 0x0D || rdtemp[count] == 0x0A)
{
done = 1 ;
while (rdtemp[count] == 0x0D || rdtemp[count] == 0x0A)
{
if (++count == UNDERSHOOT)
return -1 ;
}
}
else if (++count == UNDERSHOOT)
return -1 ;
}
return count;
}
//*****************************************************************
ulong make_laddr(char* instr)
{
ulong ts = ((ulong) FP_SEG(instr)) << 4 ; //lint !e740
ulong to = (ulong) FP_OFF(instr) ; //lint !e740
return ts + to ;
}
//*****************************************************************
// NULL-terminates all lines in inbfr, by converting all
// CR and LF into NULL. Also counts the lines and returns count.
//*****************************************************************
unsigned convert_lines(char* inbfr, unsigned rcount)
{
unsigned count = 0 ; // output line count
unsigned bcount = 0 ; // input character count
while (bcount < rcount)
{
if (*inbfr == 0x0D || *inbfr == 0x0A)
{
count++ ;
while (*inbfr == 0x0D || *inbfr == 0x0A)
{
*inbfr++ = 0 ;
bcount++ ;
}
}
else
{
inbfr++ ;
bcount++ ;
}
}
return count ;
}
//*****************************************************************
// parse lines from input file.
// Back file up to
//*****************************************************************
unsigned fill_search_buffer(FILE* infile)
{
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 ref file
unsigned rlines = fill_read_buffer(infile) ;
if (rlines == 0)
return 0;
// DEBUG:
ulong iaddr = make_laddr(search.bfr[0].instr) ;
// now, translate the read buffer into the ref-list buffer
unsigned lcount = isl_lines ;
char *sptr = readptr ;
while (!done)
{
unsigned slen = strlen(sptr) ;
// DEBUG:
{
ulong saddr = make_laddr(search.bfr[count].instr) ;
if ((saddr+slen - iaddr) > (ulong) BFR_SIZE)
{
printf("\nSearch overrun:\n") ;
printf("count = %d\n", count) ;
printf("iaddr=%ld, saddr=%ld\n", iaddr, saddr) ;
exit(1) ;
}
}
strcpy(search.bfr[count].instr, sptr) ;
// pad short lines with spaces
if (slen < sizeof(sum_conv))
{
for (j=slen; j<last_ref_char; j++)
search.bfr[count].instr[j] = ' ' ;
// now, NULL-terminate the line
search.bfr[count].instr[last_ref_char] = 0 ;
}
// point to next string in buffer
sptr += slen ;
while (*sptr == 0) sptr++ ; // skip NULLs at end of last line
count++ ;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// If this terminates on lcount, rather than rlines,
// the input buffer will have to be adjusted
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
if (--lcount == 0 || count == rlines)
{
done = 1 ;
// set tail-pointer variable in current ref struct
offsetf = FP_OFF(sptr) ; //lint !e740
search.tlptr = search.hdptr + (offsetf - offseti) ;
fsetpos(infile, &search.tlptr) ; // adjust input-file position
}
}
return count;
}
//*****************************************************************
// Read a buffer-worth of raw data into readbfr,
// do a partial read-and-fill to ensure that it contains
// a full line at the end,
// then replace all 0x0D and 0x0A with NULLs.
// Return a count of lines.
//
// This routine reads from the current input file pointer
//*****************************************************************
unsigned fill_read_buffer(FILE* infile)
{
//***********************************************************
// read data into read buffer and ensure even-line boundary.
// This method assumes that the input file has already
// been correctly positioned using fseek().
//***********************************************************
unsigned rbytes = fread(readptr, 1, ((unsigned) BFR_SIZE)-UNDERSHOOT, infile) ;
if (rbytes == 0)
return 0;
//***********************************************************
// FILL LAST LINE
// if last line doesn't already end with a newline,
// read more data to get there, and tack it on the end.
//***********************************************************
char* endptr = readptr + rbytes - 1 ;
if (*endptr != 0x0D && *endptr != 0x0A)
{
unsigned slen = fread(rdtemp, 1, UNDERSHOOT, infile) ;
if (slen == 0)
error_exit(NO_READ_FILE, "reading infile") ;
unsigned j=0;
// search for newline (it MUST be there!!)
while (rdtemp[j] != 0x0D && rdtemp[j] != 0x0A)
{
j++ ;
if (j >= UNDERSHOOT)
error_exit(BAD_FORMAT, rdtemp) ;
}
// then NULL-out and count the newlines
while (rdtemp[j] == 0x0D || rdtemp[j] == 0x0A)
{
rdtemp[j] = 0 ;
j++ ;
if (j >= UNDERSHOOT)
error_exit(BAD_FORMAT, rdtemp) ;
}
slen = j ;
// copy the extra bytes into read buffer
for (j=0; j<slen; j++)
{
*endptr++ = rdtemp[j] ;
}
rbytes += slen ;
}
// NULL-terminate and count the lines in read buffer.
return convert_lines(readptr, rbytes) ;
}
//*****************************************************************
void display_logo(void)
{
dprints(0, 0, LOGO, logo) ;
dprints(0, 1, LOGO, dividers) ;
dprints(0, 2, LOGO, header) ;
dprints(0, 3, LOGO, dividerd) ;
}
//*****************************************************************
// Build the indexed reference list
//*****************************************************************
void build_index(void)
{
union sum_conv outList ;
char lname[_MAX_PATH] ;
FILE* idxfile ;
FILE* infile ;
fpos_t fpos ;
char instr[128], outstr[80] ;
unsigned lflag ;
char lext, extn[3] = ".x" ;
unsigned long out_lines = 0L ;
_makepath(tempstr, ildrive, ilpath, "interrup", "idx") ;
idxfile = fopen(tempstr, "wb") ;
if (idxfile == NULL)
error_exit(NO_WRITE_FILE, "INTERRUP.IDX") ;
puts(Version) ;
puts("Building index file... this will take a couple of minutes") ;
_makepath(lname, ildrive, ilpath, "interrup", "lst") ;
infile = fopen(lname, "rb") ;
if (infile == NULL) // then combined file does not exist; use parts
{
lflag = 0 ;
lext = 'a' ;
printf("reading INTERRUP.x sections: ") ;
_makepath(lname, ildrive, ilpath, "interrup", "a") ;
infile = fopen(lname, "rb") ;
if (infile == NULL)
{
fclose(idxfile) ;
unlink(tempstr) ;
error_exit(NO_LIST_FILE, lname) ;
}
}
else
{
lflag = 1 ;
lext = ' ' ;
printf("reading INTERRUP.LST: ") ;
}
fclose(infile) ;
int done = 0 ;
while (!done)
{
// open the next input file
infile = fopen(lname, "rb") ;
// if next file can't be opened, we're done!!
if (infile == NULL)
{
fclose(idxfile) ;
printf("\nRef file contains %lu lines\n", out_lines) ;
return ;
}
putchar(lext) ;
fpos = 0L ;
// now that the next List file is open,
// start searching for divider lines
while ((fgets(instr, 128, infile)) != NULL)
{
if (strncmp(instr, "--------", 8) == 0 &&
instr[9] == '-' &&
instr[8] != '!'
)
{
out_lines++ ;
// reset the output data field
memset(outList.idx.data, ' ', 80) ;
outstr[ 0] = ' ' ;
outstr[ 1] = instr[10] ; // INT number
outstr[ 2] = instr[11] ;
outstr[ 3] = ' ' ;
outstr[ 4] = instr[12] ; // AH contents
outstr[ 5] = instr[13] ;
outstr[ 6] = ' ' ;
outstr[ 7] = instr[14] ; // AL contents
outstr[ 8] = instr[15] ;
outstr[ 9] = ' ' ;
outstr[10] = instr[8] ; // classification
outstr[11] = '>' ;
outList.idx.file = lext ;
sprintf(outList.idx.foffset, "%08lX", fpos) ;
outList.idx.null_term = ' ' ; // replace NULL with SPACE in file
// move instr up to description line
fgets(instr, 128, infile) ;
// Trim line to 80 chars
int inlen = strlen(instr) ;
while (instr[inlen-1] == 0x0D || instr[inlen-1] == 0x0A)
{
instr[--inlen] = 0 ;
}
strncpy(&outstr[12], &instr[8], 80-13) ; // append to outstr
outstr[80] = 0 ; // add safety NULL-terminator
strcpy(outList.idx.data, outstr) ;
fprintf(idxfile, "%s\r\n", outList.instr) ;
} // if line matches search pattern, add to index file
fgetpos(infile, &fpos) ; // update input-file pointer
} // if input file not yet empty
fclose(infile) ;
if (lext == ' ')
{
done = 1 ;
fclose(idxfile) ;
}
else
{
extn[1] = ++lext ;
_makepath(lname, ildrive, ilpath, "interrup", extn) ;
}
} // while not done parsing files
}