This is abbrev.c in view mode; [Download] [Up]
#include <config.h> #include <stdio.h> #include <string.h> #include "buffer.h" #include "abbrev.h" #include "text.h" #include "ledit.h" #include "ins.h" #include "cmds.h" #include "misc.h" #ifdef HAS_ABBREVS #ifdef pc_system #define MAX_ABBREVS 48 #else #define MAX_ABBREVS 256 #endif #define MAX_ABBREV_LEN 48 #define MAX_ABBREV_TABLES 10 typedef struct Abbrev_Table_Type { int len; /* current length of abbrev */ int empty; /* number of cell known to be empty */ char abbrevs [MAX_ABBREVS][MAX_ABBREV_LEN]; /* formatted as abbrev\0expansion */ char word_chars[256]; /* word delimiters */ char name[16]; /* name of table */ } Abbrev_Table_Type; static Abbrev_Table_Type *Global_Abbrev_Table; static Abbrev_Table_Type *Abbrev_Tables [MAX_ABBREV_TABLES]; int expand_abbrev (unsigned char ch) { Abbrev_Table_Type *tbl; int len, i; unsigned char *p; char *abbrev; if ((i = CBuf->abbrev_table_handle) == -1) tbl = NULL; else tbl = Abbrev_Tables [i]; if (tbl == NULL) { tbl = Global_Abbrev_Table; if (tbl == NULL) return 0; } if (tbl->len == 0) return 0; if (tbl->word_chars[(int) ch]) return 0; /* not a delimiter */ p = CLine->data + (Point - 1); while ((p >= CLine->data) && (tbl->word_chars[(int) *p])) { p--; } p++; len = (int) ((CLine->data + Point) - p); if ((len == 0) || (len >= MAX_ABBREV_LEN / 2)) return 0; /* It makes no sense to have an abbrev larger than its expansion! */ ch = *p; for (i = 0; i < tbl->len; i++) { abbrev = tbl->abbrevs [i]; if ((*abbrev == (char) ch) && (abbrev[len] == 0) && (0 == strncmp (abbrev, (char *) p, len))) { Point -= len; abbrev += len + 1; deln (&len); len = strlen (abbrev); if (CBuf->flags & OVERWRITE_MODE) { deln (&len); /* this does not delete across lines */ } ins_chars ((unsigned char *) abbrev, len); return 1; } } return 0; } static Abbrev_Table_Type *find_table (char *name, int *loc, int err) { Abbrev_Table_Type **tbl, **max; Abbrev_Table_Type **empty_tbl = NULL; tbl = Abbrev_Tables; max = tbl + MAX_ABBREV_TABLES; while (tbl < max) { if (*tbl == NULL) { if (empty_tbl == NULL) empty_tbl = tbl; } else if (strcmp (name, (*tbl)->name) == 0) { break; } tbl++; } *loc = (int) (tbl - Abbrev_Tables); if (tbl == max) { if (empty_tbl != NULL) *loc = (int) (empty_tbl - Abbrev_Tables); if (err) msg_error ("Table does not exist."); return NULL; } return *tbl; } void create_abbrev_table (char *name, char *word_chars) { Abbrev_Table_Type *tbl; int loc; tbl = find_table (name, &loc, 0); if (tbl == NULL) { if (loc == MAX_ABBREV_TABLES) { msg_error ("Abbrev Table Quota reached."); return; } tbl = (Abbrev_Table_Type *) SLMALLOC (sizeof (Abbrev_Table_Type)); if (tbl == NULL) { msg_error ("Malloc error."); return; } Abbrev_Tables [loc] = tbl; } MEMSET ((char *) tbl, 0, sizeof (Abbrev_Table_Type)); if (*word_chars == 0) word_chars = Jed_Word_Range; SLmake_lut ((unsigned char *) tbl->word_chars, (unsigned char *) word_chars, 0); strncpy (tbl->name, name, 15); /* The null char is here because of * the MEMSET */ if (strcmp (name, "Global") == 0) Global_Abbrev_Table = tbl; } void delete_abbrev_table (char *name) { Abbrev_Table_Type *tbl; int n; Buffer *b; tbl = find_table (name, &n, 1); if (tbl == NULL) return; SLFREE (tbl); Abbrev_Tables[n] = NULL; if (tbl == Global_Abbrev_Table) Global_Abbrev_Table = NULL; b = CBuf; do { if (b->abbrev_table_handle == n) b->abbrev_table_handle = -1; b = b->next; } while (b != CBuf); } void define_abbrev (char *table, char *abbrev, char *expans) { Abbrev_Table_Type *tbl; int len, lena; int i; char *a; tbl = find_table (table, &len, 1); if (tbl == NULL) return; if (tbl->len == MAX_ABBREVS) return; /* silently return */ lena = strlen (abbrev); len = lena + strlen (expans) + 1; if (len >= MAX_ABBREV_LEN) { msg_error ("Expansion is too long."); } for (i = 0; i < MAX_ABBREVS; i++) { a = tbl->abbrevs[i]; if ((*a == 0) || ((a[lena] == 0) && (0 == strcmp (a, abbrev)))) { strcpy (a, abbrev); strcpy (a + lena + 1, expans); tbl->len++; return; } } } void use_abbrev_table (char *name) { Abbrev_Table_Type *tbl; int loc; tbl = find_table (name, &loc, 1); if (tbl == NULL) return; CBuf->abbrev_table_handle = loc; } int abbrev_table_p (char *name) { int loc; if (find_table (name, &loc, 0) != NULL) return 1; return 0; } static void push_word (Abbrev_Table_Type *tbl) { char buf[256], *b, *w; int i, in_range; b = buf; w = tbl->word_chars; if (w[(unsigned char) '-'] != 0) *b++ = '-'; in_range = 0; for (i = 33; i < 256; i++) { if ((i != '-') && (0 != w[i])) { if (i == '\\') *b++ = (char) i; *b = (char) i; if (in_range == 0) { *(b + 1) = '-'; b += 2; *b = 0; in_range = 1; } } else { if (in_range) { if (*b == 0) b--; else b++; in_range = 0; } } } *b = 0; SLang_push_string (buf); } void what_abbrev_table (void) { Abbrev_Table_Type *tbl; int i; char *w = ""; if ((i = CBuf->abbrev_table_handle) == -1) tbl = NULL; else tbl = Abbrev_Tables [i]; if (tbl == NULL) tbl = Global_Abbrev_Table; if (tbl == NULL) { SLang_push_string (w); SLang_push_string (w); } else { SLang_push_string (tbl->name); push_word (tbl); } } void dump_abbrev_table (char *name) { Abbrev_Table_Type *tbl; char *abbrev; int i, len; if (NULL == (tbl = find_table (name, &len, 1))) return; len = tbl->len; for (i = 0; i < len; i++) { abbrev = tbl->abbrevs [i]; if (*abbrev) { insert_string (abbrev); ins ('\t'); insert_string (abbrev + (1 + strlen (abbrev))); newline (); } } push_word (tbl); } int list_abbrev_tables (void) { int n = 0; Abbrev_Table_Type **tbl, **max; tbl = Abbrev_Tables; max = tbl + MAX_ABBREV_TABLES; while ((tbl < max) && (*tbl != NULL)) { n++; SLang_push_string ((*tbl)->name); tbl++; } return n; } #endif /* HAS_ABBREVS */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.