home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / jove414s.zip / abbrev.c next >
C/C++ Source or Header  |  1991-07-06  |  7KB  |  309 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. #include "jove.h"
  9.  
  10. #if defined(ABBREV)
  11.  
  12. #include "fp.h"
  13. #include "ctype.h"
  14.  
  15. #if defined(MSDOS)
  16. # include <d:\c600\include\io.h>
  17. #endif
  18. #define HASHSIZE    20
  19.  
  20. struct abbrev {
  21.     unsigned int    a_hash;
  22.     char    *a_abbrev,
  23.         *a_phrase;
  24.     struct abbrev    *a_next;
  25.     data_obj    *a_cmdhook;
  26. };
  27.  
  28. private    void
  29.     define proto((struct abbrev **, char *, char *)),
  30.     rest_abbrevs proto((char *)),
  31.     save_abbrevs proto((char *));
  32.  
  33. private    unsigned int hash proto((char *));
  34.  
  35. #define GLOBAL    NMAJORS
  36. private struct abbrev    *A_tables[NMAJORS + 1][HASHSIZE];    /* Must be zeroed! */
  37.  
  38. int AutoCaseAbbrev = 1;
  39.  
  40. private unsigned int
  41. hash(a)
  42. register  char *a;
  43. {
  44.     register  unsigned int    hashval = 0;
  45.     register  int    c;
  46.  
  47.     while ((c = *a++) != '\0')
  48.         hashval = (hashval << 2) + c;
  49.  
  50.     return hashval;
  51. }
  52.  
  53. private void
  54. def_abbrev(table)
  55. struct abbrev    *table[HASHSIZE];
  56. {
  57.     char    abbrev[100],
  58.         phrase[100];
  59.  
  60.     null_ncpy(abbrev, ask((char *) 0, "abbrev: "), sizeof(abbrev)-1);
  61.     null_ncpy(phrase, ask((char *) 0, "abbrev: %s phrase: ", abbrev),
  62.         sizeof(phrase)-1);
  63.     define(table, abbrev, phrase);
  64. }
  65.  
  66. private struct abbrev *
  67. lookup_abbrev(table, abbrev)
  68. register  struct abbrev    *table[HASHSIZE];
  69. register  char    *abbrev;
  70. {
  71.     register  struct abbrev    *ap;
  72.     unsigned int    h;
  73.  
  74.     h = hash(abbrev);
  75.     for (ap = table[h % HASHSIZE]; ap; ap = ap->a_next)
  76.         if (ap->a_hash == h && strcmp(ap->a_abbrev, abbrev) == 0)
  77.             break;
  78.     return ap;
  79. }
  80.  
  81. private void
  82. define(table, abbrev, phrase)
  83. register  struct abbrev    *table[HASHSIZE];
  84. char    *abbrev,
  85.     *phrase;
  86. {
  87.     register  struct abbrev    *ap;
  88.  
  89.     ap = lookup_abbrev(table, abbrev);
  90.     if (ap == 0) {
  91.         register  unsigned int    h = hash(abbrev);
  92.  
  93.         ap = (struct abbrev *) emalloc(sizeof *ap);
  94.         ap->a_hash = h;
  95.         ap->a_abbrev = copystr(abbrev);
  96.         h %= HASHSIZE;
  97.         ap->a_next = table[h];
  98.         ap->a_cmdhook = 0;
  99.         table[h] = ap;
  100.     } else
  101.         free(ap->a_phrase);
  102.     ap->a_phrase = copystr(phrase);
  103. }
  104.  
  105. void
  106. AbbrevExpand()
  107. {
  108.     Bufpos    point;
  109.     char    wordbuf[100];
  110.     register  char    *wp = wordbuf,
  111.             *cp;
  112. #if !(defined(IBMPC) || defined(MAC))
  113.     register  int    c;
  114. #else
  115.     int c;
  116. #endif
  117.     int    UC_count = 0;
  118.     struct abbrev    *ap;
  119.  
  120.     DOTsave(&point);
  121.     WITH_TABLE(curbuf->b_major)
  122.     b_word(1);
  123.     while (curchar < point.p_char && ismword(c = linebuf[curchar])) {
  124.         if (AutoCaseAbbrev) {
  125.             if (isupper(c)) {
  126.                 UC_count += 1;
  127. #if (defined(IBMPC) || defined(MAC))
  128.                 lower((char *) &c);
  129. #else
  130.                 c = tolower(c);
  131. #endif
  132.             }
  133.         }
  134.         *wp++ = c;
  135.         curchar += 1;
  136.     }
  137.     *wp = '\0';
  138.     END_TABLE();
  139.  
  140.     if ((ap = lookup_abbrev(A_tables[curbuf->b_major], wordbuf)) == 0 &&
  141.         (ap = lookup_abbrev(A_tables[GLOBAL], wordbuf)) == 0) {
  142.         SetDot(&point);
  143.         return;
  144.     }
  145.     del_char(BACKWARD, (wp - wordbuf), NO);
  146.  
  147.     for (cp = ap->a_phrase; (c = *cp) != '\0'; ) {
  148.         if (AutoCaseAbbrev) {
  149.             insert_c(islower(c) && UC_count &&
  150.                    (cp == ap->a_phrase || (UC_count > 1 && (cp[-1] == ' '))) ?
  151.                 toupper(c) : c, 1);
  152.         } else
  153.             insert_c(c, 1);
  154.         cp += 1;
  155.     }
  156.     if (ap->a_cmdhook != 0)
  157.         ExecCmd(ap->a_cmdhook);
  158. }
  159.  
  160. private char    *mode_names[NMAJORS + 1] = {
  161.     "Fundamental Mode",
  162.     "Text Mode",
  163.     "C Mode",
  164. #if defined(LISP)
  165.     "Lisp Mode",
  166. #endif
  167.     "Global"
  168. };
  169.  
  170. private void
  171. save_abbrevs(file)
  172. char    *file;
  173. {
  174.     File    *fp;
  175.     struct abbrev    *ap,
  176.             **tp;
  177.     char    buf[LBSIZE];
  178.     int    i,
  179.         count = 0;
  180.  
  181.     fp = open_file(file, buf, F_WRITE, YES, YES);
  182.     for (i = 0; i <= GLOBAL; i++) {
  183.         fwritef(fp, "------%s abbrevs------\n", mode_names[i]);
  184.         for (tp = A_tables[i]; tp < &A_tables[i][HASHSIZE]; tp++)
  185.             for (ap = *tp; ap; ap = ap->a_next) {
  186.                 fwritef(fp, "%s:%s\n",
  187.                     ap->a_abbrev,
  188.                     ap->a_phrase);
  189.                 count += 1;
  190.             }
  191.     }
  192.     f_close(fp);
  193.     add_mess(" %d written.", count);
  194. }
  195.  
  196. private void
  197. rest_abbrevs(file)
  198. char    *file;
  199. {
  200.     int    eof = 0,
  201.         mode = -1,    /* Will be ++'d immediately */
  202.         lnum = 0;
  203.     char    *phrase_p;
  204.     File    *fp;
  205.     char    buf[LBSIZE];
  206.  
  207.     fp = open_file(file, buf, F_READ, YES, YES);
  208.     while (mode <= GLOBAL) {
  209.         eof = f_gets(fp, genbuf, (size_t) LBSIZE);
  210.         if (eof || genbuf[0] == '\0')
  211.             break;
  212.         lnum += 1;
  213.         if (strncmp(genbuf, "------", (size_t)6) == 0) {
  214.             mode += 1;
  215.             continue;
  216.         }
  217.         if (mode == -1)
  218. fmterr:            complain("Abbrev. format error, line %d.", file, lnum);
  219.         phrase_p = strchr(genbuf, ':');
  220.         if (phrase_p == 0)
  221.             goto fmterr;
  222.         *phrase_p++ = '\0';    /* Null terminate the abbrev. */
  223.         define(A_tables[mode], genbuf, phrase_p);
  224.     }
  225.     f_close(fp);
  226.     message(NullStr);
  227. }
  228.  
  229. void
  230. DefGAbbrev()
  231. {
  232.     def_abbrev(A_tables[GLOBAL]);
  233. }
  234.  
  235. void
  236. DefMAbbrev()
  237. {
  238.     def_abbrev(A_tables[curbuf->b_major]);
  239. }
  240.  
  241. void
  242. SaveAbbrevs()
  243. {
  244.     char    filebuf[FILESIZE];
  245.  
  246.     save_abbrevs(ask_file((char *) 0, (char *) 0, filebuf));
  247. }
  248.  
  249. void
  250. RestAbbrevs()
  251. {
  252.     char    filebuf[FILESIZE];
  253.  
  254.     rest_abbrevs(ask_file((char *) 0, (char *) 0, filebuf));
  255. }
  256.  
  257. void
  258. EditAbbrevs()
  259. {
  260.     char    *tname = "jove_wam.$$$",
  261.         *EditName = "Abbreviation Edit";
  262.     Buffer    *obuf = curbuf,
  263.         *ebuf;
  264.  
  265.     if ((ebuf = buf_exists(EditName)) != NIL) {
  266.         if (ebuf->b_type != B_SCRATCH)
  267.             confirm("Over-write buffer %b?", ebuf);
  268.     }
  269.     SetBuf(ebuf = do_select(curwind, EditName));
  270.     ebuf->b_type = B_SCRATCH;
  271.     initlist(ebuf);
  272.     /* Empty buffer.  Save the definitions to a tmp file
  273.        and read them into this buffer so we can edit them. */
  274.     save_abbrevs(tname);
  275.     read_file(tname, NO);
  276.     message("[Edit definitions and then type C-X C-C]");
  277.     Recur();        /* We edit them ... now */
  278.     /* RESetBuf in case we deleted the buffer while we were editing. */
  279.     SetBuf(ebuf = do_select(curwind, EditName));
  280.     if (IsModified(ebuf)) {
  281.         SetBuf(ebuf);
  282.         file_write(tname, 0);
  283.         rest_abbrevs(tname);
  284.     }
  285.     (void) unlink(tname);
  286.     SetBuf(do_select(curwind, obuf->b_name));
  287. }
  288.  
  289. void
  290. BindMtoW()
  291. {
  292.     struct abbrev    *ap;
  293.     char    *word;
  294.     data_obj    *hook;
  295.  
  296.     word = ask((char *) 0, "Word: ");
  297.  
  298.     if ((ap = lookup_abbrev(A_tables[curbuf->b_major], word)) == 0 &&
  299.         (ap = lookup_abbrev(A_tables[GLOBAL], word)) == 0)
  300.         complain("%s: unknown abbrev.", word);
  301.  
  302.     hook = findmac("Macro: ");
  303.     if (hook == 0)
  304.         complain("[Undefined macro]");
  305.     ap->a_cmdhook = hook;
  306. }
  307.  
  308. #endif /* ABBREV */
  309.