/*
 *  OHelp -- An Online Help facility (Version 2.0)
 *           Copyright (c) 1989 by John Wiederhirn
 *
 *  See 'OHelp.doc' for more information on installation & operation.
 *
 */

#include    <stdio.h>

#define SOE '~'
#define EOE '@'

/*
 *  This allows the user to relocate where OHelp expects to find the
 *  help data file, using Matt Dillon's CONFIG pgm (FF168/169).  The
 *  default is to "OHelp.hlp" in the current directory.
 *
 */

short   config[] = {
    'ST', 'RT', 0, 0,
    'TE', 'XT', 0,46, 'He','lp',' f','il','e ','at',':\x0',
              'OH','el','p.','hl','p\x0',0,0,0,0,0,0,0,0,0,0,0,
    'EN', 'D ', 0 };

/*
 *  These are external function declarations.
 *
 */

extern  char    tolower(), *strcpy(), *strncpy(), *strcat(), *fgets();
extern  int 	strcmp();

/*
 *  These are all of my global data and internal function declarations...
 *
 */

char    buffer[80], spat[80], *lowerit();
FILE    *fp;
int 	locateit(), writeit(),listem();
void    endit();

/*
 *  Here's where the program figures out what to do.
 *
 */

main (argc,argv)

int argc;
char    *argv[];

{
int curr;
char    *search;
char    *filnam;

    curr = 0;
    filnam = (char *)&config[15];
    search = &spat[0];
    do {
        if (argc > 1)
            ++curr;
        search = strcpy(&spat[0],argv[curr]);
        if ((fp = fopen(filnam,"r")) == NULL)
            endit(1);
        if (!(strcmp(search,"?"))) {
        if (listem())
            endit(5);
        } else {
        search = strcat(search,"\n");
        if (locateit(search))
            endit(2);
        if (writeit())
            endit(3);
        }
        if (fclose(fp))
            endit(4);
    } while (curr<(argc-1));
    endit(0);
}

/*
 *  The locateit() subroutine trys to find the entry in the help data
 *  file, and if it can't it returns an error code.  If it does, it
 *  positions the file pointer at the start of the actual entry.
 *
 */

int locateit( snam )

    char    *snam;

    {
    char    *dummy;
    int match, header;

        match = 0;
        dummy = &buffer[0];
        while ((match == 0) & (dummy != NULL)) {
            header = 0;
            dummy = &buffer[0];
            while ((header == 0) & (dummy != NULL)) {
                dummy = fgets(dummy, 81, fp);
                if (buffer[0] == SOE)
                    header = 1;
            }
            if (dummy != NULL) {
            snam = lowerit( snam );
            dummy = lowerit( &buffer[1] );
            if (!(strcmp(snam,dummy)))
                match = 1;
            }
        }
        if (match)
            return(NULL);
        if (feof(fp))
            return(1);
        if (ferror(fp))
            return(2);
        return(3);
    }

/*
 *  The writeit() sbr. then proceeds to write the selected entry to
 *  the screen (or wherever the user redirects it...).  Again, if there's
 *  a problem, an error code is returned.
 *
 */

int writeit()

    {
    char    *dummy, *lin;
    int good, len;

        good = 0;
        dummy = strncpy(&buffer[0], "\x0", 80);
        lin = strncpy(&spat[0], "\x0", 80);
        while (dummy)
        {
            puts(lin);
            lin = strncpy(lin, "\x0", 80);
            dummy = fgets( dummy, 81, fp);
            len = strlen( dummy ) - 1;
            lin = strncpy( lin, dummy, len );
            if (buffer[0] == EOE)
            {
                good = 1;
                dummy = NULL;
                puts("");
            }
        }
        if (good)
            return(NULL);
        if (feof(fp))
            return(1);
        if (ferror(fp))
            return(2);
        return(3);
    }

/*
 *  This next nifty sbr. decides whether everything ended OK, and if it
 *  didn't, prints an appropriate error message.
 *
 */

void    endit( x )

    int x;

    {
    char    *msg;

        switch(x)
        {
        case 1:
            puts("Error opening the Help file!");
            exit(0);
            break;
        case 2:
            msg = strcat("!!! Can't find entry for: ",&spat[0]);
            puts(msg);
            exit(0);
            break;
        case 3:
            puts("Error in help entry!");
            x = fclose(fp);
            exit(0);
            break;
        case 4:
            puts("Error closing the Help file!");
            exit(0);
            break;
        case 5:
            puts("Error listing help topics!");
            exit(0);
            break;
        default:
            exit(0);
        }
    }

/*
 *  The program uses this sbr. to convert the user-supplied argument,
 *  and the help data headers both to lower-case so they can be
 *  compared for equality.
 *
 */

char    *lowerit( s )

    char    *s;

    {
    char    low[80];
    short   slen, x;

        slen = strlen( s );
        for( x=0; x < slen; x++)
        {
            low[x] = tolower( s[x] );
        }
        low[x] = '\x0';
        s = strcpy(s,&low[0]);
        return( s );
    }

/*
 *  Last, this baby is the sbr. which scans the help data file, and
 *  prints out all the topics for which help is available.  This
 *  actually amounts to dumping a "nice" format listing of all the
 *  help data entry headers.
 *
 */

int listem()

    {
    char    *dummy, *line, *d2, hdr[80];
    int header, nochr, hdrlen;

        puts("Help is available for these keywords:");
        nochr = 0;
        dummy = &buffer[0];
        line = strncpy(&spat[0],"\x0",80);
        while (dummy != NULL) {
            header = 0;
            dummy = &buffer[0];
            d2 = strncpy(&hdr[0],"\x0",80);
            while ((header == 0) & (dummy != NULL)) {
                dummy = fgets(dummy, 81, fp);
                if (buffer[0] == SOE)
                    header = 1;
            }
            if (dummy != NULL) {
                hdrlen = strlen(&buffer[1]) - 1;
                dummy = strncpy(d2,&buffer[1],hdrlen); 
                dummy = strcat(dummy,"  ");
                if ((hdrlen+nochr+2)<70) {
                    nochr += hdrlen + 2;
                    line = strcat(line,dummy);
                } else {
                    puts(line);
                    line = strncpy(line,"\x0",80);
                    nochr = hdrlen + 2;
                    line = strcat(line,dummy);
                }
            }
        }
        puts(line);
        if (dummy != NULL)
            return(NULL);
        if (feof(fp))
            return(NULL);
        if (ferror(fp))
            return(2);
        return(3);
    }

/*
 *  Vot vsyo! (Translation: "That's all!")
 *
 */
