home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
ddjmag
/
ddj9003.arc
/
STEVENS.LST
< prev
next >
Wrap
File List
|
1990-02-13
|
15KB
|
489 lines
C PROGRAMMING COLUMN
by Al Stevens
[LISTING ONE]
/* ------------ dir.h ----------- */
/* Substitute Lattice directory functions for
* Turbo C directory functions
*/
#include <dos.h>
#define ffblk FILEINFO
#define ff_name name
#define findfirst(path,ff,attr) dfind(ff,path,attr)
#define findnext(ff) dnext(ff)
[LISTING TWO]
/* ---------- search.c ----------- */
/*
* the TEXTSRCH retrieval process
*/
#include <stdio.h>
#include <string.h>
#include <curses.h>
#include "textsrch.h"
static char fnames[MAXFILES] [65];
static int fctr;
static void select_text(void);
static void display_page(WINDOW *file_selector, int pg);
void display_text(char *fname);
/* ---- process the result of a query expression search ---- */
void process_result(struct bitmap map1)
{
int i;
extern int file_count;
for (i = 0; i < file_count; i++)
if (getbit(&map1, i))
strncpy(fnames[fctr++], text_filename(i), 64);
initscr(); /* initialize curses */
select_text(); /* select a file to view */
endwin(); /* turn off curses */
fctr = 0;
}
/* ------- search the data base for a word match -------- */
struct bitmap search(char *word)
{
struct bitmap map1;
memset(&map1, 0xff, sizeof (struct bitmap));
if (srchtree(word) != 0)
map1 = search_index(word);
return map1;
}
#define HEIGHT 8
#define WIDTH 70
#define HOMEY 3
#define HOMEX 3
#define ESC 27
/* --- select text file from those satisfying the query ---- */
static void select_text(void)
{
WINDOW *file_selector;
int selector = 0; /*selector cursor relative to the table */
int cursor = 0; /*selector cursor relative to the screen*/
int keystroke = 0;
/* --- use a window with a border to display the files -- */
file_selector = newwin(HEIGHT+2, WIDTH+2, HOMEY, HOMEX);
keypad(file_selector, 1); /* turn on keypad mode */
noecho(); /* turn off echo mode */
wsetscrreg(file_selector, 1, HEIGHT);/* set scroll limits */
/* -------- display the first page of the table --------- */
display_page(file_selector, 0);
while (keystroke != ESC) {
/* ----- draw the window frame ------ */
box(file_selector, VERT_DOUBLE, HORIZ_DOUBLE);
/* ------------ fill the selector window ------------ */
mvwaddstr(file_selector, cursor+1, 1, "->");
wrefresh(file_selector);
/* -------------- make a selection ------------------ */
keystroke = wgetch(file_selector);/* read a keystroke */
mvwaddstr(file_selector, cursor+1, 1, " ");
switch (keystroke) {
case KEY_HOME:
/* -------- Home key (to top of list) ------- */
selector = cursor = 0;
display_page(file_selector, 0);
break;
case KEY_END:
/* ------- End key (to bottom of list) ------ */
selector = fctr - HEIGHT;
if (selector < 0) {
selector = 0;
cursor = fctr-1;
}
else
cursor = HEIGHT-1;
display_page(file_selector, selector);
break;
case KEY_DOWN:
/* - down arrow (move the selector cursor) -- */
/* --------- test at bottom of list --------- */
if (selector < fctr-1) {
selector++;
/* ------ test at bottom of window ------ */
if (cursor < HEIGHT-1)
cursor++;
else {
/* ---- scroll the window up one ---- */
scroll(file_selector);
/* --- paint the new bottom line ---- */
mvwprintw(file_selector, cursor+1, 3,
fnames[selector]);
}
}
break;
case KEY_UP:
/* --- up arrow (move the selector cursor) -- */
/* ----------- test at top of list ---------- */
if (selector) {
--selector;
/* -------- test at top of window ------- */
if (cursor)
--cursor;
else {
/* --- scroll the window down one --- */
winsertln(file_selector);
/* ----- paint the new top line ----- */
mvwprintw(file_selector, 1, 3,
fnames[selector]);
}
}
break;
case '\n':
/* -- user selected a file, go display it --- */
display_text(fnames[selector]);
break;
case ESC:
/* --------- exit from the display ---------- */
break;
default:
/* ----------- invalid keystroke ------------ */
beep();
break;
}
}
delwin(file_selector); /* delete the selector window */
clear(); /* clear the standard window */
refresh();
}
/* ------ display a page of the file selector window ------- */
static void display_page(WINDOW *file_selector, int line)
{
int y = 0;
werase(file_selector);
while (line < fctr && y < HEIGHT)
mvwprintw(file_selector, ++y, 3, fnames[line++]);
}
[LISTING THREE]
/* ---------------- display.c ----------------- */
/* Display a text file on the screen.
* User may scroll and page the file.
* Highlight key words from the search.
* User may jump to the next and previous key word.
*/
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <ctype.h>
#include <string.h>
#include "textsrch.h"
#define ESC 27
/* ----------- header block for a line of text ----------- */
struct textline {
char keys[5]; /* offsets to key words */
struct textline *nextline; /* pointer to next line */
char text; /* first character of text */
};
/* --------- listhead for text line linked list -------- */
struct textline *firstline;
struct textline *lastline;
int pagemarked(int topline);
static void do_display(FILE *fp);
static void findkeys(struct textline *thisline);
static void display_textpage(WINDOW *text_window, int line);
/* ---------- display the text in a selected file --------- */
void display_text(char *filepath)
{
FILE *fp;
fp = fopen(filepath, "r");
if (fp != NULL) {
do_display(fp);
fclose(fp);
}
else {
/* ----- the selected file does not exist ----- */
char ermsg[80];
sprintf(ermsg, "%s: No such file", filepath);
error_handler(ermsg);
}
}
static void do_display(FILE *fp)
{
char line[120];
WINDOW *text_window;
int keystroke = 0;
int topline = 0;
int linect = 0;
struct textline *thisline;
firstline = lastline = NULL;
/* --------- read the text file into the heap ------- */
while (fgets(line, sizeof line, fp) != NULL) {
line[78] = '\0';
thisline =
malloc(sizeof(struct textline)+strlen(line)+1);
if (thisline == NULL)
break; /* no more room */
/* ----- clear the text line record space -------- */
memset(thisline, '\0', sizeof(struct textline) +
strlen(line)+1);
/* ---- build the text line linked list entry ---- */
if (lastline != NULL)
lastline->nextline = thisline;
lastline = thisline;
if (firstline == NULL)
firstline = thisline;
thisline->nextline = NULL;
strcpy(&thisline->text, line);
/* ------------ mark the key words ------------ */
findkeys(thisline);
linect++;
}
/* ------- build a window to display the text ------- */
text_window = newwin(LINES, COLS, 0, 0);
keypad(text_window, 1); /* turn on keypad mode */
while (keystroke != ESC) {
/* --- display the text and draw the window frame --- */
display_textpage(text_window, topline);
box(text_window, VERT_SINGLE, HORIZ_SINGLE);
wrefresh(text_window);
/* ------------ read a keystroke ------------- */
keystroke = wgetch(text_window);
switch (keystroke) {
case KEY_HOME:
/* ------- Home key (to top of file) ------ */
topline = 0;
break;
case KEY_DOWN:
/* --- down arrow (scroll up) ---- */
if (topline < linect-(LINES-2))
topline++;
break;
case KEY_UP:
/* ----- up arrow (scroll down) ---- */
if (topline)
--topline;
break;
case KEY_PGUP:
/* -------- PgUp key (previous page) -------- */
topline -= LINES-2;
if (topline < 0)
topline = 0;
break;
case KEY_PGDN:
/* -------- PgDn key (next page) ------------ */
topline += LINES-2;
if (topline <= linect-(LINES-2))
break;
case KEY_END:
/* ------- End key (to bottom of file) ------ */
topline = linect-(LINES-2);
if (topline < 0)
topline = 0;
break;
case KEY_RIGHT:
/* - Right arrow. Go to next marked key word */
do {
/* -- repeat PGDN until we find a mark -- */
topline += LINES-2;
if (topline > linect-(LINES-2)) {
topline = linect-(LINES-2);
if (topline < 0)
topline = 0;
}
if (pagemarked(topline))
break;
} while (topline &&
topline < linect-(LINES-2));
break;
case KEY_LEFT:
/* Left arrow. Go to previous marked key word */
do {
/* -- repeat PGUP until we find a mark -- */
topline -= LINES-2;
if (topline < 0)
topline = 0;
if (pagemarked(topline))
break;
} while (topline > 0);
break;
case ESC:
break;
default:
beep();
break;
}
}
/* -------- clean up and exit --------- */
wclear(text_window);
wrefresh(text_window);
delwin(text_window);
thisline = firstline;
while (thisline != NULL) {
free(thisline);
thisline = thisline-> nextline;
}
}
/* ---- test a page to see if a marked keyword is on it ---- */
int pagemarked(int topline)
{
struct textline *tl = firstline;
int line;
while (topline-- && tl != NULL)
tl = tl->nextline;
for (line = 0; tl != NULL && line < LINES-2; line++) {
if (*tl->keys)
break;
tl = tl->nextline;
}
return *tl->keys;
}
#define iswhite(c) ((c)==' '||(c)=='\t'||(c)=='\n')
/* ---- Find the key words in a line of text. Mark their
character positions in the text structure ------- */
static void findkeys(struct textline *thisline)
{
char *cp = &thisline->text;
int ofptr = 0;
while (*cp && ofptr < 5) {
struct postfix *pf = pftokens;/* the query expression */
while (iswhite(*cp)) /* skip the white space */
cp++;
if (*cp) {
/* ---- test this word against each argument in the
query expression ------- */
while (pf->pfix != TERM) {
if (pf->pfix == OPERAND &&
strnicmp(cp, pf->pfixop,
strlen(pf->pfixop)) == 0)
break;
pf++;
}
if (pf->pfix != TERM)
/* ----- the word matches a query argument.
Put its offset into the line's header --- */
thisline->keys[ofptr++] =
(cp - &thisline->text) & 255;
/* --- skip to the next word in the line --- */
while (*cp && !iswhite(*cp))
cp++;
}
}
}
/* --- display page of text starting with specified line --- */
static void display_textpage(WINDOW *text_window, int line)
{
struct textline *thisline = firstline;
int y = 1;
wclear(text_window);
wmove(text_window, 0, 0);
/* ---- point to the first line of the page ----- */
while (line-- && thisline != NULL)
thisline = thisline->nextline;
/* ------- display all the lines on the page ------ */
while (thisline != NULL && y < LINES-1) {
char *cp = &thisline->text;
char *kp = thisline->keys;
char off = 0;
wmove(text_window, y++, 1);
/* ------ a character at a time -------- */
while (*cp) {
/* --- is this character position a key word? --- */
if (*kp && off == *kp) {
wstandout(text_window); /* highlight key words*/
kp++;
}
/* ---- is this character white space? ---- */
if (iswhite(*cp))
wstandend(text_window); /* turn off hightlight*/
/* ---- write the character to the window ------ */
waddch(text_window, *cp);
off++;
cp++;
}
/* -------- a line at a time ---------- */
thisline = thisline->nextline;
}
}
[LISTING FOUR]
/* ------------- error.c ------------- */
/* General-purpose error handler */
#include <curses.h>
#include <string.h>
void error_handler(char *ermsg)
{
int x, y;
WINDOW *error_window;
x = (COLS - (strlen(ermsg)+2)) / 2;
y = LINES/2-1;
error_window = newwin(3, 2+strlen(ermsg), y, x);
box(error_window, VERT_SINGLE, HORIZ_SINGLE);
mvwprintw(error_window, 1, 1, ermsg);
wrefresh(error_window);
beep();
getch();
wclear(error_window);
wrefresh(error_window);
delwin(error_window);
}