home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / reactivekbd / part01 / rk_button.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-16  |  7.2 KB  |  213 lines

  1. #include "rk_button.h"             
  2. #include "file+rk.h"
  3.  
  4. extern maxk;
  5. extern max_nodes;
  6. extern max_freq;
  7. int maxprime=16*1024;
  8.  
  9.                      /** shared with rk_file/file+rk **/
  10. char   first[MAX_SET],             /* the first letter of each pred */
  11.        context[MAX_CMD_LINE_LENGTH] = "\07",   /* last chars entered */
  12.        old_context[MAX_CMD_LINE_LENGTH] = "\07";
  13. Buffer Buf, CBuf;             /* ptrs into the model k levels  */
  14. char   *prime_file;             /* file to prime from and log to */
  15. int    next_free = 0;             /* index of next free node avail */
  16. long   psize;                 /* # chars to prime from prime_file*/
  17.                      /* zero freqs, maybe overwritten */
  18. static char zero_freq[128] = {         /* by a user supplied $home/file */
  19.   '\n',   ' ',   'e',   's',   't',   'r',   'a',   'l',
  20.    'n',   '.',   'c',   'i',   'm',   'o',   'd',   'h',
  21.    'p',   'u',   'f',   'b',   'w',   'g',   '-',   'y',
  22.    '/',   'v',   'k',   '*',   'x',   '5',   '1',   '2',
  23.    '4',   '>',   'q', '\07',   '3',   'z',   '0',   'j',
  24.    'M',   'I',   '6',  '\'',   'E',   '~',   'A',   ',',
  25.    'S',   'D',   'R',   '?',   'C',   '|',   'B',   'T',
  26.    'P',   'U',   '!',   '_',   '<',   'N',   '8',   '@',
  27.    '&',   '7',  '\\',   '"',   'J',   ')',   '(',   '[',
  28.    ']',   'F',   'L',   ':',   'O',   'K',   '9',   'H',
  29.    '+',   '$',   'W',   'Y',   '=',   'G',   ';',   '^',
  30.    '{',   'X',   'Q',   '#',   '}',   'V',   '%',   'Z',
  31.    '`',  '\b',  '\t', '\26', '\00', '\01', '\02', '\03',
  32.  '\04', '\05', '\06', '\13',  '\f',  '\r', '\16', '\17',
  33.  '\20', '\21', '\22', '\23', '\24', '\25', '\27', '\30',
  34.  '\31', '\32', '\33', '\34', '\35', '\36', '\37','\177',};
  35.  
  36. char *zero_freq_file;
  37.  
  38. static char    pred_set[MAX_SET];    /* flags chars already in first[]*/
  39.  
  40. static NodePtr free_nodes;         /* now use malloc to get at init */
  41. static NodePtr root;             /* the root of the k model trie  */
  42.  
  43. NodePtr create_node() {             /* return ptr to a new node or abort */
  44.     if (next_free >= max_nodes) {
  45.         char *malloc(); NodePtr nptr;
  46.         nptr = (NodePtr) malloc((unsigned) sizeof(Node));
  47.         if (nptr == nil)         /* SHOULD FORGET AND CONTINUE ON */
  48.             abortit ("Out of memory in create_node.\n",-1);
  49.         next_free++;              /* just for show_free_nodes */
  50.             return(nptr);              /* if more are needed   */
  51.     } else  return(&free_nodes[next_free++]); /* first nodes upto MAX */
  52. }
  53.  
  54. NodePtr move_up(nptr, c) NodePtr nptr; char c; {
  55.  
  56.     NodePtr xptr, fxptr, last_ptr, last_fptr; int state;
  57.  
  58.     if (nptr == nil) xptr = nil;
  59.     else {
  60.          if (nptr->up == nil) state = START;
  61.          else {
  62.             fxptr = xptr = nptr->up;  last_fptr = last_ptr = nil;
  63.             state = SCANNING;
  64.             do {
  65.                if (xptr == nil) state = END;
  66.                else {
  67.                   if (fxptr->count > xptr->count) {
  68.              last_fptr = last_ptr;  fxptr = xptr; }
  69.                   if (xptr->value == c) {
  70.                      state = FOUND;
  71.                      if (fxptr != xptr) {
  72.                         if (last_fptr == nil) nptr->up = xptr;
  73.                         else last_fptr->next = xptr;
  74.                         last_ptr->next = xptr->next;  xptr->next = fxptr;
  75.                   }  } else { last_ptr = xptr;  xptr = xptr->next; }
  76.             }  } while (state == SCANNING);
  77.          }
  78.          switch (state) {
  79.          case FOUND:
  80.          if (++(xptr->count) == max_freq) { /* Forgets on halving 1 */
  81.             /*last_fptr =*/ fxptr = nptr->up;
  82.             while (fxptr != nil) {         /* JJD 9-86 */
  83.             fxptr->count++;
  84.             fxptr->count >>= 1;
  85. /* DOESN'T FORGET A NODES SUBTREE NODES YET SO DON'T DO IT */
  86. /* MAY HAcE TO INCREASE max_freq TO REDUCE HALcING & OcERHEAD */
  87. /*             if (fxptr->count == 0) {
  88.                 last_fptr->next = fxptr->next;
  89. write(1,"1/2 free\n",9);
  90.                 Free(fxptr);
  91.                 fxptr = last_fptr->next;
  92.             } else {
  93.                 last_fptr = fxptr; */
  94.                 fxptr = fxptr->next;
  95.             
  96.             }
  97.         }
  98.         break;
  99.          case START: case END:
  100.                xptr = create_node();
  101.                xptr->value = c;  xptr->count = 1;
  102.                xptr->up = xptr->next = nil;
  103.            if (state == START) nptr->up = xptr;
  104.            else last_ptr->next = xptr;
  105.                break;
  106.     }}
  107.     return (xptr);
  108. }
  109.  
  110. find_first(buf) Buffer buf; { /* find 1st char of all pred in context */
  111.  
  112.     int i, order = 0; NodePtr xptr; char *p;
  113.  
  114.         for (p= &pred_set[0]; p< &pred_set[MAX_SET]; p++) *p = '\0';
  115.     for (i=maxk-1; i>=0; i--) {      
  116.         if (buf[i] != nil)
  117.         if (buf[i]->up != nil) {
  118.         xptr = buf[i]->up;
  119.         while (xptr != nil) {
  120.             if (!pred_set[(int)xptr->value]) {
  121.             pred_set[(int)xptr->value]++;
  122.             first[order++] = xptr->value;
  123.             }  
  124.             xptr = xptr->next;
  125.     }   }    }
  126.         for (p= &zero_freq[0]; p< &zero_freq[MAX_SET]; p++)
  127.         if (!pred_set[(int)*p]) first[order++] = *p;
  128. }
  129.  
  130. char first_pred(buf) Buffer buf; {
  131.     int i = maxk-1;
  132.     for (;;) {
  133.     if (buf[i] != nil)
  134.         if (buf[i]->up != nil) return (buf[i]->up->value);
  135.     if (i == 0) return((char)1);
  136.     i--;
  137.     }
  138. }
  139.  
  140. NodePtr scan_up(nptr,c) NodePtr nptr; char c; {
  141.  
  142.     NodePtr xptr;
  143.     if (nptr == nil) return(nil);
  144.     else {
  145.         xptr = nptr->up;
  146.         for (;;) {
  147.             if (xptr == nil) return (nil);
  148.             else if (xptr->value == c) return(xptr);
  149.             else xptr = xptr->next;
  150.     }    }
  151. }
  152.  
  153. init_reactive() {
  154.     double atof(), u;
  155.     register int i; FILE *from, *popen();
  156.     char c, *b, *rindex(), tbuf[256], home[128];
  157.     char cbuf[32+1], *cstart, *cend, *end; int full; long size;
  158.  
  159.                 /* get a bunch of nodes for starters        */
  160.     free_nodes = (NodePtr) malloc((unsigned) (max_nodes * sizeof(Node)));
  161.         if (free_nodes == nil) {
  162.             sprintf (tbuf, "cannot allocate %d nodes.\n", max_nodes);
  163.             abortit (tbuf, -1);
  164.     }
  165.                 /* set up root and pointers into model      */
  166.     CBuf[0] = Buf[0]        = root = create_node();
  167.     root->up    = root->next = nil;
  168.     root->count = 1;
  169.     for (i=1; i<=maxk; i++) Buf[i] = nil;
  170.         if ((from = fopen (zero_freq_file, "r")) != NULL) {
  171.         i = 0;
  172.         while (((int)(c = getc(from))) != EOF) {
  173.             zero_freq[i++] = c;
  174.             if (((int)(c = getc(from))) == EOF) break; /* del NL */
  175.             if (i>127) break;             /* test if okay */
  176.         }
  177.     } /* else use built in zero_freq[] */
  178.                 /* calc amount to prime, sys load dependent*/
  179.     if ((from = popen ("uptime", "r")) != NULL) {
  180.         fgets (tbuf, 128, from);
  181.         b = rindex (tbuf, ':');  b++;
  182.         u = atof(b);
  183.         pclose (from);
  184.     } else u = 1.0;
  185.     if (u > 1.0) psize = (long) ((double)((double) maxprime) / u);
  186.     else         psize = (long) (maxprime);
  187.                 /* if user has .rk.log_file, prime from it */
  188.         if ((from = fopen (prime_file, "r")) != NULL) {
  189.         fseek (from, 0L, 2);        /* find out how long it is */
  190.         size = ftell (from);
  191.         if (size > psize) {            /* prime max chars at end  */
  192.         fseek (from, -psize, 2);           /* start after ^G mark  */
  193. /* on second thought, if not "logged" by rk, may be no ^Gs in the file     */
  194. /*             while ((((int)(c = getc(from))) != EOF) && (c != '\07')) ;*/
  195.         } else rewind (from);
  196.         cstart = cend = cbuf; end = &cbuf[maxk]; full = 0;
  197.         while (((int)(c = getc(from))) != EOF) {
  198.         *cstart = c;
  199.         if (full) { ++cstart; if (cstart > end) cstart = cbuf; }
  200.         if (++cend > end) { cend = cbuf; full = 1; }
  201.         *cend = '\0';
  202.             for (i=maxk; i>0; i--) Buf[i] = move_up(Buf[i-1],c);
  203.         }
  204.         i = 0;        /* align the context */
  205.         while (cstart != cend) {
  206.         context[i] = old_context[i] = *cstart++; i++;
  207.         if (cstart > end) cstart = cbuf;
  208.         }
  209.         fclose (from);    
  210.     }
  211. }
  212.  
  213.