*** empty log message ***
[bpt/emacs.git] / src / abbrev.c
index 723ec1a..bdb8dc6 100644 (file)
@@ -1,12 +1,12 @@
 /* Primitives for word-abbrev mode.
 /* Primitives for word-abbrev mode.
-   Copyright (C) 1985, 1986, 1993, 1996, 1998, 2001
-   Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1993, 1996, 1998, 2001, 2002, 2003, 2004,
+                 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -16,8 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 
 #include <config.h>
 
 
 #include <config.h>
@@ -77,16 +77,19 @@ Lisp_Object Vlast_abbrev_text;
 
 /* Character address of start of last abbrev expanded */
 
 
 /* Character address of start of last abbrev expanded */
 
-int last_abbrev_point;
+EMACS_INT last_abbrev_point;
 
 /* Hook to run before expanding any abbrev.  */
 
 Lisp_Object Vpre_abbrev_expand_hook, Qpre_abbrev_expand_hook;
 
 /* Hook to run before expanding any abbrev.  */
 
 Lisp_Object Vpre_abbrev_expand_hook, Qpre_abbrev_expand_hook;
+
+Lisp_Object Qsystem_type, Qcount, Qforce;
 \f
 DEFUN ("make-abbrev-table", Fmake_abbrev_table, Smake_abbrev_table, 0, 0, 0,
        doc: /* Create a new, empty abbrev table object.  */)
      ()
 {
 \f
 DEFUN ("make-abbrev-table", Fmake_abbrev_table, Smake_abbrev_table, 0, 0, 0,
        doc: /* Create a new, empty abbrev table object.  */)
      ()
 {
+  /* The value 59 is arbitrary chosen prime number.  */
   return Fmake_vector (make_number (59), make_number (0));
 }
 
   return Fmake_vector (make_number (59), make_number (0));
 }
 
@@ -97,36 +100,53 @@ DEFUN ("clear-abbrev-table", Fclear_abbrev_table, Sclear_abbrev_table, 1, 1, 0,
 {
   int i, size;
 
 {
   int i, size;
 
-  CHECK_VECTOR (table, 0);
+  CHECK_VECTOR (table);
   size = XVECTOR (table)->size;
   abbrevs_changed = 1;
   for (i = 0; i < size; i++)
     XVECTOR (table)->contents[i] = make_number (0);
   return Qnil;
 }
   size = XVECTOR (table)->size;
   abbrevs_changed = 1;
   for (i = 0; i < size; i++)
     XVECTOR (table)->contents[i] = make_number (0);
   return Qnil;
 }
-\f
-DEFUN ("define-abbrev", Fdefine_abbrev, Sdefine_abbrev, 3, 5, 0,
+
+DEFUN ("define-abbrev", Fdefine_abbrev, Sdefine_abbrev, 3, 6, 0,
        doc: /* Define an abbrev in TABLE named NAME, to expand to EXPANSION and call HOOK.
        doc: /* Define an abbrev in TABLE named NAME, to expand to EXPANSION and call HOOK.
-NAME must be a string.
+NAME must be a string, and should be lower-case.
 EXPANSION should usually be a string.
 To undefine an abbrev, define it with EXPANSION = nil.
 If HOOK is non-nil, it should be a function of no arguments;
 it is called after EXPANSION is inserted.
 If EXPANSION is not a string, the abbrev is a special one,
  which does not expand in the usual way but only runs HOOK.
 EXPANSION should usually be a string.
 To undefine an abbrev, define it with EXPANSION = nil.
 If HOOK is non-nil, it should be a function of no arguments;
 it is called after EXPANSION is inserted.
 If EXPANSION is not a string, the abbrev is a special one,
  which does not expand in the usual way but only runs HOOK.
-COUNT, if specified, initializes the abbrev's usage-count
-which is incremented each time the abbrev is used.  */)
-     (table, name, expansion, hook, count)
-     Lisp_Object table, name, expansion, hook, count;
+
+COUNT, if specified, gives the initial value for the abbrev's
+usage-count, which is incremented each time the abbrev is used.
+\(The default is zero.)
+
+SYSTEM-FLAG, if non-nil, says that this is a "system" abbreviation
+which should not be saved in the user's abbreviation file.
+Unless SYSTEM-FLAG is `force', a system abbreviation will not
+overwrite a non-system abbreviation of the same name.  */)
+     (table, name, expansion, hook, count, system_flag)
+     Lisp_Object table, name, expansion, hook, count, system_flag;
 {
   Lisp_Object sym, oexp, ohook, tem;
 {
   Lisp_Object sym, oexp, ohook, tem;
-  CHECK_VECTOR (table, 0);
-  CHECK_STRING (name, 1);
+  CHECK_VECTOR (table);
+  CHECK_STRING (name);
+
+  /* If defining a system abbrev, do not overwrite a non-system abbrev
+     of the same name, unless 'force is used. */
+  if (!NILP (system_flag) && !EQ (system_flag, Qforce))
+    {
+      sym = Fintern_soft (name, table);
+
+      if (!NILP (SYMBOL_VALUE (sym)) &&
+          NILP (Fplist_get (XSYMBOL (sym)->plist, Qsystem_type))) return Qnil;
+    }
 
   if (NILP (count))
     count = make_number (0);
   else
 
   if (NILP (count))
     count = make_number (0);
   else
-    CHECK_NUMBER (count, 0);
+    CHECK_NUMBER (count);
 
   sym = Fintern (name, table);
 
 
   sym = Fintern (name, table);
 
@@ -137,12 +157,17 @@ which is incremented each time the abbrev is used.  */)
             && (tem = Fstring_equal (oexp, expansion), !NILP (tem))))
        &&
        (EQ (ohook, hook)
             && (tem = Fstring_equal (oexp, expansion), !NILP (tem))))
        &&
        (EQ (ohook, hook)
-        || (tem = Fequal (ohook, hook), !NILP (tem)))))
+        || (tem = Fequal (ohook, hook), !NILP (tem))))
+      && NILP (system_flag))
     abbrevs_changed = 1;
 
   Fset (sym, expansion);
   Ffset (sym, hook);
     abbrevs_changed = 1;
 
   Fset (sym, expansion);
   Ffset (sym, hook);
-  Fsetplist (sym, count);
+
+  if (! NILP (system_flag))
+    Fsetplist (sym, list4 (Qcount, count, Qsystem_type, system_flag));
+  else
+    Fsetplist (sym, count);
 
   return name;
 }
 
   return name;
 }
@@ -154,7 +179,7 @@ DEFUN ("define-global-abbrev", Fdefine_global_abbrev, Sdefine_global_abbrev, 2,
      Lisp_Object abbrev, expansion;
 {
   Fdefine_abbrev (Vglobal_abbrev_table, Fdowncase (abbrev),
      Lisp_Object abbrev, expansion;
 {
   Fdefine_abbrev (Vglobal_abbrev_table, Fdowncase (abbrev),
-                 expansion, Qnil, make_number (0));
+                 expansion, Qnil, make_number (0), Qnil);
   return abbrev;
 }
 
   return abbrev;
 }
 
@@ -168,7 +193,7 @@ DEFUN ("define-mode-abbrev", Fdefine_mode_abbrev, Sdefine_mode_abbrev, 2, 2,
     error ("Major mode has no abbrev table");
 
   Fdefine_abbrev (current_buffer->abbrev_table, Fdowncase (abbrev),
     error ("Major mode has no abbrev table");
 
   Fdefine_abbrev (current_buffer->abbrev_table, Fdowncase (abbrev),
-                 expansion, Qnil, make_number (0));
+                 expansion, Qnil, make_number (0), Qnil);
   return abbrev;
 }
 
   return abbrev;
 }
 
@@ -183,7 +208,7 @@ The default is to try buffer's mode-specific abbrev table, then global table.  *
      Lisp_Object abbrev, table;
 {
   Lisp_Object sym;
      Lisp_Object abbrev, table;
 {
   Lisp_Object sym;
-  CHECK_STRING (abbrev, 0);
+  CHECK_STRING (abbrev);
   if (!NILP (table))
     sym = Fintern_soft (abbrev, table);
   else
   if (!NILP (table))
     sym = Fintern_soft (abbrev, table);
   else
@@ -225,17 +250,17 @@ Returns the abbrev symbol, if expansion took place.  */)
 {
   register char *buffer, *p;
   int wordstart, wordend;
 {
   register char *buffer, *p;
   int wordstart, wordend;
-  register int wordstart_byte, wordend_byte, idx;
+  register int wordstart_byte, wordend_byte, idx, idx_byte;
   int whitecnt;
   int uccount = 0, lccount = 0;
   register Lisp_Object sym;
   Lisp_Object expansion, hook, tem;
   Lisp_Object value;
   int whitecnt;
   int uccount = 0, lccount = 0;
   register Lisp_Object sym;
   Lisp_Object expansion, hook, tem;
   Lisp_Object value;
+  int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
 
   value = Qnil;
 
 
   value = Qnil;
 
-  if (!NILP (Vrun_hooks))
-    call1 (Vrun_hooks, Qpre_abbrev_expand_hook);
+  Frun_hooks (1, &Qpre_abbrev_expand_hook);
 
   wordstart = 0;
   if (!(BUFFERP (Vabbrev_start_location_buffer)
 
   wordstart = 0;
   if (!(BUFFERP (Vabbrev_start_location_buffer)
@@ -244,7 +269,7 @@ Returns the abbrev symbol, if expansion took place.  */)
   if (!NILP (Vabbrev_start_location))
     {
       tem = Vabbrev_start_location;
   if (!NILP (Vabbrev_start_location))
     {
       tem = Vabbrev_start_location;
-      CHECK_NUMBER_COERCE_MARKER (tem, 0);
+      CHECK_NUMBER_COERCE_MARKER (tem);
       wordstart = XINT (tem);
       Vabbrev_start_location = Qnil;
       if (wordstart < BEGV || wordstart > ZV)
       wordstart = XINT (tem);
       Vabbrev_start_location = Qnil;
       if (wordstart < BEGV || wordstart > ZV)
@@ -277,25 +302,39 @@ Returns the abbrev symbol, if expansion took place.  */)
 
   p = buffer = (char *) alloca (wordend_byte - wordstart_byte);
 
 
   p = buffer = (char *) alloca (wordend_byte - wordstart_byte);
 
-  for (idx = wordstart_byte; idx < wordend_byte; idx++)
+  for (idx = wordstart, idx_byte = wordstart_byte; idx < wordend; )
     {
     {
-      /* ??? This loop needs to go by characters!  */
-      register int c = FETCH_BYTE (idx);
+      register int c;
+
+      if (multibyte)
+       {
+         FETCH_CHAR_ADVANCE (c, idx, idx_byte);
+       }
+      else
+       {
+         c = FETCH_BYTE (idx_byte);
+         idx++, idx_byte++;
+       }
+
       if (UPPERCASEP (c))
        c = DOWNCASE (c), uccount++;
       else if (! NOCASEP (c))
        lccount++;
       if (UPPERCASEP (c))
        c = DOWNCASE (c), uccount++;
       else if (! NOCASEP (c))
        lccount++;
-      *p++ = c;
+      if (multibyte)
+       p += CHAR_STRING (c, p);
+      else
+       *p++ = c;
     }
 
   if (VECTORP (current_buffer->abbrev_table))
     sym = oblookup (current_buffer->abbrev_table, buffer,
     }
 
   if (VECTORP (current_buffer->abbrev_table))
     sym = oblookup (current_buffer->abbrev_table, buffer,
-                   wordend - wordstart, wordend_byte - wordstart_byte);
+                   wordend - wordstart, p - buffer);
   else
     XSETFASTINT (sym, 0);
   else
     XSETFASTINT (sym, 0);
+
   if (INTEGERP (sym) || NILP (SYMBOL_VALUE (sym)))
     sym = oblookup (Vglobal_abbrev_table, buffer,
   if (INTEGERP (sym) || NILP (SYMBOL_VALUE (sym)))
     sym = oblookup (Vglobal_abbrev_table, buffer,
-                   wordend - wordstart, wordend_byte - wordstart_byte);
+                   wordend - wordstart, p - buffer);
   if (INTEGERP (sym) || NILP (SYMBOL_VALUE (sym)))
     return value;
 
   if (INTEGERP (sym) || NILP (SYMBOL_VALUE (sym)))
     return value;
 
@@ -315,9 +354,12 @@ Returns the abbrev symbol, if expansion took place.  */)
   value = sym;
   last_abbrev_point = wordstart;
 
   value = sym;
   last_abbrev_point = wordstart;
 
+  /* Increment use count.  */
   if (INTEGERP (XSYMBOL (sym)->plist))
     XSETINT (XSYMBOL (sym)->plist,
   if (INTEGERP (XSYMBOL (sym)->plist))
     XSETINT (XSYMBOL (sym)->plist,
-            XINT (XSYMBOL (sym)->plist) + 1);  /* Increment use count */
+            XINT (XSYMBOL (sym)->plist) + 1);
+  else if (INTEGERP (tem = Fget (sym, Qcount)))
+    Fput (sym, Qcount, make_number (XINT (tem) + 1));
 
   /* If this abbrev has an expansion, delete the abbrev
      and insert the expansion.  */
 
   /* If this abbrev has an expansion, delete the abbrev
      and insert the expansion.  */
@@ -326,10 +368,13 @@ Returns the abbrev symbol, if expansion took place.  */)
     {
       SET_PT (wordstart);
 
     {
       SET_PT (wordstart);
 
-      del_range_both (wordstart, wordstart_byte, wordend, wordend_byte, 1);
+      insert_from_string (expansion, 0, 0, SCHARS (expansion),
+                         SBYTES (expansion), 1);
+      del_range_both (PT, PT_BYTE,
+                     wordend + (PT - wordstart),
+                     wordend_byte + (PT_BYTE - wordstart_byte),
+                     1);
 
 
-      insert_from_string (expansion, 0, 0, XSTRING (expansion)->size,
-                         STRING_BYTES (XSTRING (expansion)), 1);
       SET_PT (PT + whitecnt);
 
       if (uccount && !lccount)
       SET_PT (PT + whitecnt);
 
       if (uccount && !lccount)
@@ -373,8 +418,8 @@ Returns the abbrev symbol, if expansion took place.  */)
       /* If the abbrev has a hook function, run it.  */
       expanded = call0 (hook);
 
       /* If the abbrev has a hook function, run it.  */
       expanded = call0 (hook);
 
-      /* In addition, if the hook function is a symbol with a a
-        non-nil `no-self-insert' property, let the value it returned
+      /* In addition, if the hook function is a symbol with
+        non-nil `no-self-insert' property, let the value it returned
         specify whether we consider that an expansion took place.  If
         it returns nil, no expansion has been done.  */
 
         specify whether we consider that an expansion took place.  If
         it returns nil, no expansion has been done.  */
 
@@ -409,13 +454,13 @@ is not undone.  */)
 
       val = SYMBOL_VALUE (Vlast_abbrev);
       if (!STRINGP (val))
 
       val = SYMBOL_VALUE (Vlast_abbrev);
       if (!STRINGP (val))
-       error ("value of abbrev-symbol must be a string");
+       error ("Value of `abbrev-symbol' must be a string");
       zv_before = ZV;
       zv_before = ZV;
-      del_range_byte (PT_BYTE, PT_BYTE + STRING_BYTES (XSTRING (val)), 1);
+      del_range_byte (PT_BYTE, PT_BYTE + SBYTES (val), 1);
       /* Don't inherit properties here; just copy from old contents.  */
       insert_from_string (Vlast_abbrev_text, 0, 0,
       /* Don't inherit properties here; just copy from old contents.  */
       insert_from_string (Vlast_abbrev_text, 0, 0,
-                         XSTRING (Vlast_abbrev_text)->size,
-                         STRING_BYTES (XSTRING (Vlast_abbrev_text)), 0);
+                         SCHARS (Vlast_abbrev_text),
+                         SBYTES (Vlast_abbrev_text), 0);
       Vlast_abbrev_text = Qnil;
       /* Total number of characters deleted.  */
       adjust = ZV - zv_before;
       Vlast_abbrev_text = Qnil;
       /* Total number of characters deleted.  */
       adjust = ZV - zv_before;
@@ -428,18 +473,31 @@ static void
 write_abbrev (sym, stream)
      Lisp_Object sym, stream;
 {
 write_abbrev (sym, stream)
      Lisp_Object sym, stream;
 {
-  Lisp_Object name;
-  if (NILP (SYMBOL_VALUE (sym)))
+  Lisp_Object name, count, system_flag;
+
+  if (INTEGERP (XSYMBOL (sym)->plist))
+    {
+      count = XSYMBOL (sym)->plist;
+      system_flag = Qnil;
+    }
+  else
+    {
+      count = Fget (sym, Qcount);
+      system_flag = Fget (sym, Qsystem_type);
+    }
+
+  if (NILP (SYMBOL_VALUE (sym)) || ! NILP (system_flag))
     return;
     return;
+
   insert ("    (", 5);
   insert ("    (", 5);
-  XSETSTRING (name, XSYMBOL (sym)->name);
+  name = SYMBOL_NAME (sym);
   Fprin1 (name, stream);
   insert (" ", 1);
   Fprin1 (SYMBOL_VALUE (sym), stream);
   insert (" ", 1);
   Fprin1 (XSYMBOL (sym)->function, stream);
   insert (" ", 1);
   Fprin1 (name, stream);
   insert (" ", 1);
   Fprin1 (SYMBOL_VALUE (sym), stream);
   insert (" ", 1);
   Fprin1 (XSYMBOL (sym)->function, stream);
   insert (" ", 1);
-  Fprin1 (XSYMBOL (sym)->plist, stream);
+  Fprin1 (count, stream);
   insert (")\n", 2);
 }
 
   insert (")\n", 2);
 }
 
@@ -447,14 +505,34 @@ static void
 describe_abbrev (sym, stream)
      Lisp_Object sym, stream;
 {
 describe_abbrev (sym, stream)
      Lisp_Object sym, stream;
 {
-  Lisp_Object one;
+  Lisp_Object one, count, system_flag;
+
+  if (INTEGERP (XSYMBOL (sym)->plist))
+    {
+      count = XSYMBOL (sym)->plist;
+      system_flag = Qnil;
+    }
+  else
+    {
+      count = Fget (sym, Qcount);
+      system_flag = Fget (sym, Qsystem_type);
+    }
 
   if (NILP (SYMBOL_VALUE (sym)))
     return;
 
   if (NILP (SYMBOL_VALUE (sym)))
     return;
+
   one = make_number (1);
   Fprin1 (Fsymbol_name (sym), stream);
   one = make_number (1);
   Fprin1 (Fsymbol_name (sym), stream);
-  Findent_to (make_number (15), one);
-  Fprin1 (XSYMBOL (sym)->plist, stream);
+
+  if (!NILP (system_flag))
+    {
+      insert_string (" (sys)");
+      Findent_to (make_number (20), one);
+    }
+  else
+    Findent_to (make_number (15), one);
+
+  Fprin1 (count, stream);
   Findent_to (make_number (20), one);
   Fprin1 (SYMBOL_VALUE (sym), stream);
   if (!NILP (XSYMBOL (sym)->function))
   Findent_to (make_number (20), one);
   Fprin1 (SYMBOL_VALUE (sym), stream);
   if (!NILP (XSYMBOL (sym)->function))
@@ -465,32 +543,53 @@ describe_abbrev (sym, stream)
   Fterpri (stream);
 }
 
   Fterpri (stream);
 }
 
+static void
+record_symbol (sym, list)
+     Lisp_Object sym, list;
+{
+  XSETCDR (list, Fcons (sym, XCDR (list)));
+}
+
 DEFUN ("insert-abbrev-table-description", Finsert_abbrev_table_description,
 DEFUN ("insert-abbrev-table-description", Finsert_abbrev_table_description,
-  Sinsert_abbrev_table_description, 1, 2, 0,
+       Sinsert_abbrev_table_description, 1, 2, 0,
        doc: /* Insert before point a full description of abbrev table named NAME.
 NAME is a symbol whose value is an abbrev table.
 If optional 2nd arg READABLE is non-nil, a human-readable description
 is inserted.  Otherwise the description is an expression,
 a call to `define-abbrev-table', which would
        doc: /* Insert before point a full description of abbrev table named NAME.
 NAME is a symbol whose value is an abbrev table.
 If optional 2nd arg READABLE is non-nil, a human-readable description
 is inserted.  Otherwise the description is an expression,
 a call to `define-abbrev-table', which would
-define the abbrev table NAME exactly as it is currently defined.  */)
+define the abbrev table NAME exactly as it is currently defined.
+
+Abbrevs marked as "system abbrevs" are normally omitted.  However, if
+READABLE is non-nil, they are listed.  */)
      (name, readable)
      Lisp_Object name, readable;
 {
   Lisp_Object table;
      (name, readable)
      Lisp_Object name, readable;
 {
   Lisp_Object table;
+  Lisp_Object symbols;
   Lisp_Object stream;
 
   Lisp_Object stream;
 
-  CHECK_SYMBOL (name, 0);
+  CHECK_SYMBOL (name);
   table = Fsymbol_value (name);
   table = Fsymbol_value (name);
-  CHECK_VECTOR (table, 0);
+  CHECK_VECTOR (table);
 
   XSETBUFFER (stream, current_buffer);
 
 
   XSETBUFFER (stream, current_buffer);
 
+  symbols = Fcons (Qnil, Qnil);
+  map_obarray (table, record_symbol, symbols);
+  symbols = XCDR (symbols);
+  symbols = Fsort (symbols, Qstring_lessp);
+
   if (!NILP (readable))
     {
       insert_string ("(");
       Fprin1 (name, stream);
       insert_string (")\n\n");
   if (!NILP (readable))
     {
       insert_string ("(");
       Fprin1 (name, stream);
       insert_string (")\n\n");
-      map_obarray (table, describe_abbrev, stream);
+      while (! NILP (symbols))
+       {
+         describe_abbrev (XCAR (symbols), stream);
+         symbols = XCDR (symbols);
+       }
+
       insert_string ("\n\n");
     }
   else
       insert_string ("\n\n");
     }
   else
@@ -498,7 +597,11 @@ define the abbrev table NAME exactly as it is currently defined.  */)
       insert_string ("(define-abbrev-table '");
       Fprin1 (name, stream);
       insert_string (" '(\n");
       insert_string ("(define-abbrev-table '");
       Fprin1 (name, stream);
       insert_string (" '(\n");
-      map_obarray (table, write_abbrev, stream);
+      while (! NILP (symbols))
+       {
+         write_abbrev (XCAR (symbols), stream);
+         symbols = XCDR (symbols);
+       }
       insert_string ("    ))\n\n");
     }
 
       insert_string ("    ))\n\n");
     }
 
@@ -509,14 +612,15 @@ DEFUN ("define-abbrev-table", Fdefine_abbrev_table, Sdefine_abbrev_table,
        2, 2, 0,
        doc: /* Define TABLENAME (a symbol) as an abbrev table name.
 Define abbrevs in it according to DEFINITIONS, which is a list of elements
        2, 2, 0,
        doc: /* Define TABLENAME (a symbol) as an abbrev table name.
 Define abbrevs in it according to DEFINITIONS, which is a list of elements
-of the form (ABBREVNAME EXPANSION HOOK USECOUNT).  */)
+of the form (ABBREVNAME EXPANSION HOOK USECOUNT SYSTEMFLAG).
+\(If the list is shorter than that, omitted elements default to nil).  */)
      (tablename, definitions)
      Lisp_Object tablename, definitions;
 {
   Lisp_Object name, exp, hook, count;
      (tablename, definitions)
      Lisp_Object tablename, definitions;
 {
   Lisp_Object name, exp, hook, count;
-  Lisp_Object table, elt;
+  Lisp_Object table, elt, sys;
 
 
-  CHECK_SYMBOL (tablename, 0);
+  CHECK_SYMBOL (tablename);
   table = Fboundp (tablename);
   if (NILP (table) || (table = Fsymbol_value (tablename), NILP (table)))
     {
   table = Fboundp (tablename);
   if (NILP (table) || (table = Fsymbol_value (tablename), NILP (table)))
     {
@@ -524,16 +628,17 @@ of the form (ABBREVNAME EXPANSION HOOK USECOUNT).  */)
       Fset (tablename, table);
       Vabbrev_table_name_list = Fcons (tablename, Vabbrev_table_name_list);
     }
       Fset (tablename, table);
       Vabbrev_table_name_list = Fcons (tablename, Vabbrev_table_name_list);
     }
-  CHECK_VECTOR (table, 0);
+  CHECK_VECTOR (table);
 
 
-  for (; !NILP (definitions); definitions = Fcdr (definitions))
+  for (; CONSP (definitions); definitions = XCDR (definitions))
     {
     {
-      elt = Fcar (definitions);
+      elt = XCAR (definitions);
       name  = Fcar (elt);      elt = Fcdr (elt);
       exp   = Fcar (elt);      elt = Fcdr (elt);
       hook  = Fcar (elt);      elt = Fcdr (elt);
       name  = Fcar (elt);      elt = Fcdr (elt);
       exp   = Fcar (elt);      elt = Fcdr (elt);
       hook  = Fcar (elt);      elt = Fcdr (elt);
-      count = Fcar (elt);
-      Fdefine_abbrev (table, name, exp, hook, count);
+      count = Fcar (elt);      elt = Fcdr (elt);
+      sys   = Fcar (elt);
+      Fdefine_abbrev (table, name, exp, hook, count, sys);
     }
   return Qnil;
 }
     }
   return Qnil;
 }
@@ -541,6 +646,15 @@ of the form (ABBREVNAME EXPANSION HOOK USECOUNT).  */)
 void
 syms_of_abbrev ()
 {
 void
 syms_of_abbrev ()
 {
+  Qsystem_type = intern ("system-type");
+  staticpro (&Qsystem_type);
+
+  Qcount = intern ("count");
+  staticpro (&Qcount);
+
+  Qforce = intern ("force");
+  staticpro (&Qforce);
+
   DEFVAR_LISP ("abbrev-table-name-list", &Vabbrev_table_name_list,
               doc: /* List of symbols whose values are abbrev tables.  */);
   Vabbrev_table_name_list = Fcons (intern ("fundamental-mode-abbrev-table"),
   DEFVAR_LISP ("abbrev-table-name-list", &Vabbrev_table_name_list,
               doc: /* List of symbols whose values are abbrev tables.  */);
   Vabbrev_table_name_list = Fcons (intern ("fundamental-mode-abbrev-table"),
@@ -565,7 +679,7 @@ for any particular abbrev defined in both.  */);
 
   DEFVAR_LISP ("last-abbrev-text", &Vlast_abbrev_text,
               doc: /* The exact text of the last abbrev expanded.
 
   DEFVAR_LISP ("last-abbrev-text", &Vlast_abbrev_text,
               doc: /* The exact text of the last abbrev expanded.
-nil if the abbrev has already been unexpanded.  */);
+A value of nil means the abbrev has already been unexpanded.  */);
 
   DEFVAR_INT ("last-abbrev-location", &last_abbrev_point,
              doc: /* The location of the start of the last abbrev expanded.  */);
 
   DEFVAR_INT ("last-abbrev-location", &last_abbrev_point,
              doc: /* The location of the start of the last abbrev expanded.  */);
@@ -576,7 +690,7 @@ nil if the abbrev has already been unexpanded.  */);
 
   DEFVAR_LISP ("abbrev-start-location", &Vabbrev_start_location,
               doc: /* Buffer position for `expand-abbrev' to use as the start of the abbrev.
 
   DEFVAR_LISP ("abbrev-start-location", &Vabbrev_start_location,
               doc: /* Buffer position for `expand-abbrev' to use as the start of the abbrev.
-nil means use the word before point as the abbrev.
+When nil, use the word before point as the abbrev.
 Calling `expand-abbrev' sets this to nil.  */);
   Vabbrev_start_location = Qnil;
 
 Calling `expand-abbrev' sets this to nil.  */);
   Vabbrev_start_location = Qnil;
 
@@ -617,3 +731,6 @@ the current abbrev table before abbrev lookup happens.  */);
   defsubr (&Sinsert_abbrev_table_description);
   defsubr (&Sdefine_abbrev_table);
 }
   defsubr (&Sinsert_abbrev_table_description);
   defsubr (&Sdefine_abbrev_table);
 }
+
+/* arch-tag: b721db69-f633-44a8-a361-c275acbdad7d
+   (do not change this comment) */