aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c773
1 files changed, 643 insertions, 130 deletions
diff --git a/src/data.c b/src/data.c
index 6622088b648..4ef81f2474e 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1,5 +1,5 @@
1/* Primitive operations on Lisp data types for GNU Emacs Lisp interpreter. 1/* Primitive operations on Lisp data types for GNU Emacs Lisp interpreter.
2 Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2013 Free Software 2 Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2014 Free Software
3 Foundation, Inc. 3 Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
@@ -21,6 +21,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21#include <config.h> 21#include <config.h>
22#include <stdio.h> 22#include <stdio.h>
23 23
24#include <byteswap.h>
25#include <count-one-bits.h>
26#include <count-trailing-zeros.h>
24#include <intprops.h> 27#include <intprops.h>
25 28
26#include "lisp.h" 29#include "lisp.h"
@@ -38,6 +41,7 @@ Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
38static Lisp_Object Qsubr; 41static Lisp_Object Qsubr;
39Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; 42Lisp_Object Qerror_conditions, Qerror_message, Qtop_level;
40Lisp_Object Qerror, Quser_error, Qquit, Qargs_out_of_range; 43Lisp_Object Qerror, Quser_error, Qquit, Qargs_out_of_range;
44static Lisp_Object Qwrong_length_argument;
41static Lisp_Object Qwrong_type_argument; 45static Lisp_Object Qwrong_type_argument;
42Lisp_Object Qvoid_variable, Qvoid_function; 46Lisp_Object Qvoid_variable, Qvoid_function;
43static Lisp_Object Qcyclic_function_indirection; 47static Lisp_Object Qcyclic_function_indirection;
@@ -54,6 +58,7 @@ Lisp_Object Qintegerp, Qwholenump, Qsymbolp, Qlistp, Qconsp;
54static Lisp_Object Qnatnump; 58static Lisp_Object Qnatnump;
55Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp; 59Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp;
56Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp; 60Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp;
61Lisp_Object Qbool_vector_p;
57Lisp_Object Qbuffer_or_string_p; 62Lisp_Object Qbuffer_or_string_p;
58static Lisp_Object Qkeywordp, Qboundp; 63static Lisp_Object Qkeywordp, Qboundp;
59Lisp_Object Qfboundp; 64Lisp_Object Qfboundp;
@@ -76,7 +81,8 @@ static Lisp_Object Qprocess, Qmarker;
76static Lisp_Object Qcompiled_function, Qframe; 81static Lisp_Object Qcompiled_function, Qframe;
77Lisp_Object Qbuffer; 82Lisp_Object Qbuffer;
78static Lisp_Object Qchar_table, Qbool_vector, Qhash_table; 83static Lisp_Object Qchar_table, Qbool_vector, Qhash_table;
79static Lisp_Object Qsubrp, Qmany, Qunevalled; 84static Lisp_Object Qsubrp;
85static Lisp_Object Qmany, Qunevalled;
80Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; 86Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
81static Lisp_Object Qdefun; 87static Lisp_Object Qdefun;
82 88
@@ -85,6 +91,106 @@ static Lisp_Object Qdefalias_fset_function;
85 91
86static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *); 92static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *);
87 93
94static bool
95BOOLFWDP (union Lisp_Fwd *a)
96{
97 return XFWDTYPE (a) == Lisp_Fwd_Bool;
98}
99static bool
100INTFWDP (union Lisp_Fwd *a)
101{
102 return XFWDTYPE (a) == Lisp_Fwd_Int;
103}
104static bool
105KBOARD_OBJFWDP (union Lisp_Fwd *a)
106{
107 return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj;
108}
109static bool
110OBJFWDP (union Lisp_Fwd *a)
111{
112 return XFWDTYPE (a) == Lisp_Fwd_Obj;
113}
114
115static struct Lisp_Boolfwd *
116XBOOLFWD (union Lisp_Fwd *a)
117{
118 eassert (BOOLFWDP (a));
119 return &a->u_boolfwd;
120}
121static struct Lisp_Kboard_Objfwd *
122XKBOARD_OBJFWD (union Lisp_Fwd *a)
123{
124 eassert (KBOARD_OBJFWDP (a));
125 return &a->u_kboard_objfwd;
126}
127static struct Lisp_Intfwd *
128XINTFWD (union Lisp_Fwd *a)
129{
130 eassert (INTFWDP (a));
131 return &a->u_intfwd;
132}
133static struct Lisp_Objfwd *
134XOBJFWD (union Lisp_Fwd *a)
135{
136 eassert (OBJFWDP (a));
137 return &a->u_objfwd;
138}
139
140static void
141CHECK_SUBR (Lisp_Object x)
142{
143 CHECK_TYPE (SUBRP (x), Qsubrp, x);
144}
145
146static void
147set_blv_found (struct Lisp_Buffer_Local_Value *blv, int found)
148{
149 eassert (found == !EQ (blv->defcell, blv->valcell));
150 blv->found = found;
151}
152
153static Lisp_Object
154blv_value (struct Lisp_Buffer_Local_Value *blv)
155{
156 return XCDR (blv->valcell);
157}
158
159static void
160set_blv_value (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
161{
162 XSETCDR (blv->valcell, val);
163}
164
165static void
166set_blv_where (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
167{
168 blv->where = val;
169}
170
171static void
172set_blv_defcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
173{
174 blv->defcell = val;
175}
176
177static void
178set_blv_valcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
179{
180 blv->valcell = val;
181}
182
183static _Noreturn void
184wrong_length_argument (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
185{
186 Lisp_Object size1 = make_number (bool_vector_size (a1));
187 Lisp_Object size2 = make_number (bool_vector_size (a2));
188 if (NILP (a3))
189 xsignal2 (Qwrong_length_argument, size1, size2);
190 else
191 xsignal3 (Qwrong_length_argument, size1, size2,
192 make_number (bool_vector_size (a3)));
193}
88 194
89Lisp_Object 195Lisp_Object
90wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value) 196wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value)
@@ -100,9 +206,9 @@ wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value)
100} 206}
101 207
102void 208void
103pure_write_error (void) 209pure_write_error (Lisp_Object obj)
104{ 210{
105 error ("Attempt to modify read-only object"); 211 xsignal2 (Qerror, build_string ("Attempt to modify read-only object"), obj);
106} 212}
107 213
108void 214void
@@ -288,7 +394,8 @@ DEFUN ("stringp", Fstringp, Sstringp, 1, 1, 0,
288 394
289DEFUN ("multibyte-string-p", Fmultibyte_string_p, Smultibyte_string_p, 395DEFUN ("multibyte-string-p", Fmultibyte_string_p, Smultibyte_string_p,
290 1, 1, 0, 396 1, 1, 0,
291 doc: /* Return t if OBJECT is a multibyte string. */) 397 doc: /* Return t if OBJECT is a multibyte string.
398Return nil if OBJECT is either a unibyte string, or not a string. */)
292 (Lisp_Object object) 399 (Lisp_Object object)
293{ 400{
294 if (STRINGP (object) && STRING_MULTIBYTE (object)) 401 if (STRINGP (object) && STRING_MULTIBYTE (object))
@@ -526,7 +633,7 @@ global value outside of any lexical scope. */)
526 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); 633 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
527 if (blv->fwd) 634 if (blv->fwd)
528 /* In set_internal, we un-forward vars when their value is 635 /* In set_internal, we un-forward vars when their value is
529 set to Qunbound. */ 636 set to Qunbound. */
530 return Qt; 637 return Qt;
531 else 638 else
532 { 639 {
@@ -537,7 +644,7 @@ global value outside of any lexical scope. */)
537 } 644 }
538 case SYMBOL_FORWARDED: 645 case SYMBOL_FORWARDED:
539 /* In set_internal, we un-forward vars when their value is 646 /* In set_internal, we un-forward vars when their value is
540 set to Qunbound. */ 647 set to Qunbound. */
541 return Qt; 648 return Qt;
542 default: emacs_abort (); 649 default: emacs_abort ();
543 } 650 }
@@ -579,7 +686,7 @@ Return SYMBOL. */)
579} 686}
580 687
581DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, 688DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0,
582 doc: /* Return SYMBOL's function definition. Error if that is void. */) 689 doc: /* Return SYMBOL's function definition, or nil if that is void. */)
583 (register Lisp_Object symbol) 690 (register Lisp_Object symbol)
584{ 691{
585 CHECK_SYMBOL (symbol); 692 CHECK_SYMBOL (symbol);
@@ -631,6 +738,10 @@ Associates the function with the current load file, if any.
631The optional third argument DOCSTRING specifies the documentation string 738The optional third argument DOCSTRING specifies the documentation string
632for SYMBOL; if it is omitted or nil, SYMBOL uses the documentation string 739for SYMBOL; if it is omitted or nil, SYMBOL uses the documentation string
633determined by DEFINITION. 740determined by DEFINITION.
741
742Internally, this normally uses `fset', but if SYMBOL has a
743`defalias-fset-function' property, the associated value is used instead.
744
634The return value is undefined. */) 745The return value is undefined. */)
635 (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring) 746 (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring)
636{ 747{
@@ -891,19 +1002,14 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva
891 - (char *) &buffer_defaults); 1002 - (char *) &buffer_defaults);
892 int idx = PER_BUFFER_IDX (offset); 1003 int idx = PER_BUFFER_IDX (offset);
893 1004
894 Lisp_Object tail; 1005 Lisp_Object tail, buf;
895 1006
896 if (idx <= 0) 1007 if (idx <= 0)
897 break; 1008 break;
898 1009
899 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 1010 FOR_EACH_LIVE_BUFFER (tail, buf)
900 { 1011 {
901 Lisp_Object lbuf; 1012 struct buffer *b = XBUFFER (buf);
902 struct buffer *b;
903
904 lbuf = Fcdr (XCAR (tail));
905 if (!BUFFERP (lbuf)) continue;
906 b = XBUFFER (lbuf);
907 1013
908 if (! PER_BUFFER_VALUE_P (b, idx)) 1014 if (! PER_BUFFER_VALUE_P (b, idx))
909 set_per_buffer_value (b, offset, newval); 1015 set_per_buffer_value (b, offset, newval);
@@ -1069,40 +1175,6 @@ DEFUN ("set", Fset, Sset, 2, 2, 0,
1069 return newval; 1175 return newval;
1070} 1176}
1071 1177
1072/* Return true if SYMBOL currently has a let-binding
1073 which was made in the buffer that is now current. */
1074
1075static bool
1076let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol)
1077{
1078 struct specbinding *p;
1079
1080 for (p = specpdl_ptr; p > specpdl; )
1081 if ((--p)->func == NULL
1082 && CONSP (p->symbol))
1083 {
1084 struct Lisp_Symbol *let_bound_symbol = XSYMBOL (XCAR (p->symbol));
1085 eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS);
1086 if (symbol == let_bound_symbol
1087 && XBUFFER (XCDR (XCDR (p->symbol))) == current_buffer)
1088 return 1;
1089 }
1090
1091 return 0;
1092}
1093
1094static bool
1095let_shadows_global_binding_p (Lisp_Object symbol)
1096{
1097 struct specbinding *p;
1098
1099 for (p = specpdl_ptr; p > specpdl; )
1100 if ((--p)->func == NULL && EQ (p->symbol, symbol))
1101 return 1;
1102
1103 return 0;
1104}
1105
1106/* Store the value NEWVAL into SYMBOL. 1178/* Store the value NEWVAL into SYMBOL.
1107 If buffer/frame-locality is an issue, WHERE specifies which context to use. 1179 If buffer/frame-locality is an issue, WHERE specifies which context to use.
1108 (nil stands for the current buffer/frame). 1180 (nil stands for the current buffer/frame).
@@ -1328,9 +1400,7 @@ for this variable. The default value is meaningful for variables with
1328local bindings in certain buffers. */) 1400local bindings in certain buffers. */)
1329 (Lisp_Object symbol) 1401 (Lisp_Object symbol)
1330{ 1402{
1331 register Lisp_Object value; 1403 Lisp_Object value = default_value (symbol);
1332
1333 value = default_value (symbol);
1334 if (!EQ (value, Qunbound)) 1404 if (!EQ (value, Qunbound))
1335 return value; 1405 return value;
1336 1406
@@ -1422,24 +1492,19 @@ of previous VARs.
1422usage: (setq-default [VAR VALUE]...) */) 1492usage: (setq-default [VAR VALUE]...) */)
1423 (Lisp_Object args) 1493 (Lisp_Object args)
1424{ 1494{
1425 register Lisp_Object args_left; 1495 Lisp_Object args_left, symbol, val;
1426 register Lisp_Object val, symbol;
1427 struct gcpro gcpro1; 1496 struct gcpro gcpro1;
1428 1497
1429 if (NILP (args)) 1498 args_left = val = args;
1430 return Qnil;
1431
1432 args_left = args;
1433 GCPRO1 (args); 1499 GCPRO1 (args);
1434 1500
1435 do 1501 while (CONSP (args_left))
1436 { 1502 {
1437 val = eval_sub (Fcar (Fcdr (args_left))); 1503 val = eval_sub (Fcar (XCDR (args_left)));
1438 symbol = XCAR (args_left); 1504 symbol = XCAR (args_left);
1439 Fset_default (symbol, val); 1505 Fset_default (symbol, val);
1440 args_left = Fcdr (XCDR (args_left)); 1506 args_left = Fcdr (XCDR (args_left));
1441 } 1507 }
1442 while (!NILP (args_left));
1443 1508
1444 UNGCPRO; 1509 UNGCPRO;
1445 return val; 1510 return val;
@@ -1490,8 +1555,12 @@ Note that binding the variable with `let', or setting it while
1490a `let'-style binding made in this buffer is in effect, 1555a `let'-style binding made in this buffer is in effect,
1491does not make the variable buffer-local. Return VARIABLE. 1556does not make the variable buffer-local. Return VARIABLE.
1492 1557
1493In most cases it is better to use `make-local-variable', 1558This globally affects all uses of this variable, so it belongs together with
1494which makes a variable local in just one buffer. 1559the variable declaration, rather than with its uses (if you just want to make
1560a variable local to the current buffer for one particular use, use
1561`make-local-variable'). Buffer-local bindings are normally cleared
1562while setting up a new major mode, unless they have a `permanent-local'
1563property.
1495 1564
1496The function `default-value' gets the default value and `set-default' sets it. */) 1565The function `default-value' gets the default value and `set-default' sets it. */)
1497 (register Lisp_Object variable) 1566 (register Lisp_Object variable)
@@ -1841,17 +1910,18 @@ BUFFER defaults to the current buffer. */)
1841 XSETBUFFER (tmp, buf); 1910 XSETBUFFER (tmp, buf);
1842 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */ 1911 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */
1843 1912
1844 for (tail = BVAR (buf, local_var_alist); CONSP (tail); tail = XCDR (tail)) 1913 if (EQ (blv->where, tmp)) /* The binding is already loaded. */
1845 { 1914 return blv_found (blv) ? Qt : Qnil;
1846 elt = XCAR (tail); 1915 else
1847 if (EQ (variable, XCAR (elt))) 1916 for (tail = BVAR (buf, local_var_alist); CONSP (tail); tail = XCDR (tail))
1848 { 1917 {
1849 eassert (!blv->frame_local); 1918 elt = XCAR (tail);
1850 eassert (blv_found (blv) || !EQ (blv->where, tmp)); 1919 if (EQ (variable, XCAR (elt)))
1851 return Qt; 1920 {
1852 } 1921 eassert (!blv->frame_local);
1853 } 1922 return Qt;
1854 eassert (!blv_found (blv) || !EQ (blv->where, tmp)); 1923 }
1924 }
1855 return Qnil; 1925 return Qnil;
1856 } 1926 }
1857 case SYMBOL_FORWARDED: 1927 case SYMBOL_FORWARDED:
@@ -1930,7 +2000,7 @@ If the current binding is global (the default), the value is nil. */)
1930 { 2000 {
1931 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); 2001 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym);
1932 if (KBOARD_OBJFWDP (valcontents)) 2002 if (KBOARD_OBJFWDP (valcontents))
1933 return Fframe_terminal (Fselected_frame ()); 2003 return Fframe_terminal (selected_frame);
1934 else if (!BUFFER_OBJFWDP (valcontents)) 2004 else if (!BUFFER_OBJFWDP (valcontents))
1935 return Qnil; 2005 return Qnil;
1936 } 2006 }
@@ -1950,7 +2020,7 @@ If the current binding is global (the default), the value is nil. */)
1950} 2020}
1951 2021
1952/* This code is disabled now that we use the selected frame to return 2022/* This code is disabled now that we use the selected frame to return
1953 keyboard-local-values. */ 2023 keyboard-local-values. */
1954#if 0 2024#if 0
1955extern struct terminal *get_terminal (Lisp_Object display, int); 2025extern struct terminal *get_terminal (Lisp_Object display, int);
1956 2026
@@ -2079,13 +2149,9 @@ or a byte-code object. IDX starts at 0. */)
2079 } 2149 }
2080 else if (BOOL_VECTOR_P (array)) 2150 else if (BOOL_VECTOR_P (array))
2081 { 2151 {
2082 int val; 2152 if (idxval < 0 || idxval >= bool_vector_size (array))
2083
2084 if (idxval < 0 || idxval >= XBOOL_VECTOR (array)->size)
2085 args_out_of_range (array, idx); 2153 args_out_of_range (array, idx);
2086 2154 return bool_vector_ref (array, idxval);
2087 val = (unsigned char) XBOOL_VECTOR (array)->data[idxval / BOOL_VECTOR_BITS_PER_CHAR];
2088 return (val & (1 << (idxval % BOOL_VECTOR_BITS_PER_CHAR)) ? Qt : Qnil);
2089 } 2155 }
2090 else if (CHAR_TABLE_P (array)) 2156 else if (CHAR_TABLE_P (array))
2091 { 2157 {
@@ -2129,18 +2195,9 @@ bool-vector. IDX starts at 0. */)
2129 } 2195 }
2130 else if (BOOL_VECTOR_P (array)) 2196 else if (BOOL_VECTOR_P (array))
2131 { 2197 {
2132 int val; 2198 if (idxval < 0 || idxval >= bool_vector_size (array))
2133
2134 if (idxval < 0 || idxval >= XBOOL_VECTOR (array)->size)
2135 args_out_of_range (array, idx); 2199 args_out_of_range (array, idx);
2136 2200 bool_vector_set (array, idxval, !NILP (newelt));
2137 val = (unsigned char) XBOOL_VECTOR (array)->data[idxval / BOOL_VECTOR_BITS_PER_CHAR];
2138
2139 if (! NILP (newelt))
2140 val |= 1 << (idxval % BOOL_VECTOR_BITS_PER_CHAR);
2141 else
2142 val &= ~(1 << (idxval % BOOL_VECTOR_BITS_PER_CHAR));
2143 XBOOL_VECTOR (array)->data[idxval / BOOL_VECTOR_BITS_PER_CHAR] = val;
2144 } 2201 }
2145 else if (CHAR_TABLE_P (array)) 2202 else if (CHAR_TABLE_P (array))
2146 { 2203 {
@@ -2210,10 +2267,8 @@ bool-vector. IDX starts at 0. */)
2210 2267
2211/* Arithmetic functions */ 2268/* Arithmetic functions */
2212 2269
2213enum comparison { equal, notequal, less, grtr, less_or_equal, grtr_or_equal }; 2270Lisp_Object
2214 2271arithcompare (Lisp_Object num1, Lisp_Object num2, enum Arith_Comparison comparison)
2215static Lisp_Object
2216arithcompare (Lisp_Object num1, Lisp_Object num2, enum comparison comparison)
2217{ 2272{
2218 double f1 = 0, f2 = 0; 2273 double f1 = 0, f2 = 0;
2219 bool floatp = 0; 2274 bool floatp = 0;
@@ -2230,32 +2285,32 @@ arithcompare (Lisp_Object num1, Lisp_Object num2, enum comparison comparison)
2230 2285
2231 switch (comparison) 2286 switch (comparison)
2232 { 2287 {
2233 case equal: 2288 case ARITH_EQUAL:
2234 if (floatp ? f1 == f2 : XINT (num1) == XINT (num2)) 2289 if (floatp ? f1 == f2 : XINT (num1) == XINT (num2))
2235 return Qt; 2290 return Qt;
2236 return Qnil; 2291 return Qnil;
2237 2292
2238 case notequal: 2293 case ARITH_NOTEQUAL:
2239 if (floatp ? f1 != f2 : XINT (num1) != XINT (num2)) 2294 if (floatp ? f1 != f2 : XINT (num1) != XINT (num2))
2240 return Qt; 2295 return Qt;
2241 return Qnil; 2296 return Qnil;
2242 2297
2243 case less: 2298 case ARITH_LESS:
2244 if (floatp ? f1 < f2 : XINT (num1) < XINT (num2)) 2299 if (floatp ? f1 < f2 : XINT (num1) < XINT (num2))
2245 return Qt; 2300 return Qt;
2246 return Qnil; 2301 return Qnil;
2247 2302
2248 case less_or_equal: 2303 case ARITH_LESS_OR_EQUAL:
2249 if (floatp ? f1 <= f2 : XINT (num1) <= XINT (num2)) 2304 if (floatp ? f1 <= f2 : XINT (num1) <= XINT (num2))
2250 return Qt; 2305 return Qt;
2251 return Qnil; 2306 return Qnil;
2252 2307
2253 case grtr: 2308 case ARITH_GRTR:
2254 if (floatp ? f1 > f2 : XINT (num1) > XINT (num2)) 2309 if (floatp ? f1 > f2 : XINT (num1) > XINT (num2))
2255 return Qt; 2310 return Qt;
2256 return Qnil; 2311 return Qnil;
2257 2312
2258 case grtr_or_equal: 2313 case ARITH_GRTR_OR_EQUAL:
2259 if (floatp ? f1 >= f2 : XINT (num1) >= XINT (num2)) 2314 if (floatp ? f1 >= f2 : XINT (num1) >= XINT (num2))
2260 return Qt; 2315 return Qt;
2261 return Qnil; 2316 return Qnil;
@@ -2265,48 +2320,66 @@ arithcompare (Lisp_Object num1, Lisp_Object num2, enum comparison comparison)
2265 } 2320 }
2266} 2321}
2267 2322
2268DEFUN ("=", Feqlsign, Seqlsign, 2, 2, 0, 2323static Lisp_Object
2269 doc: /* Return t if two args, both numbers or markers, are equal. */) 2324arithcompare_driver (ptrdiff_t nargs, Lisp_Object *args,
2270 (register Lisp_Object num1, Lisp_Object num2) 2325 enum Arith_Comparison comparison)
2271{ 2326{
2272 return arithcompare (num1, num2, equal); 2327 ptrdiff_t argnum;
2328 for (argnum = 1; argnum < nargs; ++argnum)
2329 {
2330 if (EQ (Qnil, arithcompare (args[argnum-1], args[argnum], comparison)))
2331 return Qnil;
2332 }
2333 return Qt;
2273} 2334}
2274 2335
2275DEFUN ("<", Flss, Slss, 2, 2, 0, 2336DEFUN ("=", Feqlsign, Seqlsign, 1, MANY, 0,
2276 doc: /* Return t if first arg is less than second arg. Both must be numbers or markers. */) 2337 doc: /* Return t if args, all numbers or markers, are equal.
2277 (register Lisp_Object num1, Lisp_Object num2) 2338usage: (= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
2339 (ptrdiff_t nargs, Lisp_Object *args)
2278{ 2340{
2279 return arithcompare (num1, num2, less); 2341 return arithcompare_driver (nargs, args, ARITH_EQUAL);
2280} 2342}
2281 2343
2282DEFUN (">", Fgtr, Sgtr, 2, 2, 0, 2344DEFUN ("<", Flss, Slss, 1, MANY, 0,
2283 doc: /* Return t if first arg is greater than second arg. Both must be numbers or markers. */) 2345 doc: /* Return t if each arg is less than the next arg. All must be numbers or markers.
2284 (register Lisp_Object num1, Lisp_Object num2) 2346usage: (< NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
2347 (ptrdiff_t nargs, Lisp_Object *args)
2285{ 2348{
2286 return arithcompare (num1, num2, grtr); 2349 return arithcompare_driver (nargs, args, ARITH_LESS);
2287} 2350}
2288 2351
2289DEFUN ("<=", Fleq, Sleq, 2, 2, 0, 2352DEFUN (">", Fgtr, Sgtr, 1, MANY, 0,
2290 doc: /* Return t if first arg is less than or equal to second arg. 2353 doc: /* Return t if each arg is greater than the next arg. All must be numbers or markers.
2291Both must be numbers or markers. */) 2354usage: (> NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
2292 (register Lisp_Object num1, Lisp_Object num2) 2355 (ptrdiff_t nargs, Lisp_Object *args)
2293{ 2356{
2294 return arithcompare (num1, num2, less_or_equal); 2357 return arithcompare_driver (nargs, args, ARITH_GRTR);
2295} 2358}
2296 2359
2297DEFUN (">=", Fgeq, Sgeq, 2, 2, 0, 2360DEFUN ("<=", Fleq, Sleq, 1, MANY, 0,
2298 doc: /* Return t if first arg is greater than or equal to second arg. 2361 doc: /* Return t if each arg is less than or equal to the next arg.
2299Both must be numbers or markers. */) 2362All must be numbers or markers.
2300 (register Lisp_Object num1, Lisp_Object num2) 2363usage: (<= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
2364 (ptrdiff_t nargs, Lisp_Object *args)
2301{ 2365{
2302 return arithcompare (num1, num2, grtr_or_equal); 2366 return arithcompare_driver (nargs, args, ARITH_LESS_OR_EQUAL);
2367}
2368
2369DEFUN (">=", Fgeq, Sgeq, 1, MANY, 0,
2370 doc: /* Return t if each arg is greater than or equal to the next arg.
2371All must be numbers or markers.
2372usage: (>= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
2373 (ptrdiff_t nargs, Lisp_Object *args)
2374{
2375 return arithcompare_driver (nargs, args, ARITH_GRTR_OR_EQUAL);
2303} 2376}
2304 2377
2305DEFUN ("/=", Fneq, Sneq, 2, 2, 0, 2378DEFUN ("/=", Fneq, Sneq, 2, 2, 0,
2306 doc: /* Return t if first arg is not equal to second arg. Both must be numbers or markers. */) 2379 doc: /* Return t if first arg is not equal to second arg. Both must be numbers or markers. */)
2307 (register Lisp_Object num1, Lisp_Object num2) 2380 (register Lisp_Object num1, Lisp_Object num2)
2308{ 2381{
2309 return arithcompare (num1, num2, notequal); 2382 return arithcompare (num1, num2, ARITH_NOTEQUAL);
2310} 2383}
2311 2384
2312DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0, 2385DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0,
@@ -2454,12 +2527,12 @@ NUMBER may be an integer or a floating point number. */)
2454 2527
2455DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0, 2528DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0,
2456 doc: /* Parse STRING as a decimal number and return the number. 2529 doc: /* Parse STRING as a decimal number and return the number.
2457This parses both integers and floating point numbers. 2530Ignore leading spaces and tabs, and all trailing chars. Return 0 if
2458It ignores leading spaces and tabs, and all trailing chars. 2531STRING cannot be parsed as an integer or floating point number.
2459 2532
2460If BASE, interpret STRING as a number in that base. If BASE isn't 2533If BASE, interpret STRING as a number in that base. If BASE isn't
2461present, base 10 is used. BASE must be between 2 and 16 (inclusive). 2534present, base 10 is used. BASE must be between 2 and 16 (inclusive).
2462If the base used is not 10, STRING is always parsed as integer. */) 2535If the base used is not 10, STRING is always parsed as an integer. */)
2463 (register Lisp_Object string, Lisp_Object base) 2536 (register Lisp_Object string, Lisp_Object base)
2464{ 2537{
2465 register char *p; 2538 register char *p;
@@ -2896,6 +2969,434 @@ lowercase l) for small endian machines. */)
2896 return make_number (order); 2969 return make_number (order);
2897} 2970}
2898 2971
2972/* Because we round up the bool vector allocate size to word_size
2973 units, we can safely read past the "end" of the vector in the
2974 operations below. These extra bits are always zero. */
2975
2976static bits_word
2977bool_vector_spare_mask (EMACS_INT nr_bits)
2978{
2979 return (((bits_word) 1) << (nr_bits % BITS_PER_BITS_WORD)) - 1;
2980}
2981
2982/* Info about unsigned long long, falling back on unsigned long
2983 if unsigned long long is not available. */
2984
2985#if HAVE_UNSIGNED_LONG_LONG_INT
2986enum { BITS_PER_ULL = CHAR_BIT * sizeof (unsigned long long) };
2987# define ULL_MAX ULLONG_MAX
2988#else
2989enum { BITS_PER_ULL = CHAR_BIT * sizeof (unsigned long) };
2990# define ULL_MAX ULONG_MAX
2991# define count_one_bits_ll count_one_bits_l
2992# define count_trailing_zeros_ll count_trailing_zeros_l
2993#endif
2994
2995/* Shift VAL right by the width of an unsigned long long.
2996 BITS_PER_ULL must be less than BITS_PER_BITS_WORD. */
2997
2998static bits_word
2999shift_right_ull (bits_word w)
3000{
3001 /* Pacify bogus GCC warning about shift count exceeding type width. */
3002 int shift = BITS_PER_ULL - BITS_PER_BITS_WORD < 0 ? BITS_PER_ULL : 0;
3003 return w >> shift;
3004}
3005
3006/* Return the number of 1 bits in W. */
3007
3008static int
3009count_one_bits_word (bits_word w)
3010{
3011 if (BITS_WORD_MAX <= UINT_MAX)
3012 return count_one_bits (w);
3013 else if (BITS_WORD_MAX <= ULONG_MAX)
3014 return count_one_bits_l (w);
3015 else
3016 {
3017 int i = 0, count = 0;
3018 while (count += count_one_bits_ll (w),
3019 (i += BITS_PER_ULL) < BITS_PER_BITS_WORD)
3020 w = shift_right_ull (w);
3021 return count;
3022 }
3023}
3024
3025enum bool_vector_op { bool_vector_exclusive_or,
3026 bool_vector_union,
3027 bool_vector_intersection,
3028 bool_vector_set_difference,
3029 bool_vector_subsetp };
3030
3031static Lisp_Object
3032bool_vector_binop_driver (Lisp_Object a,
3033 Lisp_Object b,
3034 Lisp_Object dest,
3035 enum bool_vector_op op)
3036{
3037 EMACS_INT nr_bits;
3038 bits_word *adata, *bdata, *destdata;
3039 ptrdiff_t i = 0;
3040 ptrdiff_t nr_words;
3041
3042 CHECK_BOOL_VECTOR (a);
3043 CHECK_BOOL_VECTOR (b);
3044
3045 nr_bits = bool_vector_size (a);
3046 if (bool_vector_size (b) != nr_bits)
3047 wrong_length_argument (a, b, dest);
3048
3049 nr_words = bool_vector_words (nr_bits);
3050 adata = bool_vector_data (a);
3051 bdata = bool_vector_data (b);
3052
3053 if (NILP (dest))
3054 {
3055 dest = make_uninit_bool_vector (nr_bits);
3056 destdata = bool_vector_data (dest);
3057 }
3058 else
3059 {
3060 CHECK_BOOL_VECTOR (dest);
3061 destdata = bool_vector_data (dest);
3062 if (bool_vector_size (dest) != nr_bits)
3063 wrong_length_argument (a, b, dest);
3064
3065 switch (op)
3066 {
3067 case bool_vector_exclusive_or:
3068 for (; i < nr_words; i++)
3069 if (destdata[i] != (adata[i] ^ bdata[i]))
3070 goto set_dest;
3071 break;
3072
3073 case bool_vector_subsetp:
3074 for (; i < nr_words; i++)
3075 if (adata[i] &~ bdata[i])
3076 return Qnil;
3077 return Qt;
3078
3079 case bool_vector_union:
3080 for (; i < nr_words; i++)
3081 if (destdata[i] != (adata[i] | bdata[i]))
3082 goto set_dest;
3083 break;
3084
3085 case bool_vector_intersection:
3086 for (; i < nr_words; i++)
3087 if (destdata[i] != (adata[i] & bdata[i]))
3088 goto set_dest;
3089 break;
3090
3091 case bool_vector_set_difference:
3092 for (; i < nr_words; i++)
3093 if (destdata[i] != (adata[i] &~ bdata[i]))
3094 goto set_dest;
3095 break;
3096 }
3097
3098 return Qnil;
3099 }
3100
3101 set_dest:
3102 switch (op)
3103 {
3104 case bool_vector_exclusive_or:
3105 for (; i < nr_words; i++)
3106 destdata[i] = adata[i] ^ bdata[i];
3107 break;
3108
3109 case bool_vector_union:
3110 for (; i < nr_words; i++)
3111 destdata[i] = adata[i] | bdata[i];
3112 break;
3113
3114 case bool_vector_intersection:
3115 for (; i < nr_words; i++)
3116 destdata[i] = adata[i] & bdata[i];
3117 break;
3118
3119 case bool_vector_set_difference:
3120 for (; i < nr_words; i++)
3121 destdata[i] = adata[i] &~ bdata[i];
3122 break;
3123
3124 default:
3125 eassume (0);
3126 }
3127
3128 return dest;
3129}
3130
3131/* PRECONDITION must be true. Return VALUE. This odd construction
3132 works around a bogus GCC diagnostic "shift count >= width of type". */
3133
3134static int
3135pre_value (bool precondition, int value)
3136{
3137 eassume (precondition);
3138 return precondition ? value : 0;
3139}
3140
3141/* Compute the number of trailing zero bits in val. If val is zero,
3142 return the number of bits in val. */
3143static int
3144count_trailing_zero_bits (bits_word val)
3145{
3146 if (BITS_WORD_MAX == UINT_MAX)
3147 return count_trailing_zeros (val);
3148 if (BITS_WORD_MAX == ULONG_MAX)
3149 return count_trailing_zeros_l (val);
3150 if (BITS_WORD_MAX == ULL_MAX)
3151 return count_trailing_zeros_ll (val);
3152
3153 /* The rest of this code is for the unlikely platform where bits_word differs
3154 in width from unsigned int, unsigned long, and unsigned long long. */
3155 val |= ~ BITS_WORD_MAX;
3156 if (BITS_WORD_MAX <= UINT_MAX)
3157 return count_trailing_zeros (val);
3158 if (BITS_WORD_MAX <= ULONG_MAX)
3159 return count_trailing_zeros_l (val);
3160 else
3161 {
3162 int count;
3163 for (count = 0;
3164 count < BITS_PER_BITS_WORD - BITS_PER_ULL;
3165 count += BITS_PER_ULL)
3166 {
3167 if (val & ULL_MAX)
3168 return count + count_trailing_zeros_ll (val);
3169 val = shift_right_ull (val);
3170 }
3171
3172 if (BITS_PER_BITS_WORD % BITS_PER_ULL != 0
3173 && BITS_WORD_MAX == (bits_word) -1)
3174 val |= (bits_word) 1 << pre_value (ULONG_MAX < BITS_WORD_MAX,
3175 BITS_PER_BITS_WORD % BITS_PER_ULL);
3176 return count + count_trailing_zeros_ll (val);
3177 }
3178}
3179
3180static bits_word
3181bits_word_to_host_endian (bits_word val)
3182{
3183#ifndef WORDS_BIGENDIAN
3184 return val;
3185#else
3186 if (BITS_WORD_MAX >> 31 == 1)
3187 return bswap_32 (val);
3188# if HAVE_UNSIGNED_LONG_LONG
3189 if (BITS_WORD_MAX >> 31 >> 31 >> 1 == 1)
3190 return bswap_64 (val);
3191# endif
3192 {
3193 int i;
3194 bits_word r = 0;
3195 for (i = 0; i < sizeof val; i++)
3196 {
3197 r = ((r << 1 << (CHAR_BIT - 1))
3198 | (val & ((1u << 1 << (CHAR_BIT - 1)) - 1)));
3199 val = val >> 1 >> (CHAR_BIT - 1);
3200 }
3201 return r;
3202 }
3203#endif
3204}
3205
3206DEFUN ("bool-vector-exclusive-or", Fbool_vector_exclusive_or,
3207 Sbool_vector_exclusive_or, 2, 3, 0,
3208 doc: /* Return A ^ B, bitwise exclusive or.
3209If optional third argument C is given, store result into C.
3210A, B, and C must be bool vectors of the same length.
3211Return the destination vector if it changed or nil otherwise. */)
3212 (Lisp_Object a, Lisp_Object b, Lisp_Object c)
3213{
3214 return bool_vector_binop_driver (a, b, c, bool_vector_exclusive_or);
3215}
3216
3217DEFUN ("bool-vector-union", Fbool_vector_union,
3218 Sbool_vector_union, 2, 3, 0,
3219 doc: /* Return A | B, bitwise or.
3220If optional third argument C is given, store result into C.
3221A, B, and C must be bool vectors of the same length.
3222Return the destination vector if it changed or nil otherwise. */)
3223 (Lisp_Object a, Lisp_Object b, Lisp_Object c)
3224{
3225 return bool_vector_binop_driver (a, b, c, bool_vector_union);
3226}
3227
3228DEFUN ("bool-vector-intersection", Fbool_vector_intersection,
3229 Sbool_vector_intersection, 2, 3, 0,
3230 doc: /* Return A & B, bitwise and.
3231If optional third argument C is given, store result into C.
3232A, B, and C must be bool vectors of the same length.
3233Return the destination vector if it changed or nil otherwise. */)
3234 (Lisp_Object a, Lisp_Object b, Lisp_Object c)
3235{
3236 return bool_vector_binop_driver (a, b, c, bool_vector_intersection);
3237}
3238
3239DEFUN ("bool-vector-set-difference", Fbool_vector_set_difference,
3240 Sbool_vector_set_difference, 2, 3, 0,
3241 doc: /* Return A &~ B, set difference.
3242If optional third argument C is given, store result into C.
3243A, B, and C must be bool vectors of the same length.
3244Return the destination vector if it changed or nil otherwise. */)
3245 (Lisp_Object a, Lisp_Object b, Lisp_Object c)
3246{
3247 return bool_vector_binop_driver (a, b, c, bool_vector_set_difference);
3248}
3249
3250DEFUN ("bool-vector-subsetp", Fbool_vector_subsetp,
3251 Sbool_vector_subsetp, 2, 2, 0,
3252 doc: /* Return t if every t value in A is also t in B, nil otherwise.
3253A and B must be bool vectors of the same length. */)
3254 (Lisp_Object a, Lisp_Object b)
3255{
3256 return bool_vector_binop_driver (a, b, b, bool_vector_subsetp);
3257}
3258
3259DEFUN ("bool-vector-not", Fbool_vector_not,
3260 Sbool_vector_not, 1, 2, 0,
3261 doc: /* Compute ~A, set complement.
3262If optional second argument B is given, store result into B.
3263A and B must be bool vectors of the same length.
3264Return the destination vector. */)
3265 (Lisp_Object a, Lisp_Object b)
3266{
3267 EMACS_INT nr_bits;
3268 bits_word *bdata, *adata;
3269 ptrdiff_t i;
3270
3271 CHECK_BOOL_VECTOR (a);
3272 nr_bits = bool_vector_size (a);
3273
3274 if (NILP (b))
3275 b = make_uninit_bool_vector (nr_bits);
3276 else
3277 {
3278 CHECK_BOOL_VECTOR (b);
3279 if (bool_vector_size (b) != nr_bits)
3280 wrong_length_argument (a, b, Qnil);
3281 }
3282
3283 bdata = bool_vector_data (b);
3284 adata = bool_vector_data (a);
3285
3286 for (i = 0; i < nr_bits / BITS_PER_BITS_WORD; i++)
3287 bdata[i] = BITS_WORD_MAX & ~adata[i];
3288
3289 if (nr_bits % BITS_PER_BITS_WORD)
3290 {
3291 bits_word mword = bits_word_to_host_endian (adata[i]);
3292 mword = ~mword;
3293 mword &= bool_vector_spare_mask (nr_bits);
3294 bdata[i] = bits_word_to_host_endian (mword);
3295 }
3296
3297 return b;
3298}
3299
3300DEFUN ("bool-vector-count-population", Fbool_vector_count_population,
3301 Sbool_vector_count_population, 1, 1, 0,
3302 doc: /* Count how many elements in A are t.
3303A is a bool vector. To count A's nil elements, subtract the return
3304value from A's length. */)
3305 (Lisp_Object a)
3306{
3307 EMACS_INT count;
3308 EMACS_INT nr_bits;
3309 bits_word *adata;
3310 ptrdiff_t i, nwords;
3311
3312 CHECK_BOOL_VECTOR (a);
3313
3314 nr_bits = bool_vector_size (a);
3315 nwords = bool_vector_words (nr_bits);
3316 count = 0;
3317 adata = bool_vector_data (a);
3318
3319 for (i = 0; i < nwords; i++)
3320 count += count_one_bits_word (adata[i]);
3321
3322 return make_number (count);
3323}
3324
3325DEFUN ("bool-vector-count-consecutive", Fbool_vector_count_consecutive,
3326 Sbool_vector_count_consecutive, 3, 3, 0,
3327 doc: /* Count how many consecutive elements in A equal B starting at I.
3328A is a bool vector, B is t or nil, and I is an index into A. */)
3329 (Lisp_Object a, Lisp_Object b, Lisp_Object i)
3330{
3331 EMACS_INT count;
3332 EMACS_INT nr_bits;
3333 int offset;
3334 bits_word *adata;
3335 bits_word twiddle;
3336 bits_word mword; /* Machine word. */
3337 ptrdiff_t pos, pos0;
3338 ptrdiff_t nr_words;
3339
3340 CHECK_BOOL_VECTOR (a);
3341 CHECK_NATNUM (i);
3342
3343 nr_bits = bool_vector_size (a);
3344 if (XFASTINT (i) > nr_bits) /* Allow one past the end for convenience */
3345 args_out_of_range (a, i);
3346
3347 adata = bool_vector_data (a);
3348 nr_words = bool_vector_words (nr_bits);
3349 pos = XFASTINT (i) / BITS_PER_BITS_WORD;
3350 offset = XFASTINT (i) % BITS_PER_BITS_WORD;
3351 count = 0;
3352
3353 /* By XORing with twiddle, we transform the problem of "count
3354 consecutive equal values" into "count the zero bits". The latter
3355 operation usually has hardware support. */
3356 twiddle = NILP (b) ? 0 : BITS_WORD_MAX;
3357
3358 /* Scan the remainder of the mword at the current offset. */
3359 if (pos < nr_words && offset != 0)
3360 {
3361 mword = bits_word_to_host_endian (adata[pos]);
3362 mword ^= twiddle;
3363 mword >>= offset;
3364
3365 /* Do not count the pad bits. */
3366 mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset);
3367
3368 count = count_trailing_zero_bits (mword);
3369 pos++;
3370 if (count + offset < BITS_PER_BITS_WORD)
3371 return make_number (count);
3372 }
3373
3374 /* Scan whole words until we either reach the end of the vector or
3375 find an mword that doesn't completely match. twiddle is
3376 endian-independent. */
3377 pos0 = pos;
3378 while (pos < nr_words && adata[pos] == twiddle)
3379 pos++;
3380 count += (pos - pos0) * BITS_PER_BITS_WORD;
3381
3382 if (pos < nr_words)
3383 {
3384 /* If we stopped because of a mismatch, see how many bits match
3385 in the current mword. */
3386 mword = bits_word_to_host_endian (adata[pos]);
3387 mword ^= twiddle;
3388 count += count_trailing_zero_bits (mword);
3389 }
3390 else if (nr_bits % BITS_PER_BITS_WORD != 0)
3391 {
3392 /* If we hit the end, we might have overshot our count. Reduce
3393 the total by the number of spare bits at the end of the
3394 vector. */
3395 count -= BITS_PER_BITS_WORD - nr_bits % BITS_PER_BITS_WORD;
3396 }
3397
3398 return make_number (count);
3399}
2899 3400
2900 3401
2901void 3402void
@@ -2913,6 +3414,7 @@ syms_of_data (void)
2913 DEFSYM (Qerror, "error"); 3414 DEFSYM (Qerror, "error");
2914 DEFSYM (Quser_error, "user-error"); 3415 DEFSYM (Quser_error, "user-error");
2915 DEFSYM (Qquit, "quit"); 3416 DEFSYM (Qquit, "quit");
3417 DEFSYM (Qwrong_length_argument, "wrong-length-argument");
2916 DEFSYM (Qwrong_type_argument, "wrong-type-argument"); 3418 DEFSYM (Qwrong_type_argument, "wrong-type-argument");
2917 DEFSYM (Qargs_out_of_range, "args-out-of-range"); 3419 DEFSYM (Qargs_out_of_range, "args-out-of-range");
2918 DEFSYM (Qvoid_function, "void-function"); 3420 DEFSYM (Qvoid_function, "void-function");
@@ -2945,6 +3447,7 @@ syms_of_data (void)
2945 DEFSYM (Qsequencep, "sequencep"); 3447 DEFSYM (Qsequencep, "sequencep");
2946 DEFSYM (Qbufferp, "bufferp"); 3448 DEFSYM (Qbufferp, "bufferp");
2947 DEFSYM (Qvectorp, "vectorp"); 3449 DEFSYM (Qvectorp, "vectorp");
3450 DEFSYM (Qbool_vector_p, "bool-vector-p");
2948 DEFSYM (Qchar_or_string_p, "char-or-string-p"); 3451 DEFSYM (Qchar_or_string_p, "char-or-string-p");
2949 DEFSYM (Qmarkerp, "markerp"); 3452 DEFSYM (Qmarkerp, "markerp");
2950 DEFSYM (Qbuffer_or_string_p, "buffer-or-string-p"); 3453 DEFSYM (Qbuffer_or_string_p, "buffer-or-string-p");
@@ -2986,6 +3489,7 @@ syms_of_data (void)
2986 PUT_ERROR (Qquit, Qnil, "Quit"); 3489 PUT_ERROR (Qquit, Qnil, "Quit");
2987 3490
2988 PUT_ERROR (Quser_error, error_tail, ""); 3491 PUT_ERROR (Quser_error, error_tail, "");
3492 PUT_ERROR (Qwrong_length_argument, error_tail, "Wrong length argument");
2989 PUT_ERROR (Qwrong_type_argument, error_tail, "Wrong type argument"); 3493 PUT_ERROR (Qwrong_type_argument, error_tail, "Wrong type argument");
2990 PUT_ERROR (Qargs_out_of_range, error_tail, "Args out of range"); 3494 PUT_ERROR (Qargs_out_of_range, error_tail, "Args out of range");
2991 PUT_ERROR (Qvoid_function, error_tail, 3495 PUT_ERROR (Qvoid_function, error_tail,
@@ -3162,6 +3666,15 @@ syms_of_data (void)
3162 defsubr (&Ssubr_arity); 3666 defsubr (&Ssubr_arity);
3163 defsubr (&Ssubr_name); 3667 defsubr (&Ssubr_name);
3164 3668
3669 defsubr (&Sbool_vector_exclusive_or);
3670 defsubr (&Sbool_vector_union);
3671 defsubr (&Sbool_vector_intersection);
3672 defsubr (&Sbool_vector_set_difference);
3673 defsubr (&Sbool_vector_not);
3674 defsubr (&Sbool_vector_subsetp);
3675 defsubr (&Sbool_vector_count_consecutive);
3676 defsubr (&Sbool_vector_count_population);
3677
3165 set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->function); 3678 set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->function);
3166 3679
3167 DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum, 3680 DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum,