home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / JED / JED097-1.TAR / jed / src / abbrev.c next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  6.5 KB  |  341 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. #include "config.h"
  5. #include "buffer.h"
  6. #include "abbrev.h"
  7. #include "text.h"
  8. #include "ledit.h"
  9. #include "ins.h"
  10. #include "cmds.h"
  11. #include "misc.h"
  12.  
  13.  
  14. #ifdef HAS_ABBREVS
  15.  
  16. #ifdef pc_system
  17. #define MAX_ABBREVS 48
  18. #else 
  19. #define MAX_ABBREVS 256
  20. #endif
  21.  
  22. #define MAX_ABBREV_LEN 48
  23. #define MAX_ABBREV_TABLES 10
  24. typedef struct Abbrev_Table_Type
  25. {
  26.    int len;                   /* current length of abbrev */
  27.    int empty;                   /* number of cell known to be empty */
  28.    char abbrevs [MAX_ABBREVS][MAX_ABBREV_LEN];
  29.                        /* formatted as abbrev\0expansion */
  30.    char word_chars[256];           /* word delimiters */
  31.    char name[16];               /* name of table */
  32. }
  33. Abbrev_Table_Type;
  34.  
  35. static Abbrev_Table_Type *Global_Abbrev_Table;
  36. static Abbrev_Table_Type *Abbrev_Tables [MAX_ABBREV_TABLES];
  37. int expand_abbrev (unsigned char ch)
  38. {
  39.    Abbrev_Table_Type *tbl;
  40.    int len, i;
  41.    unsigned char *p;
  42.    char *abbrev;
  43.    
  44.    if ((i = CBuf->abbrev_table_handle) == -1) tbl = NULL;
  45.    else tbl = Abbrev_Tables [i];
  46.  
  47.    if (tbl == NULL) 
  48.      {
  49.     tbl = Global_Abbrev_Table;
  50.     if (tbl == NULL) return 0;
  51.      }
  52.    
  53.    if (tbl->len == 0) return 0;
  54.    
  55.    
  56.    if (tbl->word_chars[(int) ch]) return 0;   /* not a delimiter */
  57.  
  58.    p = CLine->data + (Point - 1);
  59.    
  60.    while ((p >= CLine->data) && (tbl->word_chars[(int) *p]))
  61.      {
  62.     p--;
  63.      }
  64.    p++;
  65.    
  66.    len = (int) ((CLine->data + Point) - p);
  67.    if ((len == 0) || (len >= MAX_ABBREV_LEN / 2)) return 0;
  68.    /* It makes no sense to have an abbrev larger than its expansion! */
  69.    
  70.    ch = *p;
  71.    for (i = 0; i < tbl->len; i++)
  72.      {
  73.     abbrev = tbl->abbrevs [i];
  74.     if ((*abbrev == (char) ch) && (abbrev[len] == 0) && 
  75.         (0 == strncmp (abbrev, (char *) p, len)))
  76.       {
  77.          Point -= len;
  78.          abbrev += len + 1;
  79.          deln (&len);
  80.          len = strlen (abbrev);
  81.          if (CBuf->flags & OVERWRITE_MODE)
  82.            {
  83.           deln (&len);           /* this does not delete across lines */
  84.            }
  85.          ins_chars ((unsigned char *) abbrev, len);
  86.          return 1;
  87.       }
  88.      }
  89.    return 0;
  90. }
  91.  
  92.  
  93.  
  94. static Abbrev_Table_Type *find_table (char *name, int *loc, int err)
  95. {
  96.    Abbrev_Table_Type **tbl, **max;
  97.    Abbrev_Table_Type **empty_tbl = NULL;
  98.    
  99.    tbl = Abbrev_Tables;
  100.    max = tbl + MAX_ABBREV_TABLES;
  101.    
  102.    while (tbl < max)
  103.      {
  104.     if (*tbl == NULL)
  105.       {
  106.          if (empty_tbl == NULL) empty_tbl = tbl;
  107.       }
  108.     else if (strcmp (name, (*tbl)->name) == 0)
  109.       {
  110.          break;
  111.       }
  112.     tbl++;
  113.      }
  114.    *loc = (int) (tbl - Abbrev_Tables);
  115.    if (tbl == max) 
  116.      {
  117.     if (empty_tbl != NULL) *loc = (int) (empty_tbl - Abbrev_Tables);
  118.     if (err) msg_error ("Table does not exist.");
  119.     return NULL;
  120.      }
  121.    return *tbl;
  122. }
  123.  
  124.  
  125. void create_abbrev_table (char *name, char *word_chars)
  126. {
  127.    Abbrev_Table_Type *tbl;
  128.    int loc;
  129.    
  130.    tbl = find_table (name, &loc, 0);
  131.    if (tbl == NULL)
  132.      {
  133.     if (loc == MAX_ABBREV_TABLES) 
  134.       {
  135.          msg_error ("Abbrev Table Quota reached.");
  136.          return;
  137.       }
  138.     
  139.     tbl = (Abbrev_Table_Type *) SLMALLOC (sizeof (Abbrev_Table_Type));
  140.     if (tbl == NULL)
  141.       {
  142.          msg_error ("Malloc error.");
  143.          return;
  144.       }
  145.     
  146.     Abbrev_Tables [loc] = tbl;
  147.      }
  148.    
  149.    MEMSET ((char *) tbl, 0, sizeof (Abbrev_Table_Type));
  150.    
  151.    if (*word_chars == 0) word_chars = Jed_Word_Range;
  152.    
  153.    jed_make_lut ((unsigned char *) tbl->word_chars, (unsigned char *) word_chars, 0);
  154.    
  155.    strncpy (tbl->name, name, 15);      /* The null char is here because of
  156.                     * the MEMSET
  157.                     */
  158.    
  159.    if (strcmp (name, "Global") == 0) Global_Abbrev_Table = tbl;
  160. }
  161.  
  162. void delete_abbrev_table (char *name)
  163. {
  164.    Abbrev_Table_Type *tbl;
  165.    int n;
  166.    Buffer *b;
  167.    
  168.    tbl = find_table (name, &n, 1);
  169.    if (tbl == NULL) return;
  170.    
  171.    SLFREE (tbl);
  172.    Abbrev_Tables[n] = NULL;
  173.    if (tbl == Global_Abbrev_Table) Global_Abbrev_Table = NULL;
  174.    b = CBuf;
  175.    do
  176.      {
  177.     if (b->abbrev_table_handle == n) b->abbrev_table_handle = -1;
  178.     b = b->next;
  179.      }
  180.    while (b != CBuf);
  181. }
  182.  
  183.    
  184. void define_abbrev (char *table, char *abbrev, char *expans)
  185. {
  186.    Abbrev_Table_Type *tbl;
  187.    int len, lena;
  188.    int i;
  189.    char *a;
  190.    
  191.    tbl = find_table (table, &len, 1);
  192.    if (tbl == NULL) return;
  193.    
  194.    if (tbl->len == MAX_ABBREVS) return; /* silently return */
  195.    
  196.    lena = strlen (abbrev);
  197.    len = lena + strlen (expans) + 1;
  198.    
  199.    if (len >= MAX_ABBREV_LEN)
  200.      {
  201.     msg_error ("Expansion is too long.");
  202.      }
  203.    
  204.    for (i = 0; i < MAX_ABBREVS; i++)
  205.      {
  206.     a = tbl->abbrevs[i];
  207.     if ((*a == 0) 
  208.         || ((a[lena] == 0) && (0 == strcmp (a, abbrev))))
  209.       {
  210.          strcpy (a, abbrev);
  211.          strcpy (a + lena + 1, expans);
  212.          tbl->len++;
  213.          return;
  214.       }
  215.      }
  216. }
  217.  
  218.  
  219. void use_abbrev_table (char *name)
  220. {
  221.    Abbrev_Table_Type *tbl;
  222.    int loc;
  223.    
  224.    tbl = find_table (name, &loc, 1);
  225.    if (tbl == NULL) return;
  226.    CBuf->abbrev_table_handle = loc;
  227. }
  228.  
  229. int abbrev_table_p (char *name)
  230. {
  231.    int loc;
  232.    if (find_table (name, &loc, 0) != NULL) return 1;
  233.    return 0;
  234. }
  235.  
  236. static void push_word (Abbrev_Table_Type *tbl)
  237. {
  238.    char buf[256], *b, *w;
  239.    int i, in_range;
  240.    
  241.    b = buf;
  242.    w = tbl->word_chars;
  243.    
  244.    if (w[(unsigned char) '-'] != 0) *b++ = '-';
  245.    in_range = 0;
  246.    
  247.    for (i = 33; i < 256; i++)
  248.      {
  249.     if ((i != '-') && (0 != w[i]))
  250.       {
  251.          if (i == '\\') *b++ = (char) i;
  252.          *b = (char) i;
  253.          if (in_range == 0) 
  254.            {
  255.           *(b + 1) = '-';
  256.           b += 2;  *b = 0;
  257.           in_range = 1;
  258.            }
  259.       }
  260.     else 
  261.       {
  262.          if (in_range) 
  263.            {
  264.           if (*b == 0) b--; else b++;
  265.           in_range = 0;
  266.            }
  267.       }
  268.      }
  269.    *b = 0;
  270.    SLang_push_string (buf);
  271. }
  272.  
  273. void what_abbrev_table (void)
  274. {
  275.    Abbrev_Table_Type *tbl;
  276.    int i;
  277.    char *w = "";
  278.    
  279.    
  280.    if ((i = CBuf->abbrev_table_handle) == -1) tbl = NULL;
  281.    else tbl = Abbrev_Tables [i];
  282.    
  283.    if (tbl == NULL) tbl = Global_Abbrev_Table;
  284.    if (tbl == NULL)
  285.      {
  286.     SLang_push_string (w);
  287.     SLang_push_string (w);
  288.      }
  289.    else 
  290.      {
  291.     SLang_push_string (tbl->name);
  292.     push_word (tbl);
  293.      }
  294. }
  295.  
  296.  
  297.  
  298. void dump_abbrev_table (char *name)
  299. {
  300.    Abbrev_Table_Type *tbl;
  301.    char *abbrev;
  302.    int i, len;
  303.       
  304.    if (NULL == (tbl = find_table (name, &len, 1))) return;
  305.    
  306.    len = tbl->len;
  307.    for (i = 0; i < len; i++)
  308.      {
  309.     abbrev = tbl->abbrevs [i];
  310.     if (*abbrev)
  311.       {
  312.          insert_string (abbrev);
  313.          ins ('\t');
  314.          insert_string (abbrev + (1 + strlen (abbrev)));
  315.          newline ();
  316.       }
  317.      }
  318.    push_word (tbl);
  319. }
  320.  
  321.  
  322. int list_abbrev_tables (void)
  323. {
  324.    int n = 0;         
  325.    Abbrev_Table_Type **tbl, **max;
  326.    
  327.    tbl = Abbrev_Tables;
  328.    max = tbl + MAX_ABBREV_TABLES;
  329.    
  330.    while ((tbl < max) && (*tbl != NULL))
  331.      {
  332.     n++;
  333.     SLang_push_string ((*tbl)->name);
  334.     tbl++;
  335.      }
  336.  
  337.    return n;
  338. }
  339.  
  340. #endif   /* HAS_ABBREVS */
  341.