[net.sources] ded.c

cliff@unmvax.UUCP (11/03/84)

/* cc -O -o ded ded.c -lcurses -ltermlib */
/* ded -anything will ring the bell on unique prefixes */
/* works under 4.2 */

/* INPUT should be a sorted file
   with no distinction between upper and lower case. */

/* speed entry of playlists, by allowing abbreviations */

#define INPUT "input"
#define OUTPUT "output"

#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <curses.h>
#include <signal.h>
#include <sgtty.h>

extern FILE *fopen();
FILE *outfile;

char *everything, *malloc();
char **everypointer;

int filelength, count;

extern void init(), putentry(), finit();
extern int getentry();
extern char *abbrev();

int beepflag = 0;

int (*(functs[128]))();

main(argc, argv)
int argc;
char **argv;
{
    if (argc == 2)
	beepflag = 1;
    (void) init();
    while (getentry())
	(void) putentry();
    (void) finit();
}

#define Stat stat
#define Open open
#define Malloc malloc
#define Read read
#define Write write
#define Close close
#define Ioctl ioctl

#define ASSOC(c, p) if (c != -1) functs[c & 0177] = p;

int newline(base, pointer)
char *base;
char **pointer;
{
    return(1);
}

int myerase(base, pointer)
char *base;
char **pointer;
{
    if (*pointer > base)
	*--(*pointer) = 0;
    return(0);
}

int kill(base, pointer)
char *base;
char **pointer;
{
    *pointer = base;
    **pointer = 0;
    return(0);
}

int eof(base, pointer)
char *base;
char **pointer;
{
    (void) finit();
/*NOTREACHED*/
}

int reprint(base, pointer)
char *base;
char **pointer;
{
    (void) wrefresh(curscr);
    return(0);
}

int worderase(base, pointer)
char *base;
char **pointer;
{
    while (*pointer > base && *--*pointer == ' ')
	;
    while (*pointer >= base && *--*pointer != ' ')
	;
    *(++(*pointer)) = '\0';
    return(0);
}

int tab(base, pointer)
char *base;
char **pointer;
{
    register int i;

    for (i = 8 - ((*pointer - base) % 8) ; i-- ; *((*pointer)++) = ' ')
	;
    **pointer = '\0';
    return(0);
}

void init()
{
    static char *nullstring = "";
    struct stat sbuf;
    int input;
    char *p, **q;
    struct sgttyb sgb;
    struct tchars tch;
    struct ltchars ltc;

    (void) Ioctl(fileno(stdin), TIOCGETP, &sgb);
    (void) Ioctl(fileno(stdin), TIOCGETC, &tch);
    (void) Ioctl(fileno(stdin), TIOCGLTC, &ltc);

    ASSOC(ltc.t_rprntc, reprint);
    ASSOC(ltc.t_werasc, worderase);
    ASSOC(sgb.sg_erase, myerase);
    ASSOC(sgb.sg_kill,  kill);
    ASSOC(tch.t_eofc,   eof);
    ASSOC('\n',         newline);
    ASSOC('\t',         tab);

    (void) Stat(INPUT,&sbuf);
    filelength = sbuf.st_size;
    input = Open(INPUT,O_RDONLY);
    everything = Malloc(filelength);
    (void) Read(input, everything, filelength);
    count = 0;
    for ( p = everything-1 ; ++p < everything + filelength ; ) {
	if (*p == '\n') {
	    *p = 0;
	    count++;
	}
    }
    everypointer = (char **) Malloc((count + 2) * sizeof(char *));
    *everypointer++ = nullstring;
    *(everypointer + count) = nullstring;
    q = everypointer;
    *(q++) = everything;
    for ( p = everything-1 ; ++p < everything + filelength ; )
	if (!*p)
	    *(q++) = p + 1;
    (void) Close(input);
    (void) initscr();
    (void) refresh();
    (void) leaveok(stdscr,0);
    (void) crmode();
    (void) noecho();
    outfile = fopen(OUTPUT,"a");
    (void) signal(SIGTERM, finit);
    (void) signal(SIGHUP, finit);
    (void) signal(SIGQUIT, finit);
    (void) signal(SIGINT, finit);
}

char *lastline;
char tline[80];

int getentry()
{
    char c, *p;

    p = tline;
    *p = 0;
    while (1) {
	if (Read(fileno(stdin), &c, 1) == 0)
	    return(0);
	else {
	    if (functs[c&0177] != 0) {
		if (functs[c&0177](tline,&p))
		    return(1);
	    } else if (isprint(c)) {
		(void) addch(c);
		*(p++) = c;
		*p = 0;
	    } else
		continue;
	    (void) move(0,0);
	    lastline = abbrev(tline);
	    (void) printw("%s",lastline);
	    (void) clrtoeol();
	    (void) move(0,p - tline);
	    (void) refresh();
	}
    }
}

void putentry()
{
    (void) fprintf(outfile,"%s\n",lastline);
    lastline = tline;
    (void) move(0,0);
    (void) clrtoeol();
    (void) refresh();
}

void finit()
{
    (void) fclose(outfile);
    (void) echo();
    (void) nocrmode();
    (void) endwin();
    exit(0);
}

int mycmp(s1, s2, n)
char *s1, *s2;
int n;
{
    char c, d;

    while (n--) {
	c = isupper(*s1) ? tolower(*s1++) : *(s1++);
	d = isupper(*s2) ? tolower(*s2++) : *(s2++);
	if (c < d)
	    return(-1);
	if (c > d)
	    return( 1);
    }
    return(0);
}

char *abbrev(s)
char *s;
{
    char *p;
    char **low, **high, **mid;
    int n;

    if (*s == 0)
	return(s);
    n = strlen(s);
    p = s;
    low = everypointer;
    high = everypointer + count -1;
    while (low <= high) {
	mid = low + (high - low) / 2;
	switch (mycmp(s, *mid, n)) {
	case -1:
	    high = mid - 1;
	    break;
	case  0:
	    if (beepflag)
		if (mycmp(*mid, *(mid-1), n) && mycmp(*mid, *(mid+1), n))
		    (void) Write(fileno(stdout), "", 1);
	    return(*mid);
	case  1:
	    low = mid + 1;
	    break;
	}
    }
    return(s);
}

/*	--Cliff [Matthews]
	{lbl-csam, purdue, cmcl2, ihnp4}!lanl!unmvax!cliff
	{csu-cs, pur-ee, convex, gatech, ucbvax}!unmvax!cliff
	4744 Trumbull S.E. - Albuquerque  NM  87108 - (505) 265-9143 */