#define FUNCPFX '@'
#define HPLEN   768

#include "pcstdio.h"
#include "pcdefs.h"
#include "a:printf.c"

char *helpfile = "PC.HLP";

/* 512-byte Configuration Header */
int Tlines, Tcols;
char Tinstr[LIN];  int Tinnul;
char Tdeinstr[LDEIN];  int Tdeinnul;
char Tdcpstr[LDCP];  int Tdcpnul;
char Tclsstr[LCLS];  int Tclsnul;
char Teosstr[LEOS];  int Teosnul;
char Teolstr[LEOL];  int Teolnul;
char Trvstr[LRV];
char Tnvstr[LNV];
int prtwidth;
char Pinstr[LPIN];
char Pdeinstr[LPDEIN];
char Tbottom[LBOTTOM];
int Keys[LKEYS];
/* end of Configuration Header */

int nkeys, list;  FILE *chanfp;
char *Names[LKEYS], *FNames[LKEYS];
int _fmode = 0x8000;            /* binary file operations */

main(argc, argv)
int argc;  char *argv[];
{   int n, len, i, wchan;  char *bp, swp_buf[HPLEN];
    list = (argc > 1 && tolower(*argv[1]) == 'l');  n = 0;
    if ((wchan=creat("PC.OVL", 0x8001)) == -1) err("Cannot create", "PC.OVL");
    if ((list && argc == 3) || (!list && argc == 2)) helpfile = argv[argc-1];
    if ((chanfp=fopen(helpfile, "r"))== NULL) err("Cannot open", helpfile);
    format("Processing %s...\n");  printf(helpfile);
    MakeHeader();  MakeKeys();
    for (n=1; ; ++n)
    {   for (i=0; i<HPLEN; i++) swp_buf[i] = 0;  bp = swp_buf;
        if (list) {format("Help page %u:\n");  printf(n);}
        while ((i=getc(chanfp)) > 0 && i != 032) *bp++ = i;
        if (i == EOF || i == 032) break;
        ReplKeys(swp_buf);
        if (write(wchan, swp_buf, HPLEN) == -1)
            err("Cannot write out", helpfile);
    }
    format("%u Help pages @ 3 rec/ea...\n");  printf(n-1);
    if (write(wchan, &Tlines, 512) == -1) err("Cannot write configuration","");
    format("2 Config recs\n");  close(wchan);
}

tolower(c)
int c;
{   return((c >= 'A' && c <= 'Z')? c+('a'-'A') : c);  }

err(s1, s2)
char *s1, *s2;
{   format("\007%s %s\n");  printf(s1);  printf(s2);  exit(1);   }

MakeHeader()            /* Make configuration header from help file */
{   Tlines = getint();  Tcols = getint();
    getstr(Tinstr);     Tinnul = getint();
    getstr(Tdeinstr);   Tdeinnul = getint();
    getstr(Tdcpstr);    Tdcpnul = getint();
    getstr(Tclsstr);    Tclsnul = getint();
    getstr(Teosstr);    Teosnul = getint();
    getstr(Teolstr);    Teolnul = getint();
    getstr(Trvstr);     getstr(Tnvstr);
    prtwidth = getint();  getstr(Pinstr);  getstr(Pdeinstr);
    getstr(Tbottom);
}

getint()        /* returns next integer from 'chan' file */
{   int n, c;
    n = 0;  while ((c=getc(chanfp)) >= '0' && c <= '9' ) n = n*10 + c - '0';
    while (c != '\n') c = getc(chanfp); /* scan over next '\n' */
    return(n);
}

getstr(s)       /* places next '\t'-terminated string into *s */
char *s;
{   while ((*s++ = getc(chanfp)) != '\t') ;     /* span sting */
    *--s = 0;  while (getc(chanfp) != '\n') ;   /* scan over next '\n' */
}

MakeKeys()      /* Make Keys[] array from help file */
{   int i;  char *getname();

    for (i=0; i<LKEYS; i++)
    {   Keys[i] = getoct();
        Names[i] = getname();
        FNames[i] = getname();
        if (list)
        {   format("\t%o\t\t%s\t\t%s\n");  printf(Keys[i]);
            printf(Names[i]);  printf(FNames[i]);
        }
        if (Keys[i] == 0) break;
    }
    nkeys = i;  while (getc(chanfp)) ;  /* leave just after NULL */
}

getoct()
{   int n, c;
    n = 0;  while ((c=getc(chanfp)) < '0' || c > '7') ;
    do n = n*8 + c - '0'; while ((c=getc(chanfp)) >= '0' && c <= '7');
    return(n);
}

char *getname()
{   char name[30], *np, *newname, *nnp;  int c;
    np = name;  while ((c=getc(chanfp)) <= ' ') ;
    do *np++ = c; while ((c=getc(chanfp)) >= ' ');  *np++ = 0;
    if ((newname=(char *)getmem(np-name)) == NULL)
        err("Out of space for names.", "");
    np = name;  nnp = newname;  while (*np) *nnp++ = *np++;  *nnp = 0;
    return(newname);
}

ReplKeys(help)
char *help;
{   char *hp, *fp;  int i;
    hp = help;
    while (1)
    {   while (*hp != FUNCPFX)          /* scan to next FName */
            if (++hp >= help+HPLEN) return;
        if (list) putchar('\t');  fp = hp-1;
        while (*++fp > ' ') if (list) putchar(*fp);
        if (list) format("\t\t->\t\t");
        for (i=0; i<=nkeys; i++)
            if (strcmp(FNames[i], hp)) break;
        if (i <= nkeys) /* found it -- do the replacement */
        {   if (list) format(Names[i]);
            fp = Names[i];  for (i=0; i<8; i++) *hp++ = (*fp)? *fp++ : ' ';
        } else hp = fp;
        if (list) putchar('\n');
    }
}

strcmp(str1, str2)      /* compare str1 against str2 */
char *str1, *str2;
{   while (*str1 && *str2 > ' ' && *str1 == *str2)  {str1++;    str2++;}
    return(!*str1 && *str2 <= ' ');
}
