home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / Origami / Sources / src / lib / refcomp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  5.9 KB  |  238 lines

  1. /*{{{}}}*/
  2. /*{{{  includes*/
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7.  
  8. #define REF_INIT_DECOMP
  9.  
  10. #include <h/keys.h>
  11. #include <h/token.h>
  12. #include <h/rcformat.h>
  13. #include <lib/ori_bool.h>
  14. #include <lib/ori_rc_lib.h>
  15. #include <lib/ori_add_lib.h>
  16. /*}}}  */
  17.  
  18. /*{{{  variables*/
  19. static char *ref_comp_words=0;
  20. static int ref_code_word_count=0;
  21. static int ref_code_lg=0;
  22. /*}}}  */
  23.  
  24. /*{{{  ref_compress_text*/
  25. void ref_compress_text(unsigned char *input)
  26. {
  27.   if (input[0])
  28.    /*{{{  compress words and sequences*/
  29.    { unsigned char *s,*line,cur,cur_1,cur_2,cur_3;
  30.  
  31.      s=line=input;
  32.    new_init:
  33.      cur_1=s[0];
  34.      cur_2=cur_1?s[1]:'\0';
  35.      cur_3=cur_2?s[2]:'\0';
  36.      while ((cur=cur_1))
  37.       {
  38.         /*{{{  shift chars, and get next one*/
  39.         cur_1=cur_2;cur_2=cur_3;cur_3=cur_2?(++s)[2]:'\0';
  40.         /*}}}  */
  41.         if (cur_1==cur && cur_2==cur && (cur==' ' || cur_2==cur))
  42.          /*{{{  compress sequence*/
  43.          { int l;
  44.  
  45.            for (l=1;(*s==cur) && (++l<REF_MODULO);s++);
  46.            if (cur==' ')
  47.               *line++=REF_CODE_SPACES;
  48.            else
  49.             { *line++=REF_CODE_CHARS;
  50.               *line++=cur;
  51.             }
  52.            *line++=REF_COUNT_BASE+l;
  53.            goto new_init;
  54.          }
  55.          /*}}}  */
  56.         else
  57.          /*{{{  code word/pattern*/
  58.          { if (isalpha(cur))
  59.             /*{{{  search word*/
  60.             { int i;
  61.               char *w;
  62.               char cmp_c;
  63.  
  64.               cmp_c=tolower(cur);
  65.               for (w=ref_comp_words,i=0;;i++)
  66.                  if (i>=ref_code_word_count)
  67.                     goto simple_code;
  68.                  else
  69.                   { int lw;
  70.  
  71.                     lw=w[0];
  72.                     if
  73.                      /*{{{  positions matches current list word*/
  74.                      (w[1]==cmp_c && !strncmp(w+2,(char*)s,lw-1))
  75.                      /*}}}  */
  76.                      /*{{{  code special word*/
  77.                      {
  78.                        /*{{{  add code of the word*/
  79.                        *line++=(cur==(unsigned char)w[1])
  80.                                  ? REF_CODE_LWORD
  81.                                  : REF_CODE_UWORD;
  82.                        *line++=REF_COUNT_BASE+i;
  83.                        /*}}}  */
  84.                        /*{{{  skip word in source*/
  85.                        s+=lw-1;
  86.                        /*}}}  */
  87.                        goto new_init;
  88.                      }
  89.                      /*}}}  */
  90.                     /*{{{  skip current list word*/
  91.                     w+=lw+1;
  92.                     /*}}}  */
  93.                   }
  94.             }
  95.             /*}}}  */
  96.            else
  97.             /*{{{  simple code*/
  98.             { simple_code:
  99.  
  100.               if (cur=='C' && cur_1=='-')
  101.                /*{{{  ctrl-mark*/
  102.                { *line++=REF_CODE_C;
  103.                  s++;
  104.                  goto new_init;
  105.                }
  106.                /*}}}  */
  107.               else if (cur=='M' && cur_1=='-')
  108.                /*{{{  meta-mark*/
  109.                { *line++=REF_CODE_M;
  110.                  s++;
  111.                  goto new_init;
  112.                }
  113.                /*}}}  */
  114.               else
  115.                /*{{{  single char*/
  116.                  *line++=cur;
  117.                /*}}}  */
  118.             }
  119.             /*}}}  */
  120.          }
  121.          /*}}}  */
  122.       }
  123.     *line='\0';
  124.    }
  125.    /*}}}  */
  126. }
  127. /*}}}  */
  128. /*{{{  ref_put_comp_data*/
  129. void ref_put_comp_data(FILE *f)
  130. {
  131.   int l;
  132.   char *s;
  133.  
  134.   rc_put_c(RC_REF_COMP_STR,f);
  135.   rc_put_w(ref_code_lg,f);
  136.   for (l=ref_code_word_count,s=ref_comp_words;l;l--)
  137.    { int i;
  138.  
  139.      for (i= *s++;i;i--)
  140.         rc_put_c(*s++,f);
  141.      rc_put_c('\0',f);
  142.    }
  143. }
  144. /*}}}  */
  145. /*{{{  ref_add_word*/
  146. boolean ref_add_word(char *word)
  147. {
  148.   if (ref_code_word_count<O_NOP-REF_COUNT_BASE && isalpha(*word))
  149.    { int l;
  150.  
  151.      for (l=1;;l++)
  152.       { char c;
  153.  
  154.         if (isalnum(c=word[l]))
  155.            continue;
  156.         else if (c!='\0' || l<3 || l>=O_NOP)
  157.            break;
  158.         else
  159.          { char *w;
  160.            int i;
  161.          
  162.            for
  163.             ( i=ref_code_word_count,w=ref_comp_words,c=tolower(word[0])
  164.             ;
  165.             ; i--
  166.             )
  167.               if (i==0)
  168.                /*{{{  add it*/
  169.                {
  170.                  /*{{{  realloc the old words*/
  171.                  { char *s;
  172.                    
  173.                    if (!(s=ORImalloc(ref_code_lg+l+1)))
  174.                       return(True);
  175.                    if (ref_code_word_count)
  176.                     { memcpy(s,ref_comp_words,ref_code_lg);
  177.                       ORIfree(ref_comp_words);
  178.                     }
  179.                    ref_comp_words=s;
  180.                  }
  181.                  /*}}}  */
  182.                  /*{{{  apppend length of word*/
  183.                  ref_comp_words[ref_code_lg++]=l;
  184.                  /*}}}  */
  185.                  /*{{{  append new word, first char lowercase*/
  186.                  memcpy(ref_comp_words+ref_code_lg,word,l);
  187.                  ref_comp_words[ref_code_lg]=c;
  188.                  ref_code_lg+=l;
  189.                  /*}}}  */
  190.                  ref_code_word_count++;
  191.                  break;
  192.                }
  193.                /*}}}  */
  194.               else if (w[1]==c && l==w[0]  && !memcmp(w+2,word+1,l-1))
  195.                /*{{{  already in list*/
  196.                  break;
  197.                /*}}}  */
  198.               else
  199.                /*{{{  skip to next list entry*/
  200.                  w+=w[0]+1;
  201.                /*}}}  */
  202.            break;
  203.          }
  204.       }
  205.    }
  206.  
  207.   return(False);
  208. }
  209. /*}}}  */
  210. /*{{{  ref_init_comp_data*/
  211. boolean ref_init_comp_data(int init)
  212. {
  213.   if (ref_comp_words)
  214.    /*{{{  set empty list*/
  215.    { ORIfree(ref_comp_words);
  216.      ref_comp_words=0;
  217.      ref_code_lg=0;
  218.    }
  219.    /*}}}  */
  220.   ref_code_word_count=0;
  221.   if (init)
  222.    /*{{{  init with default words*/
  223.    { static char *list[]=REF_INIT_WORD_LIST;
  224.      char **wp;
  225.  
  226.      for (wp=list;*wp;wp++)
  227.       { if (ref_add_word(*wp))
  228.            return(True);
  229.         else
  230.            continue;
  231.       }
  232.    }
  233.    /*}}}  */
  234.   return(False);
  235.   "="; /* SUNOS4.1.2 needs this, don't ask why :-) */
  236. }
  237. /*}}}  */
  238.