/*{{{  #includes*/
#include <termcap.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <local/bool.h>
/*}}}  */

/*{{{  prototypes for getopt*/
int getopt(int,char**,char*);
extern char *optarg;
extern int optind;
/*}}}  */
/*{{{  termcap-data-structs*/
typedef struct { char *capability; char *alias; } term_alias;
term_alias alias_table[] =
 { { "@1", "begin" },
   { "@7", "end" },
   { "K1", "upper_left_pad" },
   { "K2", "center_pad" },
   { "K3", "upper_right_pad" },
   { "K4", "bottom_left_pad" },
   { "K5", "bottom_right_pad" },
   { "kb", "backspace" },
   { "kB", "backtab" },
   { "kd", "down" },
   { "kD", "rubout" },
   { "kE", "clreol" },
   { "kh", "home" },
   { "kl", "left" },
   { "kL", "delline" },
   { "kN", "next_page" },
   { "kP", "prev_page" },
   { "kr", "right" },
   { "ku", "up" },
   { "kT", "tab" },
   /*{{{  function-keys 0..63*/
   { "k0", "f0" },
   { "k1", "f1" },
   { "k2", "f2" },
   { "k3", "f3" },
   { "k4", "f4" },
   { "k5", "f5" },
   { "k6", "f6" },
   { "k7", "f7" },
   { "k8", "f8" },
   { "k9", "f9" },
   { "k;", "f10" },
   { "F1", "f11" },
   { "F2", "f12" },
   { "F3", "f13" },
   { "F4", "f14" },
   { "F5", "f15" },
   { "F6", "f16" },
   { "F7", "f17" },
   { "F8", "f18" },
   { "F9", "f19" },
   { "FA", "f20" },
   { "FB", "f21" },
   { "FC", "f22" },
   { "FD", "f23" },
   { "FE", "f24" },
   { "FF", "f25" },
   { "FG", "f26" },
   { "FH", "f27" },
   { "FI", "f28" },
   { "FJ", "f29" },
   { "FK", "f30" },
   { "FL", "f31" },
   { "FM", "f32" },
   { "FN", "f33" },
   { "FO", "f34" },
   { "FP", "f35" },
   { "FQ", "f36" },
   { "FR", "f37" },
   { "FS", "f38" },
   { "FT", "f39" },
   { "FU", "f40" },
   { "FV", "f41" },
   { "FW", "f42" },
   { "FX", "f43" },
   { "FY", "f44" },
   { "FZ", "f45" },
   { "Fa", "f46" },
   { "Fb", "f47" },
   { "Fc", "f48" },
   { "Fd", "f49" },
   { "Fe", "f50" },
   { "Ff", "f51" },
   { "Fg", "f52" },
   { "Fh", "f53" },
   { "Fi", "f54" },
   { "Fj", "f55" },
   { "Fk", "f56" },
   { "Fl", "f57" },
   { "Fm", "f58" },
   { "Fn", "f59" },
   { "Fo", "f60" },
   { "Fp", "f61" },
   { "Fq", "f62" },
   { "Fr", "f63" },
   /*}}}  */
   { (char*)0, (char*)0 }
 };
/*}}}  */
/*{{{  create_alias*/
void create_alias(char *name, unsigned char *code)
{
  printf("  (alias %s (",name);
  while (*code)
  {
    if (*code==127) printf(" C-?");
    else if (*code>=' ') printf(" \"%c",*code);
    else printf(" C-%c","@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"[*code]);
    code++;
  }
  printf(" ))\n");
}
/*}}}  */

/*{{{  main*/
void main(int argc, char *argv[])
{
  /*{{{  variable declarations*/
  char termcap_area[1024];
  char bp[1024];
  char term[256];
  char *pointer;
  unsigned char *cap;
  term_alias *run=alias_table;
  int c;
  extern char *optarg;
  extern int optind;
  bool err=FALSE;
  bool no_term=FALSE;
  /*}}}  */

  /*{{{  parse arguments*/
  strcpy(term, getenv("TERM")==(char*)0 ? "" : getenv("TERM"));
  /*{{{  process options*/
  { while ((c=getopt(argc,argv,"nht:"))!=-1)
    switch (c)
    {
      /*{{{  n*/
      case 'n':
      { no_term=TRUE;
        break;
      }
      /*}}}  */
      /*{{{  h*/
      case '?':
      case 'h':
      {
        err=TRUE;
        break;
      }
      /*}}}  */
      /*{{{  t*/
      case 't':
      {
        strcpy(term,optarg);
        break;
      }
      /*}}}  */
    }
  }
  /*}}}  */
  if (term[0]=='\0')
  /*{{{  complain*/
  {
    fprintf(stderr,"autoalias: no environment variable TERM.\n");
    err=TRUE;
  }
  /*}}}  */
  else if (tgetent(bp,term)<=0)
  /*{{{  complain*/
  {
    fprintf(stderr,"autoalias: no termcap entry for %s.\n",term);
    err=TRUE;
  }
  /*}}}  */
  /*{{{  check usage*/
  if (err || optind<argc)
  {
    fprintf(stderr,"Usage: autoalias [-h] [-t terminalname]\n");
    exit(1);
  }
  /*}}}  */
  /*}}}  */
  if (!no_term) printf("(terminal (%s)\n",term);
  pointer=termcap_area;
  while ((run->capability)!=(char*)0)
  {
    if ((cap=(unsigned char*)tgetstr(run->capability,&pointer))!=(unsigned char*)0)
    create_alias(run->alias,cap);
    run++;
  }
  if (!no_term) printf(")\n");
  exit(0);
}
/*}}}  */
