diff options
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 773 |
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 | ||
| 5 | This file is part of GNU Emacs. | 5 | This 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; | |||
| 38 | static Lisp_Object Qsubr; | 41 | static Lisp_Object Qsubr; |
| 39 | Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; | 42 | Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; |
| 40 | Lisp_Object Qerror, Quser_error, Qquit, Qargs_out_of_range; | 43 | Lisp_Object Qerror, Quser_error, Qquit, Qargs_out_of_range; |
| 44 | static Lisp_Object Qwrong_length_argument; | ||
| 41 | static Lisp_Object Qwrong_type_argument; | 45 | static Lisp_Object Qwrong_type_argument; |
| 42 | Lisp_Object Qvoid_variable, Qvoid_function; | 46 | Lisp_Object Qvoid_variable, Qvoid_function; |
| 43 | static Lisp_Object Qcyclic_function_indirection; | 47 | static Lisp_Object Qcyclic_function_indirection; |
| @@ -54,6 +58,7 @@ Lisp_Object Qintegerp, Qwholenump, Qsymbolp, Qlistp, Qconsp; | |||
| 54 | static Lisp_Object Qnatnump; | 58 | static Lisp_Object Qnatnump; |
| 55 | Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp; | 59 | Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp; |
| 56 | Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp; | 60 | Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp; |
| 61 | Lisp_Object Qbool_vector_p; | ||
| 57 | Lisp_Object Qbuffer_or_string_p; | 62 | Lisp_Object Qbuffer_or_string_p; |
| 58 | static Lisp_Object Qkeywordp, Qboundp; | 63 | static Lisp_Object Qkeywordp, Qboundp; |
| 59 | Lisp_Object Qfboundp; | 64 | Lisp_Object Qfboundp; |
| @@ -76,7 +81,8 @@ static Lisp_Object Qprocess, Qmarker; | |||
| 76 | static Lisp_Object Qcompiled_function, Qframe; | 81 | static Lisp_Object Qcompiled_function, Qframe; |
| 77 | Lisp_Object Qbuffer; | 82 | Lisp_Object Qbuffer; |
| 78 | static Lisp_Object Qchar_table, Qbool_vector, Qhash_table; | 83 | static Lisp_Object Qchar_table, Qbool_vector, Qhash_table; |
| 79 | static Lisp_Object Qsubrp, Qmany, Qunevalled; | 84 | static Lisp_Object Qsubrp; |
| 85 | static Lisp_Object Qmany, Qunevalled; | ||
| 80 | Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; | 86 | Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; |
| 81 | static Lisp_Object Qdefun; | 87 | static Lisp_Object Qdefun; |
| 82 | 88 | ||
| @@ -85,6 +91,106 @@ static Lisp_Object Qdefalias_fset_function; | |||
| 85 | 91 | ||
| 86 | static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *); | 92 | static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *); |
| 87 | 93 | ||
| 94 | static bool | ||
| 95 | BOOLFWDP (union Lisp_Fwd *a) | ||
| 96 | { | ||
| 97 | return XFWDTYPE (a) == Lisp_Fwd_Bool; | ||
| 98 | } | ||
| 99 | static bool | ||
| 100 | INTFWDP (union Lisp_Fwd *a) | ||
| 101 | { | ||
| 102 | return XFWDTYPE (a) == Lisp_Fwd_Int; | ||
| 103 | } | ||
| 104 | static bool | ||
| 105 | KBOARD_OBJFWDP (union Lisp_Fwd *a) | ||
| 106 | { | ||
| 107 | return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj; | ||
| 108 | } | ||
| 109 | static bool | ||
| 110 | OBJFWDP (union Lisp_Fwd *a) | ||
| 111 | { | ||
| 112 | return XFWDTYPE (a) == Lisp_Fwd_Obj; | ||
| 113 | } | ||
| 114 | |||
| 115 | static struct Lisp_Boolfwd * | ||
| 116 | XBOOLFWD (union Lisp_Fwd *a) | ||
| 117 | { | ||
| 118 | eassert (BOOLFWDP (a)); | ||
| 119 | return &a->u_boolfwd; | ||
| 120 | } | ||
| 121 | static struct Lisp_Kboard_Objfwd * | ||
| 122 | XKBOARD_OBJFWD (union Lisp_Fwd *a) | ||
| 123 | { | ||
| 124 | eassert (KBOARD_OBJFWDP (a)); | ||
| 125 | return &a->u_kboard_objfwd; | ||
| 126 | } | ||
| 127 | static struct Lisp_Intfwd * | ||
| 128 | XINTFWD (union Lisp_Fwd *a) | ||
| 129 | { | ||
| 130 | eassert (INTFWDP (a)); | ||
| 131 | return &a->u_intfwd; | ||
| 132 | } | ||
| 133 | static struct Lisp_Objfwd * | ||
| 134 | XOBJFWD (union Lisp_Fwd *a) | ||
| 135 | { | ||
| 136 | eassert (OBJFWDP (a)); | ||
| 137 | return &a->u_objfwd; | ||
| 138 | } | ||
| 139 | |||
| 140 | static void | ||
| 141 | CHECK_SUBR (Lisp_Object x) | ||
| 142 | { | ||
| 143 | CHECK_TYPE (SUBRP (x), Qsubrp, x); | ||
| 144 | } | ||
| 145 | |||
| 146 | static void | ||
| 147 | set_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 | |||
| 153 | static Lisp_Object | ||
| 154 | blv_value (struct Lisp_Buffer_Local_Value *blv) | ||
| 155 | { | ||
| 156 | return XCDR (blv->valcell); | ||
| 157 | } | ||
| 158 | |||
| 159 | static void | ||
| 160 | set_blv_value (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) | ||
| 161 | { | ||
| 162 | XSETCDR (blv->valcell, val); | ||
| 163 | } | ||
| 164 | |||
| 165 | static void | ||
| 166 | set_blv_where (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) | ||
| 167 | { | ||
| 168 | blv->where = val; | ||
| 169 | } | ||
| 170 | |||
| 171 | static void | ||
| 172 | set_blv_defcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) | ||
| 173 | { | ||
| 174 | blv->defcell = val; | ||
| 175 | } | ||
| 176 | |||
| 177 | static void | ||
| 178 | set_blv_valcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) | ||
| 179 | { | ||
| 180 | blv->valcell = val; | ||
| 181 | } | ||
| 182 | |||
| 183 | static _Noreturn void | ||
| 184 | wrong_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 | ||
| 89 | Lisp_Object | 195 | Lisp_Object |
| 90 | wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value) | 196 | wrong_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 | ||
| 102 | void | 208 | void |
| 103 | pure_write_error (void) | 209 | pure_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 | ||
| 108 | void | 214 | void |
| @@ -288,7 +394,8 @@ DEFUN ("stringp", Fstringp, Sstringp, 1, 1, 0, | |||
| 288 | 394 | ||
| 289 | DEFUN ("multibyte-string-p", Fmultibyte_string_p, Smultibyte_string_p, | 395 | DEFUN ("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. |
| 398 | Return 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 | ||
| 581 | DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, | 688 | DEFUN ("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. | |||
| 631 | The optional third argument DOCSTRING specifies the documentation string | 738 | The optional third argument DOCSTRING specifies the documentation string |
| 632 | for SYMBOL; if it is omitted or nil, SYMBOL uses the documentation string | 739 | for SYMBOL; if it is omitted or nil, SYMBOL uses the documentation string |
| 633 | determined by DEFINITION. | 740 | determined by DEFINITION. |
| 741 | |||
| 742 | Internally, this normally uses `fset', but if SYMBOL has a | ||
| 743 | `defalias-fset-function' property, the associated value is used instead. | ||
| 744 | |||
| 634 | The return value is undefined. */) | 745 | The 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 | |||
| 1075 | static bool | ||
| 1076 | let_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 | |||
| 1094 | static bool | ||
| 1095 | let_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 | |||
| 1328 | local bindings in certain buffers. */) | 1400 | local 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. | |||
| 1422 | usage: (setq-default [VAR VALUE]...) */) | 1492 | usage: (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 | |||
| 1490 | a `let'-style binding made in this buffer is in effect, | 1555 | a `let'-style binding made in this buffer is in effect, |
| 1491 | does not make the variable buffer-local. Return VARIABLE. | 1556 | does not make the variable buffer-local. Return VARIABLE. |
| 1492 | 1557 | ||
| 1493 | In most cases it is better to use `make-local-variable', | 1558 | This globally affects all uses of this variable, so it belongs together with |
| 1494 | which makes a variable local in just one buffer. | 1559 | the variable declaration, rather than with its uses (if you just want to make |
| 1560 | a variable local to the current buffer for one particular use, use | ||
| 1561 | `make-local-variable'). Buffer-local bindings are normally cleared | ||
| 1562 | while setting up a new major mode, unless they have a `permanent-local' | ||
| 1563 | property. | ||
| 1495 | 1564 | ||
| 1496 | The function `default-value' gets the default value and `set-default' sets it. */) | 1565 | The 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 |
| 1955 | extern struct terminal *get_terminal (Lisp_Object display, int); | 2025 | extern 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 | ||
| 2213 | enum comparison { equal, notequal, less, grtr, less_or_equal, grtr_or_equal }; | 2270 | Lisp_Object |
| 2214 | 2271 | arithcompare (Lisp_Object num1, Lisp_Object num2, enum Arith_Comparison comparison) | |
| 2215 | static Lisp_Object | ||
| 2216 | arithcompare (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 | ||
| 2268 | DEFUN ("=", Feqlsign, Seqlsign, 2, 2, 0, | 2323 | static Lisp_Object |
| 2269 | doc: /* Return t if two args, both numbers or markers, are equal. */) | 2324 | arithcompare_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 | ||
| 2275 | DEFUN ("<", Flss, Slss, 2, 2, 0, | 2336 | DEFUN ("=", 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) | 2338 | usage: (= 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 | ||
| 2282 | DEFUN (">", Fgtr, Sgtr, 2, 2, 0, | 2344 | DEFUN ("<", 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) | 2346 | usage: (< 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 | ||
| 2289 | DEFUN ("<=", Fleq, Sleq, 2, 2, 0, | 2352 | DEFUN (">", 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. |
| 2291 | Both must be numbers or markers. */) | 2354 | usage: (> 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 | ||
| 2297 | DEFUN (">=", Fgeq, Sgeq, 2, 2, 0, | 2360 | DEFUN ("<=", 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. |
| 2299 | Both must be numbers or markers. */) | 2362 | All must be numbers or markers. |
| 2300 | (register Lisp_Object num1, Lisp_Object num2) | 2363 | usage: (<= 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 | |||
| 2369 | DEFUN (">=", Fgeq, Sgeq, 1, MANY, 0, | ||
| 2370 | doc: /* Return t if each arg is greater than or equal to the next arg. | ||
| 2371 | All must be numbers or markers. | ||
| 2372 | usage: (>= 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 | ||
| 2305 | DEFUN ("/=", Fneq, Sneq, 2, 2, 0, | 2378 | DEFUN ("/=", 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 | ||
| 2312 | DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0, | 2385 | DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0, |
| @@ -2454,12 +2527,12 @@ NUMBER may be an integer or a floating point number. */) | |||
| 2454 | 2527 | ||
| 2455 | DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0, | 2528 | DEFUN ("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. |
| 2457 | This parses both integers and floating point numbers. | 2530 | Ignore leading spaces and tabs, and all trailing chars. Return 0 if |
| 2458 | It ignores leading spaces and tabs, and all trailing chars. | 2531 | STRING cannot be parsed as an integer or floating point number. |
| 2459 | 2532 | ||
| 2460 | If BASE, interpret STRING as a number in that base. If BASE isn't | 2533 | If BASE, interpret STRING as a number in that base. If BASE isn't |
| 2461 | present, base 10 is used. BASE must be between 2 and 16 (inclusive). | 2534 | present, base 10 is used. BASE must be between 2 and 16 (inclusive). |
| 2462 | If the base used is not 10, STRING is always parsed as integer. */) | 2535 | If 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 | |||
| 2976 | static bits_word | ||
| 2977 | bool_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 | ||
| 2986 | enum { BITS_PER_ULL = CHAR_BIT * sizeof (unsigned long long) }; | ||
| 2987 | # define ULL_MAX ULLONG_MAX | ||
| 2988 | #else | ||
| 2989 | enum { 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 | |||
| 2998 | static bits_word | ||
| 2999 | shift_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 | |||
| 3008 | static int | ||
| 3009 | count_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 | |||
| 3025 | enum 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 | |||
| 3031 | static Lisp_Object | ||
| 3032 | bool_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 | |||
| 3134 | static int | ||
| 3135 | pre_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. */ | ||
| 3143 | static int | ||
| 3144 | count_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 | |||
| 3180 | static bits_word | ||
| 3181 | bits_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 | |||
| 3206 | DEFUN ("bool-vector-exclusive-or", Fbool_vector_exclusive_or, | ||
| 3207 | Sbool_vector_exclusive_or, 2, 3, 0, | ||
| 3208 | doc: /* Return A ^ B, bitwise exclusive or. | ||
| 3209 | If optional third argument C is given, store result into C. | ||
| 3210 | A, B, and C must be bool vectors of the same length. | ||
| 3211 | Return 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 | |||
| 3217 | DEFUN ("bool-vector-union", Fbool_vector_union, | ||
| 3218 | Sbool_vector_union, 2, 3, 0, | ||
| 3219 | doc: /* Return A | B, bitwise or. | ||
| 3220 | If optional third argument C is given, store result into C. | ||
| 3221 | A, B, and C must be bool vectors of the same length. | ||
| 3222 | Return 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 | |||
| 3228 | DEFUN ("bool-vector-intersection", Fbool_vector_intersection, | ||
| 3229 | Sbool_vector_intersection, 2, 3, 0, | ||
| 3230 | doc: /* Return A & B, bitwise and. | ||
| 3231 | If optional third argument C is given, store result into C. | ||
| 3232 | A, B, and C must be bool vectors of the same length. | ||
| 3233 | Return 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 | |||
| 3239 | DEFUN ("bool-vector-set-difference", Fbool_vector_set_difference, | ||
| 3240 | Sbool_vector_set_difference, 2, 3, 0, | ||
| 3241 | doc: /* Return A &~ B, set difference. | ||
| 3242 | If optional third argument C is given, store result into C. | ||
| 3243 | A, B, and C must be bool vectors of the same length. | ||
| 3244 | Return 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 | |||
| 3250 | DEFUN ("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. | ||
| 3253 | A 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 | |||
| 3259 | DEFUN ("bool-vector-not", Fbool_vector_not, | ||
| 3260 | Sbool_vector_not, 1, 2, 0, | ||
| 3261 | doc: /* Compute ~A, set complement. | ||
| 3262 | If optional second argument B is given, store result into B. | ||
| 3263 | A and B must be bool vectors of the same length. | ||
| 3264 | Return 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 | |||
| 3300 | DEFUN ("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. | ||
| 3303 | A is a bool vector. To count A's nil elements, subtract the return | ||
| 3304 | value 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 | |||
| 3325 | DEFUN ("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. | ||
| 3328 | A 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 | ||
| 2901 | void | 3402 | void |
| @@ -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, |