diff options
| author | Ken Raeburn | 2015-11-01 01:42:21 -0400 |
|---|---|---|
| committer | Ken Raeburn | 2015-11-01 01:42:21 -0400 |
| commit | 39372e1a1032521be74575bb06f95a3898fbae30 (patch) | |
| tree | 754bd242a23d2358ea116126fcb0a629947bd9ec /src/data.c | |
| parent | 6a3121904d76e3b2f63007341d48c5c1af55de80 (diff) | |
| parent | e11aaee266da52937a3a031cb108fe13f68958c3 (diff) | |
| download | emacs-39372e1a1032521be74575bb06f95a3898fbae30.tar.gz emacs-39372e1a1032521be74575bb06f95a3898fbae30.zip | |
merge from trunk
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 884 |
1 files changed, 676 insertions, 208 deletions
diff --git a/src/data.c b/src/data.c index 3763dc8adc8..f48c9ef2d10 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-2015 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" |
| @@ -29,63 +32,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 29 | #include "buffer.h" | 32 | #include "buffer.h" |
| 30 | #include "keyboard.h" | 33 | #include "keyboard.h" |
| 31 | #include "frame.h" | 34 | #include "frame.h" |
| 32 | #include "syssignal.h" | ||
| 33 | #include "termhooks.h" /* For FRAME_KBOARD reference in y-or-n-p. */ | ||
| 34 | #include "font.h" | ||
| 35 | #include "keymap.h" | 35 | #include "keymap.h" |
| 36 | 36 | ||
| 37 | Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound; | 37 | static void swap_in_symval_forwarding (struct Lisp_Symbol *, |
| 38 | static Lisp_Object Qsubr; | 38 | struct Lisp_Buffer_Local_Value *); |
| 39 | Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; | ||
| 40 | Lisp_Object Qerror, Quser_error, Qquit, Qargs_out_of_range; | ||
| 41 | static Lisp_Object Qwrong_type_argument; | ||
| 42 | Lisp_Object Qvoid_variable, Qvoid_function; | ||
| 43 | static Lisp_Object Qcyclic_function_indirection; | ||
| 44 | static Lisp_Object Qcyclic_variable_indirection; | ||
| 45 | Lisp_Object Qcircular_list; | ||
| 46 | static Lisp_Object Qsetting_constant; | ||
| 47 | Lisp_Object Qinvalid_read_syntax; | ||
| 48 | Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch; | ||
| 49 | Lisp_Object Qend_of_file, Qarith_error, Qmark_inactive; | ||
| 50 | Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only; | ||
| 51 | Lisp_Object Qtext_read_only; | ||
| 52 | |||
| 53 | Lisp_Object Qintegerp, Qwholenump, Qsymbolp, Qlistp, Qconsp; | ||
| 54 | static Lisp_Object Qnatnump; | ||
| 55 | Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp; | ||
| 56 | Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp; | ||
| 57 | Lisp_Object Qbuffer_or_string_p; | ||
| 58 | static Lisp_Object Qkeywordp, Qboundp; | ||
| 59 | Lisp_Object Qfboundp; | ||
| 60 | Lisp_Object Qchar_table_p, Qvector_or_char_table_p; | ||
| 61 | |||
| 62 | Lisp_Object Qcdr; | ||
| 63 | static Lisp_Object Qad_advice_info, Qad_activate_internal; | ||
| 64 | |||
| 65 | static Lisp_Object Qdomain_error, Qsingularity_error, Qunderflow_error; | ||
| 66 | Lisp_Object Qrange_error, Qoverflow_error; | ||
| 67 | |||
| 68 | Lisp_Object Qfloatp; | ||
| 69 | Lisp_Object Qnumberp, Qnumber_or_marker_p; | ||
| 70 | |||
| 71 | Lisp_Object Qinteger, Qsymbol; | ||
| 72 | static Lisp_Object Qcons, Qfloat, Qmisc, Qstring, Qvector; | ||
| 73 | Lisp_Object Qwindow; | ||
| 74 | static Lisp_Object Qoverlay, Qwindow_configuration; | ||
| 75 | static Lisp_Object Qprocess, Qmarker; | ||
| 76 | static Lisp_Object Qcompiled_function, Qframe; | ||
| 77 | Lisp_Object Qbuffer; | ||
| 78 | static Lisp_Object Qchar_table, Qbool_vector, Qhash_table; | ||
| 79 | static Lisp_Object Qsubrp; | ||
| 80 | static Lisp_Object Qmany, Qunevalled; | ||
| 81 | Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; | ||
| 82 | static Lisp_Object Qdefun; | ||
| 83 | Lisp_Object Qthread, Qmutex, Qcondition_variable; | ||
| 84 | |||
| 85 | Lisp_Object Qinteractive_form; | ||
| 86 | static Lisp_Object Qdefalias_fset_function; | ||
| 87 | |||
| 88 | static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *); | ||
| 89 | 39 | ||
| 90 | static bool | 40 | static bool |
| 91 | BOOLFWDP (union Lisp_Fwd *a) | 41 | BOOLFWDP (union Lisp_Fwd *a) |
| @@ -176,6 +126,18 @@ set_blv_valcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) | |||
| 176 | blv->valcell = val; | 126 | blv->valcell = val; |
| 177 | } | 127 | } |
| 178 | 128 | ||
| 129 | static _Noreturn void | ||
| 130 | wrong_length_argument (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3) | ||
| 131 | { | ||
| 132 | Lisp_Object size1 = make_number (bool_vector_size (a1)); | ||
| 133 | Lisp_Object size2 = make_number (bool_vector_size (a2)); | ||
| 134 | if (NILP (a3)) | ||
| 135 | xsignal2 (Qwrong_length_argument, size1, size2); | ||
| 136 | else | ||
| 137 | xsignal3 (Qwrong_length_argument, size1, size2, | ||
| 138 | make_number (bool_vector_size (a3))); | ||
| 139 | } | ||
| 140 | |||
| 179 | Lisp_Object | 141 | Lisp_Object |
| 180 | wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value) | 142 | wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value) |
| 181 | { | 143 | { |
| @@ -211,7 +173,8 @@ args_out_of_range_3 (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3) | |||
| 211 | /* Data type predicates. */ | 173 | /* Data type predicates. */ |
| 212 | 174 | ||
| 213 | DEFUN ("eq", Feq, Seq, 2, 2, 0, | 175 | DEFUN ("eq", Feq, Seq, 2, 2, 0, |
| 214 | doc: /* Return t if the two args are the same Lisp object. */) | 176 | doc: /* Return t if the two args are the same Lisp object. */ |
| 177 | attributes: const) | ||
| 215 | (Lisp_Object obj1, Lisp_Object obj2) | 178 | (Lisp_Object obj1, Lisp_Object obj2) |
| 216 | { | 179 | { |
| 217 | if (EQ (obj1, obj2)) | 180 | if (EQ (obj1, obj2)) |
| @@ -220,7 +183,8 @@ DEFUN ("eq", Feq, Seq, 2, 2, 0, | |||
| 220 | } | 183 | } |
| 221 | 184 | ||
| 222 | DEFUN ("null", Fnull, Snull, 1, 1, 0, | 185 | DEFUN ("null", Fnull, Snull, 1, 1, 0, |
| 223 | doc: /* Return t if OBJECT is nil. */) | 186 | doc: /* Return t if OBJECT is nil, and return nil otherwise. */ |
| 187 | attributes: const) | ||
| 224 | (Lisp_Object object) | 188 | (Lisp_Object object) |
| 225 | { | 189 | { |
| 226 | if (NILP (object)) | 190 | if (NILP (object)) |
| @@ -256,9 +220,12 @@ for example, (type-of 1) returns `integer'. */) | |||
| 256 | case Lisp_Misc_Overlay: | 220 | case Lisp_Misc_Overlay: |
| 257 | return Qoverlay; | 221 | return Qoverlay; |
| 258 | case Lisp_Misc_Float: | 222 | case Lisp_Misc_Float: |
| 259 | return Qfloat; | 223 | return Qfloat; |
| 224 | case Lisp_Misc_Finalizer: | ||
| 225 | return Qfinalizer; | ||
| 226 | default: | ||
| 227 | emacs_abort (); | ||
| 260 | } | 228 | } |
| 261 | emacs_abort (); | ||
| 262 | 229 | ||
| 263 | case Lisp_Vectorlike: | 230 | case Lisp_Vectorlike: |
| 264 | if (WINDOW_CONFIGURATIONP (object)) | 231 | if (WINDOW_CONFIGURATIONP (object)) |
| @@ -304,7 +271,8 @@ for example, (type-of 1) returns `integer'. */) | |||
| 304 | } | 271 | } |
| 305 | 272 | ||
| 306 | DEFUN ("consp", Fconsp, Sconsp, 1, 1, 0, | 273 | DEFUN ("consp", Fconsp, Sconsp, 1, 1, 0, |
| 307 | doc: /* Return t if OBJECT is a cons cell. */) | 274 | doc: /* Return t if OBJECT is a cons cell. */ |
| 275 | attributes: const) | ||
| 308 | (Lisp_Object object) | 276 | (Lisp_Object object) |
| 309 | { | 277 | { |
| 310 | if (CONSP (object)) | 278 | if (CONSP (object)) |
| @@ -313,7 +281,8 @@ DEFUN ("consp", Fconsp, Sconsp, 1, 1, 0, | |||
| 313 | } | 281 | } |
| 314 | 282 | ||
| 315 | DEFUN ("atom", Fatom, Satom, 1, 1, 0, | 283 | DEFUN ("atom", Fatom, Satom, 1, 1, 0, |
| 316 | doc: /* Return t if OBJECT is not a cons cell. This includes nil. */) | 284 | doc: /* Return t if OBJECT is not a cons cell. This includes nil. */ |
| 285 | attributes: const) | ||
| 317 | (Lisp_Object object) | 286 | (Lisp_Object object) |
| 318 | { | 287 | { |
| 319 | if (CONSP (object)) | 288 | if (CONSP (object)) |
| @@ -323,7 +292,8 @@ DEFUN ("atom", Fatom, Satom, 1, 1, 0, | |||
| 323 | 292 | ||
| 324 | DEFUN ("listp", Flistp, Slistp, 1, 1, 0, | 293 | DEFUN ("listp", Flistp, Slistp, 1, 1, 0, |
| 325 | doc: /* Return t if OBJECT is a list, that is, a cons cell or nil. | 294 | doc: /* Return t if OBJECT is a list, that is, a cons cell or nil. |
| 326 | Otherwise, return nil. */) | 295 | Otherwise, return nil. */ |
| 296 | attributes: const) | ||
| 327 | (Lisp_Object object) | 297 | (Lisp_Object object) |
| 328 | { | 298 | { |
| 329 | if (CONSP (object) || NILP (object)) | 299 | if (CONSP (object) || NILP (object)) |
| @@ -332,7 +302,8 @@ Otherwise, return nil. */) | |||
| 332 | } | 302 | } |
| 333 | 303 | ||
| 334 | DEFUN ("nlistp", Fnlistp, Snlistp, 1, 1, 0, | 304 | DEFUN ("nlistp", Fnlistp, Snlistp, 1, 1, 0, |
| 335 | doc: /* Return t if OBJECT is not a list. Lists include nil. */) | 305 | doc: /* Return t if OBJECT is not a list. Lists include nil. */ |
| 306 | attributes: const) | ||
| 336 | (Lisp_Object object) | 307 | (Lisp_Object object) |
| 337 | { | 308 | { |
| 338 | if (CONSP (object) || NILP (object)) | 309 | if (CONSP (object) || NILP (object)) |
| @@ -341,7 +312,8 @@ DEFUN ("nlistp", Fnlistp, Snlistp, 1, 1, 0, | |||
| 341 | } | 312 | } |
| 342 | 313 | ||
| 343 | DEFUN ("symbolp", Fsymbolp, Ssymbolp, 1, 1, 0, | 314 | DEFUN ("symbolp", Fsymbolp, Ssymbolp, 1, 1, 0, |
| 344 | doc: /* Return t if OBJECT is a symbol. */) | 315 | doc: /* Return t if OBJECT is a symbol. */ |
| 316 | attributes: const) | ||
| 345 | (Lisp_Object object) | 317 | (Lisp_Object object) |
| 346 | { | 318 | { |
| 347 | if (SYMBOLP (object)) | 319 | if (SYMBOLP (object)) |
| @@ -374,7 +346,8 @@ DEFUN ("vectorp", Fvectorp, Svectorp, 1, 1, 0, | |||
| 374 | } | 346 | } |
| 375 | 347 | ||
| 376 | DEFUN ("stringp", Fstringp, Sstringp, 1, 1, 0, | 348 | DEFUN ("stringp", Fstringp, Sstringp, 1, 1, 0, |
| 377 | doc: /* Return t if OBJECT is a string. */) | 349 | doc: /* Return t if OBJECT is a string. */ |
| 350 | attributes: const) | ||
| 378 | (Lisp_Object object) | 351 | (Lisp_Object object) |
| 379 | { | 352 | { |
| 380 | if (STRINGP (object)) | 353 | if (STRINGP (object)) |
| @@ -477,7 +450,8 @@ DEFUN ("byte-code-function-p", Fbyte_code_function_p, Sbyte_code_function_p, | |||
| 477 | } | 450 | } |
| 478 | 451 | ||
| 479 | DEFUN ("char-or-string-p", Fchar_or_string_p, Schar_or_string_p, 1, 1, 0, | 452 | DEFUN ("char-or-string-p", Fchar_or_string_p, Schar_or_string_p, 1, 1, 0, |
| 480 | doc: /* Return t if OBJECT is a character or a string. */) | 453 | doc: /* Return t if OBJECT is a character or a string. */ |
| 454 | attributes: const) | ||
| 481 | (register Lisp_Object object) | 455 | (register Lisp_Object object) |
| 482 | { | 456 | { |
| 483 | if (CHARACTERP (object) || STRINGP (object)) | 457 | if (CHARACTERP (object) || STRINGP (object)) |
| @@ -486,7 +460,8 @@ DEFUN ("char-or-string-p", Fchar_or_string_p, Schar_or_string_p, 1, 1, 0, | |||
| 486 | } | 460 | } |
| 487 | 461 | ||
| 488 | DEFUN ("integerp", Fintegerp, Sintegerp, 1, 1, 0, | 462 | DEFUN ("integerp", Fintegerp, Sintegerp, 1, 1, 0, |
| 489 | doc: /* Return t if OBJECT is an integer. */) | 463 | doc: /* Return t if OBJECT is an integer. */ |
| 464 | attributes: const) | ||
| 490 | (Lisp_Object object) | 465 | (Lisp_Object object) |
| 491 | { | 466 | { |
| 492 | if (INTEGERP (object)) | 467 | if (INTEGERP (object)) |
| @@ -504,7 +479,8 @@ DEFUN ("integer-or-marker-p", Finteger_or_marker_p, Sinteger_or_marker_p, 1, 1, | |||
| 504 | } | 479 | } |
| 505 | 480 | ||
| 506 | DEFUN ("natnump", Fnatnump, Snatnump, 1, 1, 0, | 481 | DEFUN ("natnump", Fnatnump, Snatnump, 1, 1, 0, |
| 507 | doc: /* Return t if OBJECT is a nonnegative integer. */) | 482 | doc: /* Return t if OBJECT is a nonnegative integer. */ |
| 483 | attributes: const) | ||
| 508 | (Lisp_Object object) | 484 | (Lisp_Object object) |
| 509 | { | 485 | { |
| 510 | if (NATNUMP (object)) | 486 | if (NATNUMP (object)) |
| @@ -513,7 +489,8 @@ DEFUN ("natnump", Fnatnump, Snatnump, 1, 1, 0, | |||
| 513 | } | 489 | } |
| 514 | 490 | ||
| 515 | DEFUN ("numberp", Fnumberp, Snumberp, 1, 1, 0, | 491 | DEFUN ("numberp", Fnumberp, Snumberp, 1, 1, 0, |
| 516 | doc: /* Return t if OBJECT is a number (floating point or integer). */) | 492 | doc: /* Return t if OBJECT is a number (floating point or integer). */ |
| 493 | attributes: const) | ||
| 517 | (Lisp_Object object) | 494 | (Lisp_Object object) |
| 518 | { | 495 | { |
| 519 | if (NUMBERP (object)) | 496 | if (NUMBERP (object)) |
| @@ -533,7 +510,8 @@ DEFUN ("number-or-marker-p", Fnumber_or_marker_p, | |||
| 533 | } | 510 | } |
| 534 | 511 | ||
| 535 | DEFUN ("floatp", Ffloatp, Sfloatp, 1, 1, 0, | 512 | DEFUN ("floatp", Ffloatp, Sfloatp, 1, 1, 0, |
| 536 | doc: /* Return t if OBJECT is a floating point number. */) | 513 | doc: /* Return t if OBJECT is a floating point number. */ |
| 514 | attributes: const) | ||
| 537 | (Lisp_Object object) | 515 | (Lisp_Object object) |
| 538 | { | 516 | { |
| 539 | if (FLOATP (object)) | 517 | if (FLOATP (object)) |
| @@ -612,7 +590,7 @@ DEFUN ("setcar", Fsetcar, Ssetcar, 2, 2, 0, | |||
| 612 | (register Lisp_Object cell, Lisp_Object newcar) | 590 | (register Lisp_Object cell, Lisp_Object newcar) |
| 613 | { | 591 | { |
| 614 | CHECK_CONS (cell); | 592 | CHECK_CONS (cell); |
| 615 | CHECK_IMPURE (cell); | 593 | CHECK_IMPURE (cell, XCONS (cell)); |
| 616 | XSETCAR (cell, newcar); | 594 | XSETCAR (cell, newcar); |
| 617 | return newcar; | 595 | return newcar; |
| 618 | } | 596 | } |
| @@ -622,7 +600,7 @@ DEFUN ("setcdr", Fsetcdr, Ssetcdr, 2, 2, 0, | |||
| 622 | (register Lisp_Object cell, Lisp_Object newcdr) | 600 | (register Lisp_Object cell, Lisp_Object newcdr) |
| 623 | { | 601 | { |
| 624 | CHECK_CONS (cell); | 602 | CHECK_CONS (cell); |
| 625 | CHECK_IMPURE (cell); | 603 | CHECK_IMPURE (cell, XCONS (cell)); |
| 626 | XSETCDR (cell, newcdr); | 604 | XSETCDR (cell, newcdr); |
| 627 | return newcdr; | 605 | return newcdr; |
| 628 | } | 606 | } |
| @@ -650,7 +628,7 @@ global value outside of any lexical scope. */) | |||
| 650 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); | 628 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); |
| 651 | if (blv->fwd) | 629 | if (blv->fwd) |
| 652 | /* In set_internal, we un-forward vars when their value is | 630 | /* In set_internal, we un-forward vars when their value is |
| 653 | set to Qunbound. */ | 631 | set to Qunbound. */ |
| 654 | return Qt; | 632 | return Qt; |
| 655 | else | 633 | else |
| 656 | { | 634 | { |
| @@ -661,7 +639,7 @@ global value outside of any lexical scope. */) | |||
| 661 | } | 639 | } |
| 662 | case SYMBOL_FORWARDED: | 640 | case SYMBOL_FORWARDED: |
| 663 | /* In set_internal, we un-forward vars when their value is | 641 | /* In set_internal, we un-forward vars when their value is |
| 664 | set to Qunbound. */ | 642 | set to Qunbound. */ |
| 665 | return Qt; | 643 | return Qt; |
| 666 | default: emacs_abort (); | 644 | default: emacs_abort (); |
| 667 | } | 645 | } |
| @@ -703,7 +681,7 @@ Return SYMBOL. */) | |||
| 703 | } | 681 | } |
| 704 | 682 | ||
| 705 | DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, | 683 | DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, |
| 706 | doc: /* Return SYMBOL's function definition. Error if that is void. */) | 684 | doc: /* Return SYMBOL's function definition, or nil if that is void. */) |
| 707 | (register Lisp_Object symbol) | 685 | (register Lisp_Object symbol) |
| 708 | { | 686 | { |
| 709 | CHECK_SYMBOL (symbol); | 687 | CHECK_SYMBOL (symbol); |
| @@ -744,6 +722,11 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0, | |||
| 744 | if (AUTOLOADP (function)) | 722 | if (AUTOLOADP (function)) |
| 745 | Fput (symbol, Qautoload, XCDR (function)); | 723 | Fput (symbol, Qautoload, XCDR (function)); |
| 746 | 724 | ||
| 725 | /* Convert to eassert or remove after GC bug is found. In the | ||
| 726 | meantime, check unconditionally, at a slight perf hit. */ | ||
| 727 | if (! valid_lisp_object_p (definition)) | ||
| 728 | emacs_abort (); | ||
| 729 | |||
| 747 | set_symbol_function (symbol, definition); | 730 | set_symbol_function (symbol, definition); |
| 748 | 731 | ||
| 749 | return definition; | 732 | return definition; |
| @@ -755,6 +738,10 @@ Associates the function with the current load file, if any. | |||
| 755 | The optional third argument DOCSTRING specifies the documentation string | 738 | The optional third argument DOCSTRING specifies the documentation string |
| 756 | 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 |
| 757 | 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 | |||
| 758 | The return value is undefined. */) | 745 | The return value is undefined. */) |
| 759 | (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring) | 746 | (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring) |
| 760 | { | 747 | { |
| @@ -834,7 +821,7 @@ SUBR must be a built-in function. */) | |||
| 834 | DEFUN ("interactive-form", Finteractive_form, Sinteractive_form, 1, 1, 0, | 821 | DEFUN ("interactive-form", Finteractive_form, Sinteractive_form, 1, 1, 0, |
| 835 | doc: /* Return the interactive form of CMD or nil if none. | 822 | doc: /* Return the interactive form of CMD or nil if none. |
| 836 | If CMD is not a command, the return value is nil. | 823 | If CMD is not a command, the return value is nil. |
| 837 | Value, if non-nil, is a list \(interactive SPEC). */) | 824 | Value, if non-nil, is a list (interactive SPEC). */) |
| 838 | (Lisp_Object cmd) | 825 | (Lisp_Object cmd) |
| 839 | { | 826 | { |
| 840 | Lisp_Object fun = indirect_function (cmd); /* Check cycles. */ | 827 | Lisp_Object fun = indirect_function (cmd); /* Check cycles. */ |
| @@ -979,6 +966,50 @@ do_symval_forwarding (register union Lisp_Fwd *valcontents) | |||
| 979 | } | 966 | } |
| 980 | } | 967 | } |
| 981 | 968 | ||
| 969 | /* Used to signal a user-friendly error when symbol WRONG is | ||
| 970 | not a member of CHOICE, which should be a list of symbols. */ | ||
| 971 | |||
| 972 | void | ||
| 973 | wrong_choice (Lisp_Object choice, Lisp_Object wrong) | ||
| 974 | { | ||
| 975 | ptrdiff_t i = 0, len = XINT (Flength (choice)); | ||
| 976 | Lisp_Object obj, *args; | ||
| 977 | AUTO_STRING (one_of, "One of "); | ||
| 978 | AUTO_STRING (comma, ", "); | ||
| 979 | AUTO_STRING (or, " or "); | ||
| 980 | AUTO_STRING (should_be_specified, " should be specified"); | ||
| 981 | |||
| 982 | USE_SAFE_ALLOCA; | ||
| 983 | SAFE_ALLOCA_LISP (args, len * 2 + 1); | ||
| 984 | |||
| 985 | args[i++] = one_of; | ||
| 986 | |||
| 987 | for (obj = choice; !NILP (obj); obj = XCDR (obj)) | ||
| 988 | { | ||
| 989 | args[i++] = SYMBOL_NAME (XCAR (obj)); | ||
| 990 | args[i++] = (NILP (XCDR (obj)) ? should_be_specified | ||
| 991 | : NILP (XCDR (XCDR (obj))) ? or : comma); | ||
| 992 | } | ||
| 993 | |||
| 994 | obj = Fconcat (i, args); | ||
| 995 | SAFE_FREE (); | ||
| 996 | xsignal2 (Qerror, obj, wrong); | ||
| 997 | } | ||
| 998 | |||
| 999 | /* Used to signal a user-friendly error if WRONG is not a number or | ||
| 1000 | integer/floating-point number outsize of inclusive MIN..MAX range. */ | ||
| 1001 | |||
| 1002 | static void | ||
| 1003 | wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong) | ||
| 1004 | { | ||
| 1005 | AUTO_STRING (value_should_be_from, "Value should be from "); | ||
| 1006 | AUTO_STRING (to, " to "); | ||
| 1007 | xsignal2 (Qerror, | ||
| 1008 | CALLN (Fconcat, value_should_be_from, Fnumber_to_string (min), | ||
| 1009 | to, Fnumber_to_string (max)), | ||
| 1010 | wrong); | ||
| 1011 | } | ||
| 1012 | |||
| 982 | /* Store NEWVAL into SYMBOL, where VALCONTENTS is found in the value cell | 1013 | /* Store NEWVAL into SYMBOL, where VALCONTENTS is found in the value cell |
| 983 | of SYMBOL. If SYMBOL is buffer-local, VALCONTENTS should be the | 1014 | of SYMBOL. If SYMBOL is buffer-local, VALCONTENTS should be the |
| 984 | buffer-independent contents of the value cell: forwarded just one | 1015 | buffer-independent contents of the value cell: forwarded just one |
| @@ -1035,10 +1066,33 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva | |||
| 1035 | int offset = XBUFFER_OBJFWD (valcontents)->offset; | 1066 | int offset = XBUFFER_OBJFWD (valcontents)->offset; |
| 1036 | Lisp_Object predicate = XBUFFER_OBJFWD (valcontents)->predicate; | 1067 | Lisp_Object predicate = XBUFFER_OBJFWD (valcontents)->predicate; |
| 1037 | 1068 | ||
| 1038 | if (!NILP (predicate) && !NILP (newval) | 1069 | if (!NILP (newval)) |
| 1039 | && NILP (call1 (predicate, newval))) | 1070 | { |
| 1040 | wrong_type_argument (predicate, newval); | 1071 | if (SYMBOLP (predicate)) |
| 1072 | { | ||
| 1073 | Lisp_Object prop; | ||
| 1074 | |||
| 1075 | if ((prop = Fget (predicate, Qchoice), !NILP (prop))) | ||
| 1076 | { | ||
| 1077 | if (NILP (Fmemq (newval, prop))) | ||
| 1078 | wrong_choice (prop, newval); | ||
| 1079 | } | ||
| 1080 | else if ((prop = Fget (predicate, Qrange), !NILP (prop))) | ||
| 1081 | { | ||
| 1082 | Lisp_Object min = XCAR (prop), max = XCDR (prop); | ||
| 1041 | 1083 | ||
| 1084 | if (!NUMBERP (newval) | ||
| 1085 | || !NILP (arithcompare (newval, min, ARITH_LESS)) | ||
| 1086 | || !NILP (arithcompare (newval, max, ARITH_GRTR))) | ||
| 1087 | wrong_range (min, max, newval); | ||
| 1088 | } | ||
| 1089 | else if (FUNCTIONP (predicate)) | ||
| 1090 | { | ||
| 1091 | if (NILP (call1 (predicate, newval))) | ||
| 1092 | wrong_type_argument (predicate, newval); | ||
| 1093 | } | ||
| 1094 | } | ||
| 1095 | } | ||
| 1042 | if (buf == NULL) | 1096 | if (buf == NULL) |
| 1043 | buf = current_buffer; | 1097 | buf = current_buffer; |
| 1044 | set_per_buffer_value (buf, offset, newval); | 1098 | set_per_buffer_value (buf, offset, newval); |
| @@ -1254,10 +1308,10 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, | |||
| 1254 | 1308 | ||
| 1255 | /* Find the new binding. */ | 1309 | /* Find the new binding. */ |
| 1256 | XSETSYMBOL (symbol, sym); /* May have changed via aliasing. */ | 1310 | XSETSYMBOL (symbol, sym); /* May have changed via aliasing. */ |
| 1257 | tem1 = Fassq (symbol, | 1311 | tem1 = assq_no_quit (symbol, |
| 1258 | (blv->frame_local | 1312 | (blv->frame_local |
| 1259 | ? XFRAME (where)->param_alist | 1313 | ? XFRAME (where)->param_alist |
| 1260 | : BVAR (XBUFFER (where), local_var_alist))); | 1314 | : BVAR (XBUFFER (where), local_var_alist))); |
| 1261 | set_blv_where (blv, where); | 1315 | set_blv_where (blv, where); |
| 1262 | blv->found = 1; | 1316 | blv->found = 1; |
| 1263 | 1317 | ||
| @@ -1506,10 +1560,8 @@ usage: (setq-default [VAR VALUE]...) */) | |||
| 1506 | (Lisp_Object args) | 1560 | (Lisp_Object args) |
| 1507 | { | 1561 | { |
| 1508 | Lisp_Object args_left, symbol, val; | 1562 | Lisp_Object args_left, symbol, val; |
| 1509 | struct gcpro gcpro1; | ||
| 1510 | 1563 | ||
| 1511 | args_left = val = args; | 1564 | args_left = val = args; |
| 1512 | GCPRO1 (args); | ||
| 1513 | 1565 | ||
| 1514 | while (CONSP (args_left)) | 1566 | while (CONSP (args_left)) |
| 1515 | { | 1567 | { |
| @@ -1519,7 +1571,6 @@ usage: (setq-default [VAR VALUE]...) */) | |||
| 1519 | args_left = Fcdr (XCDR (args_left)); | 1571 | args_left = Fcdr (XCDR (args_left)); |
| 1520 | } | 1572 | } |
| 1521 | 1573 | ||
| 1522 | UNGCPRO; | ||
| 1523 | return val; | 1574 | return val; |
| 1524 | } | 1575 | } |
| 1525 | 1576 | ||
| @@ -1568,8 +1619,12 @@ Note that binding the variable with `let', or setting it while | |||
| 1568 | a `let'-style binding made in this buffer is in effect, | 1619 | a `let'-style binding made in this buffer is in effect, |
| 1569 | does not make the variable buffer-local. Return VARIABLE. | 1620 | does not make the variable buffer-local. Return VARIABLE. |
| 1570 | 1621 | ||
| 1571 | In most cases it is better to use `make-local-variable', | 1622 | This globally affects all uses of this variable, so it belongs together with |
| 1572 | which makes a variable local in just one buffer. | 1623 | the variable declaration, rather than with its uses (if you just want to make |
| 1624 | a variable local to the current buffer for one particular use, use | ||
| 1625 | `make-local-variable'). Buffer-local bindings are normally cleared | ||
| 1626 | while setting up a new major mode, unless they have a `permanent-local' | ||
| 1627 | property. | ||
| 1573 | 1628 | ||
| 1574 | The function `default-value' gets the default value and `set-default' sets it. */) | 1629 | The function `default-value' gets the default value and `set-default' sets it. */) |
| 1575 | (register Lisp_Object variable) | 1630 | (register Lisp_Object variable) |
| @@ -1620,8 +1675,10 @@ The function `default-value' gets the default value and `set-default' sets it. | |||
| 1620 | Lisp_Object symbol; | 1675 | Lisp_Object symbol; |
| 1621 | XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */ | 1676 | XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */ |
| 1622 | if (let_shadows_global_binding_p (symbol)) | 1677 | if (let_shadows_global_binding_p (symbol)) |
| 1623 | message ("Making %s buffer-local while let-bound!", | 1678 | { |
| 1624 | SDATA (SYMBOL_NAME (variable))); | 1679 | AUTO_STRING (format, "Making %s buffer-local while let-bound!"); |
| 1680 | CALLN (Fmessage, format, SYMBOL_NAME (variable)); | ||
| 1681 | } | ||
| 1625 | } | 1682 | } |
| 1626 | } | 1683 | } |
| 1627 | 1684 | ||
| @@ -1633,8 +1690,8 @@ DEFUN ("make-local-variable", Fmake_local_variable, Smake_local_variable, | |||
| 1633 | 1, 1, "vMake Local Variable: ", | 1690 | 1, 1, "vMake Local Variable: ", |
| 1634 | doc: /* Make VARIABLE have a separate value in the current buffer. | 1691 | doc: /* Make VARIABLE have a separate value in the current buffer. |
| 1635 | Other buffers will continue to share a common default value. | 1692 | Other buffers will continue to share a common default value. |
| 1636 | \(The buffer-local value of VARIABLE starts out as the same value | 1693 | (The buffer-local value of VARIABLE starts out as the same value |
| 1637 | VARIABLE previously had. If VARIABLE was void, it remains void.\) | 1694 | VARIABLE previously had. If VARIABLE was void, it remains void.) |
| 1638 | Return VARIABLE. | 1695 | Return VARIABLE. |
| 1639 | 1696 | ||
| 1640 | If the variable is already arranged to become local when set, | 1697 | If the variable is already arranged to become local when set, |
| @@ -1642,7 +1699,7 @@ this function causes a local value to exist for this buffer, | |||
| 1642 | just as setting the variable would do. | 1699 | just as setting the variable would do. |
| 1643 | 1700 | ||
| 1644 | This function returns VARIABLE, and therefore | 1701 | This function returns VARIABLE, and therefore |
| 1645 | (set (make-local-variable 'VARIABLE) VALUE-EXP) | 1702 | (set (make-local-variable \\='VARIABLE) VALUE-EXP) |
| 1646 | works. | 1703 | works. |
| 1647 | 1704 | ||
| 1648 | See also `make-variable-buffer-local'. | 1705 | See also `make-variable-buffer-local'. |
| @@ -1703,9 +1760,11 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */) | |||
| 1703 | Lisp_Object symbol; | 1760 | Lisp_Object symbol; |
| 1704 | XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */ | 1761 | XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */ |
| 1705 | if (let_shadows_global_binding_p (symbol)) | 1762 | if (let_shadows_global_binding_p (symbol)) |
| 1706 | message ("Making %s local to %s while let-bound!", | 1763 | { |
| 1707 | SDATA (SYMBOL_NAME (variable)), | 1764 | AUTO_STRING (format, "Making %s local to %s while let-bound!"); |
| 1708 | SDATA (BVAR (current_buffer, name))); | 1765 | CALLN (Fmessage, format, SYMBOL_NAME (variable), |
| 1766 | BVAR (current_buffer, name)); | ||
| 1767 | } | ||
| 1709 | } | 1768 | } |
| 1710 | } | 1769 | } |
| 1711 | 1770 | ||
| @@ -1715,8 +1774,11 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */) | |||
| 1715 | if (NILP (tem)) | 1774 | if (NILP (tem)) |
| 1716 | { | 1775 | { |
| 1717 | if (let_shadows_buffer_binding_p (sym)) | 1776 | if (let_shadows_buffer_binding_p (sym)) |
| 1718 | message ("Making %s buffer-local while locally let-bound!", | 1777 | { |
| 1719 | SDATA (SYMBOL_NAME (variable))); | 1778 | AUTO_STRING (format, |
| 1779 | "Making %s buffer-local while locally let-bound!"); | ||
| 1780 | CALLN (Fmessage, format, SYMBOL_NAME (variable)); | ||
| 1781 | } | ||
| 1720 | 1782 | ||
| 1721 | /* Swap out any local binding for some other buffer, and make | 1783 | /* Swap out any local binding for some other buffer, and make |
| 1722 | sure the current value is permanently recorded, if it's the | 1784 | sure the current value is permanently recorded, if it's the |
| @@ -1881,8 +1943,10 @@ frame-local bindings). */) | |||
| 1881 | Lisp_Object symbol; | 1943 | Lisp_Object symbol; |
| 1882 | XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */ | 1944 | XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */ |
| 1883 | if (let_shadows_global_binding_p (symbol)) | 1945 | if (let_shadows_global_binding_p (symbol)) |
| 1884 | message ("Making %s frame-local while let-bound!", | 1946 | { |
| 1885 | SDATA (SYMBOL_NAME (variable))); | 1947 | AUTO_STRING (format, "Making %s frame-local while let-bound!"); |
| 1948 | CALLN (Fmessage, format, SYMBOL_NAME (variable)); | ||
| 1949 | } | ||
| 1886 | } | 1950 | } |
| 1887 | return variable; | 1951 | return variable; |
| 1888 | } | 1952 | } |
| @@ -1891,19 +1955,11 @@ DEFUN ("local-variable-p", Flocal_variable_p, Slocal_variable_p, | |||
| 1891 | 1, 2, 0, | 1955 | 1, 2, 0, |
| 1892 | doc: /* Non-nil if VARIABLE has a local binding in buffer BUFFER. | 1956 | doc: /* Non-nil if VARIABLE has a local binding in buffer BUFFER. |
| 1893 | BUFFER defaults to the current buffer. */) | 1957 | BUFFER defaults to the current buffer. */) |
| 1894 | (register Lisp_Object variable, Lisp_Object buffer) | 1958 | (Lisp_Object variable, Lisp_Object buffer) |
| 1895 | { | 1959 | { |
| 1896 | register struct buffer *buf; | 1960 | struct buffer *buf = decode_buffer (buffer); |
| 1897 | struct Lisp_Symbol *sym; | 1961 | struct Lisp_Symbol *sym; |
| 1898 | 1962 | ||
| 1899 | if (NILP (buffer)) | ||
| 1900 | buf = current_buffer; | ||
| 1901 | else | ||
| 1902 | { | ||
| 1903 | CHECK_BUFFER (buffer); | ||
| 1904 | buf = XBUFFER (buffer); | ||
| 1905 | } | ||
| 1906 | |||
| 1907 | CHECK_SYMBOL (variable); | 1963 | CHECK_SYMBOL (variable); |
| 1908 | sym = XSYMBOL (variable); | 1964 | sym = XSYMBOL (variable); |
| 1909 | 1965 | ||
| @@ -2029,7 +2085,7 @@ If the current binding is global (the default), the value is nil. */) | |||
| 2029 | } | 2085 | } |
| 2030 | 2086 | ||
| 2031 | /* This code is disabled now that we use the selected frame to return | 2087 | /* This code is disabled now that we use the selected frame to return |
| 2032 | keyboard-local-values. */ | 2088 | keyboard-local-values. */ |
| 2033 | #if 0 | 2089 | #if 0 |
| 2034 | extern struct terminal *get_terminal (Lisp_Object display, int); | 2090 | extern struct terminal *get_terminal (Lisp_Object display, int); |
| 2035 | 2091 | ||
| @@ -2108,8 +2164,6 @@ DEFUN ("indirect-function", Findirect_function, Sindirect_function, 1, 2, 0, | |||
| 2108 | doc: /* Return the function at the end of OBJECT's function chain. | 2164 | doc: /* Return the function at the end of OBJECT's function chain. |
| 2109 | If OBJECT is not a symbol, just return it. Otherwise, follow all | 2165 | If OBJECT is not a symbol, just return it. Otherwise, follow all |
| 2110 | function indirections to find the final function binding and return it. | 2166 | function indirections to find the final function binding and return it. |
| 2111 | If the final symbol in the chain is unbound, signal a void-function error. | ||
| 2112 | Optional arg NOERROR non-nil means to return nil instead of signaling. | ||
| 2113 | Signal a cyclic-function-indirection error if there is a loop in the | 2167 | Signal a cyclic-function-indirection error if there is a loop in the |
| 2114 | function chain of symbols. */) | 2168 | function chain of symbols. */) |
| 2115 | (register Lisp_Object object, Lisp_Object noerror) | 2169 | (register Lisp_Object object, Lisp_Object noerror) |
| @@ -2124,9 +2178,6 @@ function chain of symbols. */) | |||
| 2124 | if (!NILP (result)) | 2178 | if (!NILP (result)) |
| 2125 | return result; | 2179 | return result; |
| 2126 | 2180 | ||
| 2127 | if (NILP (noerror)) | ||
| 2128 | xsignal1 (Qvoid_function, object); | ||
| 2129 | |||
| 2130 | return Qnil; | 2181 | return Qnil; |
| 2131 | } | 2182 | } |
| 2132 | 2183 | ||
| @@ -2158,13 +2209,9 @@ or a byte-code object. IDX starts at 0. */) | |||
| 2158 | } | 2209 | } |
| 2159 | else if (BOOL_VECTOR_P (array)) | 2210 | else if (BOOL_VECTOR_P (array)) |
| 2160 | { | 2211 | { |
| 2161 | int val; | 2212 | if (idxval < 0 || idxval >= bool_vector_size (array)) |
| 2162 | |||
| 2163 | if (idxval < 0 || idxval >= XBOOL_VECTOR (array)->size) | ||
| 2164 | args_out_of_range (array, idx); | 2213 | args_out_of_range (array, idx); |
| 2165 | 2214 | return bool_vector_ref (array, idxval); | |
| 2166 | val = (unsigned char) XBOOL_VECTOR (array)->data[idxval / BOOL_VECTOR_BITS_PER_CHAR]; | ||
| 2167 | return (val & (1 << (idxval % BOOL_VECTOR_BITS_PER_CHAR)) ? Qt : Qnil); | ||
| 2168 | } | 2215 | } |
| 2169 | else if (CHAR_TABLE_P (array)) | 2216 | else if (CHAR_TABLE_P (array)) |
| 2170 | { | 2217 | { |
| @@ -2198,28 +2245,19 @@ bool-vector. IDX starts at 0. */) | |||
| 2198 | CHECK_NUMBER (idx); | 2245 | CHECK_NUMBER (idx); |
| 2199 | idxval = XINT (idx); | 2246 | idxval = XINT (idx); |
| 2200 | CHECK_ARRAY (array, Qarrayp); | 2247 | CHECK_ARRAY (array, Qarrayp); |
| 2201 | CHECK_IMPURE (array); | ||
| 2202 | 2248 | ||
| 2203 | if (VECTORP (array)) | 2249 | if (VECTORP (array)) |
| 2204 | { | 2250 | { |
| 2251 | CHECK_IMPURE (array, XVECTOR (array)); | ||
| 2205 | if (idxval < 0 || idxval >= ASIZE (array)) | 2252 | if (idxval < 0 || idxval >= ASIZE (array)) |
| 2206 | args_out_of_range (array, idx); | 2253 | args_out_of_range (array, idx); |
| 2207 | ASET (array, idxval, newelt); | 2254 | ASET (array, idxval, newelt); |
| 2208 | } | 2255 | } |
| 2209 | else if (BOOL_VECTOR_P (array)) | 2256 | else if (BOOL_VECTOR_P (array)) |
| 2210 | { | 2257 | { |
| 2211 | int val; | 2258 | if (idxval < 0 || idxval >= bool_vector_size (array)) |
| 2212 | |||
| 2213 | if (idxval < 0 || idxval >= XBOOL_VECTOR (array)->size) | ||
| 2214 | args_out_of_range (array, idx); | 2259 | args_out_of_range (array, idx); |
| 2215 | 2260 | bool_vector_set (array, idxval, !NILP (newelt)); | |
| 2216 | val = (unsigned char) XBOOL_VECTOR (array)->data[idxval / BOOL_VECTOR_BITS_PER_CHAR]; | ||
| 2217 | |||
| 2218 | if (! NILP (newelt)) | ||
| 2219 | val |= 1 << (idxval % BOOL_VECTOR_BITS_PER_CHAR); | ||
| 2220 | else | ||
| 2221 | val &= ~(1 << (idxval % BOOL_VECTOR_BITS_PER_CHAR)); | ||
| 2222 | XBOOL_VECTOR (array)->data[idxval / BOOL_VECTOR_BITS_PER_CHAR] = val; | ||
| 2223 | } | 2261 | } |
| 2224 | else if (CHAR_TABLE_P (array)) | 2262 | else if (CHAR_TABLE_P (array)) |
| 2225 | { | 2263 | { |
| @@ -2230,6 +2268,7 @@ bool-vector. IDX starts at 0. */) | |||
| 2230 | { | 2268 | { |
| 2231 | int c; | 2269 | int c; |
| 2232 | 2270 | ||
| 2271 | CHECK_IMPURE (array, XSTRING (array)); | ||
| 2233 | if (idxval < 0 || idxval >= SCHARS (array)) | 2272 | if (idxval < 0 || idxval >= SCHARS (array)) |
| 2234 | args_out_of_range (array, idx); | 2273 | args_out_of_range (array, idx); |
| 2235 | CHECK_CHARACTER (newelt); | 2274 | CHECK_CHARACTER (newelt); |
| @@ -2270,7 +2309,7 @@ bool-vector. IDX starts at 0. */) | |||
| 2270 | { | 2309 | { |
| 2271 | if (! SINGLE_BYTE_CHAR_P (c)) | 2310 | if (! SINGLE_BYTE_CHAR_P (c)) |
| 2272 | { | 2311 | { |
| 2273 | int i; | 2312 | ptrdiff_t i; |
| 2274 | 2313 | ||
| 2275 | for (i = SBYTES (array) - 1; i >= 0; i--) | 2314 | for (i = SBYTES (array) - 1; i >= 0; i--) |
| 2276 | if (SREF (array, i) >= 0x80) | 2315 | if (SREF (array, i) >= 0x80) |
| @@ -2289,10 +2328,8 @@ bool-vector. IDX starts at 0. */) | |||
| 2289 | 2328 | ||
| 2290 | /* Arithmetic functions */ | 2329 | /* Arithmetic functions */ |
| 2291 | 2330 | ||
| 2292 | enum comparison { equal, notequal, less, grtr, less_or_equal, grtr_or_equal }; | 2331 | Lisp_Object |
| 2293 | 2332 | arithcompare (Lisp_Object num1, Lisp_Object num2, enum Arith_Comparison comparison) | |
| 2294 | static Lisp_Object | ||
| 2295 | arithcompare (Lisp_Object num1, Lisp_Object num2, enum comparison comparison) | ||
| 2296 | { | 2333 | { |
| 2297 | double f1 = 0, f2 = 0; | 2334 | double f1 = 0, f2 = 0; |
| 2298 | bool floatp = 0; | 2335 | bool floatp = 0; |
| @@ -2309,32 +2346,32 @@ arithcompare (Lisp_Object num1, Lisp_Object num2, enum comparison comparison) | |||
| 2309 | 2346 | ||
| 2310 | switch (comparison) | 2347 | switch (comparison) |
| 2311 | { | 2348 | { |
| 2312 | case equal: | 2349 | case ARITH_EQUAL: |
| 2313 | if (floatp ? f1 == f2 : XINT (num1) == XINT (num2)) | 2350 | if (floatp ? f1 == f2 : XINT (num1) == XINT (num2)) |
| 2314 | return Qt; | 2351 | return Qt; |
| 2315 | return Qnil; | 2352 | return Qnil; |
| 2316 | 2353 | ||
| 2317 | case notequal: | 2354 | case ARITH_NOTEQUAL: |
| 2318 | if (floatp ? f1 != f2 : XINT (num1) != XINT (num2)) | 2355 | if (floatp ? f1 != f2 : XINT (num1) != XINT (num2)) |
| 2319 | return Qt; | 2356 | return Qt; |
| 2320 | return Qnil; | 2357 | return Qnil; |
| 2321 | 2358 | ||
| 2322 | case less: | 2359 | case ARITH_LESS: |
| 2323 | if (floatp ? f1 < f2 : XINT (num1) < XINT (num2)) | 2360 | if (floatp ? f1 < f2 : XINT (num1) < XINT (num2)) |
| 2324 | return Qt; | 2361 | return Qt; |
| 2325 | return Qnil; | 2362 | return Qnil; |
| 2326 | 2363 | ||
| 2327 | case less_or_equal: | 2364 | case ARITH_LESS_OR_EQUAL: |
| 2328 | if (floatp ? f1 <= f2 : XINT (num1) <= XINT (num2)) | 2365 | if (floatp ? f1 <= f2 : XINT (num1) <= XINT (num2)) |
| 2329 | return Qt; | 2366 | return Qt; |
| 2330 | return Qnil; | 2367 | return Qnil; |
| 2331 | 2368 | ||
| 2332 | case grtr: | 2369 | case ARITH_GRTR: |
| 2333 | if (floatp ? f1 > f2 : XINT (num1) > XINT (num2)) | 2370 | if (floatp ? f1 > f2 : XINT (num1) > XINT (num2)) |
| 2334 | return Qt; | 2371 | return Qt; |
| 2335 | return Qnil; | 2372 | return Qnil; |
| 2336 | 2373 | ||
| 2337 | case grtr_or_equal: | 2374 | case ARITH_GRTR_OR_EQUAL: |
| 2338 | if (floatp ? f1 >= f2 : XINT (num1) >= XINT (num2)) | 2375 | if (floatp ? f1 >= f2 : XINT (num1) >= XINT (num2)) |
| 2339 | return Qt; | 2376 | return Qt; |
| 2340 | return Qnil; | 2377 | return Qnil; |
| @@ -2344,66 +2381,64 @@ arithcompare (Lisp_Object num1, Lisp_Object num2, enum comparison comparison) | |||
| 2344 | } | 2381 | } |
| 2345 | } | 2382 | } |
| 2346 | 2383 | ||
| 2347 | DEFUN ("=", Feqlsign, Seqlsign, 2, 2, 0, | 2384 | static Lisp_Object |
| 2348 | doc: /* Return t if two args, both numbers or markers, are equal. */) | 2385 | arithcompare_driver (ptrdiff_t nargs, Lisp_Object *args, |
| 2349 | (register Lisp_Object num1, Lisp_Object num2) | 2386 | enum Arith_Comparison comparison) |
| 2350 | { | 2387 | { |
| 2351 | return arithcompare (num1, num2, equal); | 2388 | ptrdiff_t argnum; |
| 2389 | for (argnum = 1; argnum < nargs; ++argnum) | ||
| 2390 | { | ||
| 2391 | if (EQ (Qnil, arithcompare (args[argnum - 1], args[argnum], comparison))) | ||
| 2392 | return Qnil; | ||
| 2393 | } | ||
| 2394 | return Qt; | ||
| 2352 | } | 2395 | } |
| 2353 | 2396 | ||
| 2354 | DEFUN ("<", Flss, Slss, 2, 2, 0, | 2397 | DEFUN ("=", Feqlsign, Seqlsign, 1, MANY, 0, |
| 2355 | doc: /* Return t if first arg is less than second arg. Both must be numbers or markers. */) | 2398 | doc: /* Return t if args, all numbers or markers, are equal. |
| 2356 | (register Lisp_Object num1, Lisp_Object num2) | 2399 | usage: (= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) |
| 2400 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 2357 | { | 2401 | { |
| 2358 | return arithcompare (num1, num2, less); | 2402 | return arithcompare_driver (nargs, args, ARITH_EQUAL); |
| 2359 | } | 2403 | } |
| 2360 | 2404 | ||
| 2361 | DEFUN (">", Fgtr, Sgtr, 2, 2, 0, | 2405 | DEFUN ("<", Flss, Slss, 1, MANY, 0, |
| 2362 | doc: /* Return t if first arg is greater than second arg. Both must be numbers or markers. */) | 2406 | doc: /* Return t if each arg (a number or marker), is less than the next arg. |
| 2363 | (register Lisp_Object num1, Lisp_Object num2) | 2407 | usage: (< NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) |
| 2408 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 2364 | { | 2409 | { |
| 2365 | return arithcompare (num1, num2, grtr); | 2410 | return arithcompare_driver (nargs, args, ARITH_LESS); |
| 2366 | } | 2411 | } |
| 2367 | 2412 | ||
| 2368 | DEFUN ("<=", Fleq, Sleq, 2, 2, 0, | 2413 | DEFUN (">", Fgtr, Sgtr, 1, MANY, 0, |
| 2369 | doc: /* Return t if first arg is less than or equal to second arg. | 2414 | doc: /* Return t if each arg (a number or marker) is greater than the next arg. |
| 2370 | Both must be numbers or markers. */) | 2415 | usage: (> NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) |
| 2371 | (register Lisp_Object num1, Lisp_Object num2) | 2416 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2372 | { | 2417 | { |
| 2373 | return arithcompare (num1, num2, less_or_equal); | 2418 | return arithcompare_driver (nargs, args, ARITH_GRTR); |
| 2374 | } | 2419 | } |
| 2375 | 2420 | ||
| 2376 | DEFUN (">=", Fgeq, Sgeq, 2, 2, 0, | 2421 | DEFUN ("<=", Fleq, Sleq, 1, MANY, 0, |
| 2377 | doc: /* Return t if first arg is greater than or equal to second arg. | 2422 | doc: /* Return t if each arg (a number or marker) is less than or equal to the next. |
| 2378 | Both must be numbers or markers. */) | 2423 | usage: (<= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) |
| 2379 | (register Lisp_Object num1, Lisp_Object num2) | 2424 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2380 | { | 2425 | { |
| 2381 | return arithcompare (num1, num2, grtr_or_equal); | 2426 | return arithcompare_driver (nargs, args, ARITH_LESS_OR_EQUAL); |
| 2382 | } | 2427 | } |
| 2383 | 2428 | ||
| 2384 | DEFUN ("/=", Fneq, Sneq, 2, 2, 0, | 2429 | DEFUN (">=", Fgeq, Sgeq, 1, MANY, 0, |
| 2385 | doc: /* Return t if first arg is not equal to second arg. Both must be numbers or markers. */) | 2430 | doc: /* Return t if each arg (a number or marker) is greater than or equal to the next. |
| 2386 | (register Lisp_Object num1, Lisp_Object num2) | 2431 | usage: (>= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) |
| 2432 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 2387 | { | 2433 | { |
| 2388 | return arithcompare (num1, num2, notequal); | 2434 | return arithcompare_driver (nargs, args, ARITH_GRTR_OR_EQUAL); |
| 2389 | } | 2435 | } |
| 2390 | 2436 | ||
| 2391 | DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0, | 2437 | DEFUN ("/=", Fneq, Sneq, 2, 2, 0, |
| 2392 | doc: /* Return t if NUMBER is zero. */) | 2438 | doc: /* Return t if first arg is not equal to second arg. Both must be numbers or markers. */) |
| 2393 | (register Lisp_Object number) | 2439 | (register Lisp_Object num1, Lisp_Object num2) |
| 2394 | { | 2440 | { |
| 2395 | CHECK_NUMBER_OR_FLOAT (number); | 2441 | return arithcompare (num1, num2, ARITH_NOTEQUAL); |
| 2396 | |||
| 2397 | if (FLOATP (number)) | ||
| 2398 | { | ||
| 2399 | if (XFLOAT_DATA (number) == 0.0) | ||
| 2400 | return Qt; | ||
| 2401 | return Qnil; | ||
| 2402 | } | ||
| 2403 | |||
| 2404 | if (!XINT (number)) | ||
| 2405 | return Qt; | ||
| 2406 | return Qnil; | ||
| 2407 | } | 2442 | } |
| 2408 | 2443 | ||
| 2409 | /* Convert the cons-of-integers, integer, or float value C to an | 2444 | /* Convert the cons-of-integers, integer, or float value C to an |
| @@ -2533,12 +2568,12 @@ NUMBER may be an integer or a floating point number. */) | |||
| 2533 | 2568 | ||
| 2534 | DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0, | 2569 | DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0, |
| 2535 | doc: /* Parse STRING as a decimal number and return the number. | 2570 | doc: /* Parse STRING as a decimal number and return the number. |
| 2536 | This parses both integers and floating point numbers. | 2571 | Ignore leading spaces and tabs, and all trailing chars. Return 0 if |
| 2537 | It ignores leading spaces and tabs, and all trailing chars. | 2572 | STRING cannot be parsed as an integer or floating point number. |
| 2538 | 2573 | ||
| 2539 | If BASE, interpret STRING as a number in that base. If BASE isn't | 2574 | If BASE, interpret STRING as a number in that base. If BASE isn't |
| 2540 | present, base 10 is used. BASE must be between 2 and 16 (inclusive). | 2575 | present, base 10 is used. BASE must be between 2 and 16 (inclusive). |
| 2541 | If the base used is not 10, STRING is always parsed as integer. */) | 2576 | If the base used is not 10, STRING is always parsed as an integer. */) |
| 2542 | (register Lisp_Object string, Lisp_Object base) | 2577 | (register Lisp_Object string, Lisp_Object base) |
| 2543 | { | 2578 | { |
| 2544 | register char *p; | 2579 | register char *p; |
| @@ -2598,6 +2633,7 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) | |||
| 2598 | accum = 0; | 2633 | accum = 0; |
| 2599 | break; | 2634 | break; |
| 2600 | case Amult: | 2635 | case Amult: |
| 2636 | case Adiv: | ||
| 2601 | accum = 1; | 2637 | accum = 1; |
| 2602 | break; | 2638 | break; |
| 2603 | case Alogand: | 2639 | case Alogand: |
| @@ -2653,7 +2689,7 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) | |||
| 2653 | accum *= next; | 2689 | accum *= next; |
| 2654 | break; | 2690 | break; |
| 2655 | case Adiv: | 2691 | case Adiv: |
| 2656 | if (!argnum) | 2692 | if (! (argnum || nargs == 1)) |
| 2657 | accum = next; | 2693 | accum = next; |
| 2658 | else | 2694 | else |
| 2659 | { | 2695 | { |
| @@ -2722,7 +2758,7 @@ float_arith_driver (double accum, ptrdiff_t argnum, enum arithop code, | |||
| 2722 | accum *= next; | 2758 | accum *= next; |
| 2723 | break; | 2759 | break; |
| 2724 | case Adiv: | 2760 | case Adiv: |
| 2725 | if (!argnum) | 2761 | if (! (argnum || nargs == 1)) |
| 2726 | accum = next; | 2762 | accum = next; |
| 2727 | else | 2763 | else |
| 2728 | { | 2764 | { |
| @@ -2777,9 +2813,11 @@ usage: (* &rest NUMBERS-OR-MARKERS) */) | |||
| 2777 | } | 2813 | } |
| 2778 | 2814 | ||
| 2779 | DEFUN ("/", Fquo, Squo, 1, MANY, 0, | 2815 | DEFUN ("/", Fquo, Squo, 1, MANY, 0, |
| 2780 | doc: /* Return first argument divided by all the remaining arguments. | 2816 | doc: /* Divide number by divisors and return the result. |
| 2817 | With two or more arguments, return first argument divided by the rest. | ||
| 2818 | With one argument, return 1 divided by the argument. | ||
| 2781 | The arguments must be numbers or markers. | 2819 | The arguments must be numbers or markers. |
| 2782 | usage: (/ DIVIDEND &rest DIVISORS) */) | 2820 | usage: (/ NUMBER &rest DIVISORS) */) |
| 2783 | (ptrdiff_t nargs, Lisp_Object *args) | 2821 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2784 | { | 2822 | { |
| 2785 | ptrdiff_t argnum; | 2823 | ptrdiff_t argnum; |
| @@ -2896,7 +2934,7 @@ In this case, the sign bit is duplicated. */) | |||
| 2896 | if (XINT (count) >= BITS_PER_EMACS_INT) | 2934 | if (XINT (count) >= BITS_PER_EMACS_INT) |
| 2897 | XSETINT (val, 0); | 2935 | XSETINT (val, 0); |
| 2898 | else if (XINT (count) > 0) | 2936 | else if (XINT (count) > 0) |
| 2899 | XSETINT (val, XINT (value) << XFASTINT (count)); | 2937 | XSETINT (val, XUINT (value) << XFASTINT (count)); |
| 2900 | else if (XINT (count) <= -BITS_PER_EMACS_INT) | 2938 | else if (XINT (count) <= -BITS_PER_EMACS_INT) |
| 2901 | XSETINT (val, XINT (value) < 0 ? -1 : 0); | 2939 | XSETINT (val, XINT (value) < 0 ? -1 : 0); |
| 2902 | else | 2940 | else |
| @@ -2966,7 +3004,8 @@ DEFUN ("lognot", Flognot, Slognot, 1, 1, 0, | |||
| 2966 | DEFUN ("byteorder", Fbyteorder, Sbyteorder, 0, 0, 0, | 3004 | DEFUN ("byteorder", Fbyteorder, Sbyteorder, 0, 0, 0, |
| 2967 | doc: /* Return the byteorder for the machine. | 3005 | doc: /* Return the byteorder for the machine. |
| 2968 | Returns 66 (ASCII uppercase B) for big endian machines or 108 (ASCII | 3006 | Returns 66 (ASCII uppercase B) for big endian machines or 108 (ASCII |
| 2969 | lowercase l) for small endian machines. */) | 3007 | lowercase l) for small endian machines. */ |
| 3008 | attributes: const) | ||
| 2970 | (void) | 3009 | (void) |
| 2971 | { | 3010 | { |
| 2972 | unsigned i = 0x04030201; | 3011 | unsigned i = 0x04030201; |
| @@ -2975,6 +3014,434 @@ lowercase l) for small endian machines. */) | |||
| 2975 | return make_number (order); | 3014 | return make_number (order); |
| 2976 | } | 3015 | } |
| 2977 | 3016 | ||
| 3017 | /* Because we round up the bool vector allocate size to word_size | ||
| 3018 | units, we can safely read past the "end" of the vector in the | ||
| 3019 | operations below. These extra bits are always zero. */ | ||
| 3020 | |||
| 3021 | static bits_word | ||
| 3022 | bool_vector_spare_mask (EMACS_INT nr_bits) | ||
| 3023 | { | ||
| 3024 | return (((bits_word) 1) << (nr_bits % BITS_PER_BITS_WORD)) - 1; | ||
| 3025 | } | ||
| 3026 | |||
| 3027 | /* Info about unsigned long long, falling back on unsigned long | ||
| 3028 | if unsigned long long is not available. */ | ||
| 3029 | |||
| 3030 | #if HAVE_UNSIGNED_LONG_LONG_INT && defined ULLONG_MAX | ||
| 3031 | enum { BITS_PER_ULL = CHAR_BIT * sizeof (unsigned long long) }; | ||
| 3032 | # define ULL_MAX ULLONG_MAX | ||
| 3033 | #else | ||
| 3034 | enum { BITS_PER_ULL = CHAR_BIT * sizeof (unsigned long) }; | ||
| 3035 | # define ULL_MAX ULONG_MAX | ||
| 3036 | # define count_one_bits_ll count_one_bits_l | ||
| 3037 | # define count_trailing_zeros_ll count_trailing_zeros_l | ||
| 3038 | #endif | ||
| 3039 | |||
| 3040 | /* Shift VAL right by the width of an unsigned long long. | ||
| 3041 | BITS_PER_ULL must be less than BITS_PER_BITS_WORD. */ | ||
| 3042 | |||
| 3043 | static bits_word | ||
| 3044 | shift_right_ull (bits_word w) | ||
| 3045 | { | ||
| 3046 | /* Pacify bogus GCC warning about shift count exceeding type width. */ | ||
| 3047 | int shift = BITS_PER_ULL - BITS_PER_BITS_WORD < 0 ? BITS_PER_ULL : 0; | ||
| 3048 | return w >> shift; | ||
| 3049 | } | ||
| 3050 | |||
| 3051 | /* Return the number of 1 bits in W. */ | ||
| 3052 | |||
| 3053 | static int | ||
| 3054 | count_one_bits_word (bits_word w) | ||
| 3055 | { | ||
| 3056 | if (BITS_WORD_MAX <= UINT_MAX) | ||
| 3057 | return count_one_bits (w); | ||
| 3058 | else if (BITS_WORD_MAX <= ULONG_MAX) | ||
| 3059 | return count_one_bits_l (w); | ||
| 3060 | else | ||
| 3061 | { | ||
| 3062 | int i = 0, count = 0; | ||
| 3063 | while (count += count_one_bits_ll (w), | ||
| 3064 | (i += BITS_PER_ULL) < BITS_PER_BITS_WORD) | ||
| 3065 | w = shift_right_ull (w); | ||
| 3066 | return count; | ||
| 3067 | } | ||
| 3068 | } | ||
| 3069 | |||
| 3070 | enum bool_vector_op { bool_vector_exclusive_or, | ||
| 3071 | bool_vector_union, | ||
| 3072 | bool_vector_intersection, | ||
| 3073 | bool_vector_set_difference, | ||
| 3074 | bool_vector_subsetp }; | ||
| 3075 | |||
| 3076 | static Lisp_Object | ||
| 3077 | bool_vector_binop_driver (Lisp_Object a, | ||
| 3078 | Lisp_Object b, | ||
| 3079 | Lisp_Object dest, | ||
| 3080 | enum bool_vector_op op) | ||
| 3081 | { | ||
| 3082 | EMACS_INT nr_bits; | ||
| 3083 | bits_word *adata, *bdata, *destdata; | ||
| 3084 | ptrdiff_t i = 0; | ||
| 3085 | ptrdiff_t nr_words; | ||
| 3086 | |||
| 3087 | CHECK_BOOL_VECTOR (a); | ||
| 3088 | CHECK_BOOL_VECTOR (b); | ||
| 3089 | |||
| 3090 | nr_bits = bool_vector_size (a); | ||
| 3091 | if (bool_vector_size (b) != nr_bits) | ||
| 3092 | wrong_length_argument (a, b, dest); | ||
| 3093 | |||
| 3094 | nr_words = bool_vector_words (nr_bits); | ||
| 3095 | adata = bool_vector_data (a); | ||
| 3096 | bdata = bool_vector_data (b); | ||
| 3097 | |||
| 3098 | if (NILP (dest)) | ||
| 3099 | { | ||
| 3100 | dest = make_uninit_bool_vector (nr_bits); | ||
| 3101 | destdata = bool_vector_data (dest); | ||
| 3102 | } | ||
| 3103 | else | ||
| 3104 | { | ||
| 3105 | CHECK_BOOL_VECTOR (dest); | ||
| 3106 | destdata = bool_vector_data (dest); | ||
| 3107 | if (bool_vector_size (dest) != nr_bits) | ||
| 3108 | wrong_length_argument (a, b, dest); | ||
| 3109 | |||
| 3110 | switch (op) | ||
| 3111 | { | ||
| 3112 | case bool_vector_exclusive_or: | ||
| 3113 | for (; i < nr_words; i++) | ||
| 3114 | if (destdata[i] != (adata[i] ^ bdata[i])) | ||
| 3115 | goto set_dest; | ||
| 3116 | break; | ||
| 3117 | |||
| 3118 | case bool_vector_subsetp: | ||
| 3119 | for (; i < nr_words; i++) | ||
| 3120 | if (adata[i] &~ bdata[i]) | ||
| 3121 | return Qnil; | ||
| 3122 | return Qt; | ||
| 3123 | |||
| 3124 | case bool_vector_union: | ||
| 3125 | for (; i < nr_words; i++) | ||
| 3126 | if (destdata[i] != (adata[i] | bdata[i])) | ||
| 3127 | goto set_dest; | ||
| 3128 | break; | ||
| 3129 | |||
| 3130 | case bool_vector_intersection: | ||
| 3131 | for (; i < nr_words; i++) | ||
| 3132 | if (destdata[i] != (adata[i] & bdata[i])) | ||
| 3133 | goto set_dest; | ||
| 3134 | break; | ||
| 3135 | |||
| 3136 | case bool_vector_set_difference: | ||
| 3137 | for (; i < nr_words; i++) | ||
| 3138 | if (destdata[i] != (adata[i] &~ bdata[i])) | ||
| 3139 | goto set_dest; | ||
| 3140 | break; | ||
| 3141 | } | ||
| 3142 | |||
| 3143 | return Qnil; | ||
| 3144 | } | ||
| 3145 | |||
| 3146 | set_dest: | ||
| 3147 | switch (op) | ||
| 3148 | { | ||
| 3149 | case bool_vector_exclusive_or: | ||
| 3150 | for (; i < nr_words; i++) | ||
| 3151 | destdata[i] = adata[i] ^ bdata[i]; | ||
| 3152 | break; | ||
| 3153 | |||
| 3154 | case bool_vector_union: | ||
| 3155 | for (; i < nr_words; i++) | ||
| 3156 | destdata[i] = adata[i] | bdata[i]; | ||
| 3157 | break; | ||
| 3158 | |||
| 3159 | case bool_vector_intersection: | ||
| 3160 | for (; i < nr_words; i++) | ||
| 3161 | destdata[i] = adata[i] & bdata[i]; | ||
| 3162 | break; | ||
| 3163 | |||
| 3164 | case bool_vector_set_difference: | ||
| 3165 | for (; i < nr_words; i++) | ||
| 3166 | destdata[i] = adata[i] &~ bdata[i]; | ||
| 3167 | break; | ||
| 3168 | |||
| 3169 | default: | ||
| 3170 | eassume (0); | ||
| 3171 | } | ||
| 3172 | |||
| 3173 | return dest; | ||
| 3174 | } | ||
| 3175 | |||
| 3176 | /* PRECONDITION must be true. Return VALUE. This odd construction | ||
| 3177 | works around a bogus GCC diagnostic "shift count >= width of type". */ | ||
| 3178 | |||
| 3179 | static int | ||
| 3180 | pre_value (bool precondition, int value) | ||
| 3181 | { | ||
| 3182 | eassume (precondition); | ||
| 3183 | return precondition ? value : 0; | ||
| 3184 | } | ||
| 3185 | |||
| 3186 | /* Compute the number of trailing zero bits in val. If val is zero, | ||
| 3187 | return the number of bits in val. */ | ||
| 3188 | static int | ||
| 3189 | count_trailing_zero_bits (bits_word val) | ||
| 3190 | { | ||
| 3191 | if (BITS_WORD_MAX == UINT_MAX) | ||
| 3192 | return count_trailing_zeros (val); | ||
| 3193 | if (BITS_WORD_MAX == ULONG_MAX) | ||
| 3194 | return count_trailing_zeros_l (val); | ||
| 3195 | if (BITS_WORD_MAX == ULL_MAX) | ||
| 3196 | return count_trailing_zeros_ll (val); | ||
| 3197 | |||
| 3198 | /* The rest of this code is for the unlikely platform where bits_word differs | ||
| 3199 | in width from unsigned int, unsigned long, and unsigned long long. */ | ||
| 3200 | val |= ~ BITS_WORD_MAX; | ||
| 3201 | if (BITS_WORD_MAX <= UINT_MAX) | ||
| 3202 | return count_trailing_zeros (val); | ||
| 3203 | if (BITS_WORD_MAX <= ULONG_MAX) | ||
| 3204 | return count_trailing_zeros_l (val); | ||
| 3205 | else | ||
| 3206 | { | ||
| 3207 | int count; | ||
| 3208 | for (count = 0; | ||
| 3209 | count < BITS_PER_BITS_WORD - BITS_PER_ULL; | ||
| 3210 | count += BITS_PER_ULL) | ||
| 3211 | { | ||
| 3212 | if (val & ULL_MAX) | ||
| 3213 | return count + count_trailing_zeros_ll (val); | ||
| 3214 | val = shift_right_ull (val); | ||
| 3215 | } | ||
| 3216 | |||
| 3217 | if (BITS_PER_BITS_WORD % BITS_PER_ULL != 0 | ||
| 3218 | && BITS_WORD_MAX == (bits_word) -1) | ||
| 3219 | val |= (bits_word) 1 << pre_value (ULONG_MAX < BITS_WORD_MAX, | ||
| 3220 | BITS_PER_BITS_WORD % BITS_PER_ULL); | ||
| 3221 | return count + count_trailing_zeros_ll (val); | ||
| 3222 | } | ||
| 3223 | } | ||
| 3224 | |||
| 3225 | static bits_word | ||
| 3226 | bits_word_to_host_endian (bits_word val) | ||
| 3227 | { | ||
| 3228 | #ifndef WORDS_BIGENDIAN | ||
| 3229 | return val; | ||
| 3230 | #else | ||
| 3231 | if (BITS_WORD_MAX >> 31 == 1) | ||
| 3232 | return bswap_32 (val); | ||
| 3233 | # if HAVE_UNSIGNED_LONG_LONG | ||
| 3234 | if (BITS_WORD_MAX >> 31 >> 31 >> 1 == 1) | ||
| 3235 | return bswap_64 (val); | ||
| 3236 | # endif | ||
| 3237 | { | ||
| 3238 | int i; | ||
| 3239 | bits_word r = 0; | ||
| 3240 | for (i = 0; i < sizeof val; i++) | ||
| 3241 | { | ||
| 3242 | r = ((r << 1 << (CHAR_BIT - 1)) | ||
| 3243 | | (val & ((1u << 1 << (CHAR_BIT - 1)) - 1))); | ||
| 3244 | val = val >> 1 >> (CHAR_BIT - 1); | ||
| 3245 | } | ||
| 3246 | return r; | ||
| 3247 | } | ||
| 3248 | #endif | ||
| 3249 | } | ||
| 3250 | |||
| 3251 | DEFUN ("bool-vector-exclusive-or", Fbool_vector_exclusive_or, | ||
| 3252 | Sbool_vector_exclusive_or, 2, 3, 0, | ||
| 3253 | doc: /* Return A ^ B, bitwise exclusive or. | ||
| 3254 | If optional third argument C is given, store result into C. | ||
| 3255 | A, B, and C must be bool vectors of the same length. | ||
| 3256 | Return the destination vector if it changed or nil otherwise. */) | ||
| 3257 | (Lisp_Object a, Lisp_Object b, Lisp_Object c) | ||
| 3258 | { | ||
| 3259 | return bool_vector_binop_driver (a, b, c, bool_vector_exclusive_or); | ||
| 3260 | } | ||
| 3261 | |||
| 3262 | DEFUN ("bool-vector-union", Fbool_vector_union, | ||
| 3263 | Sbool_vector_union, 2, 3, 0, | ||
| 3264 | doc: /* Return A | B, bitwise or. | ||
| 3265 | If optional third argument C is given, store result into C. | ||
| 3266 | A, B, and C must be bool vectors of the same length. | ||
| 3267 | Return the destination vector if it changed or nil otherwise. */) | ||
| 3268 | (Lisp_Object a, Lisp_Object b, Lisp_Object c) | ||
| 3269 | { | ||
| 3270 | return bool_vector_binop_driver (a, b, c, bool_vector_union); | ||
| 3271 | } | ||
| 3272 | |||
| 3273 | DEFUN ("bool-vector-intersection", Fbool_vector_intersection, | ||
| 3274 | Sbool_vector_intersection, 2, 3, 0, | ||
| 3275 | doc: /* Return A & B, bitwise and. | ||
| 3276 | If optional third argument C is given, store result into C. | ||
| 3277 | A, B, and C must be bool vectors of the same length. | ||
| 3278 | Return the destination vector if it changed or nil otherwise. */) | ||
| 3279 | (Lisp_Object a, Lisp_Object b, Lisp_Object c) | ||
| 3280 | { | ||
| 3281 | return bool_vector_binop_driver (a, b, c, bool_vector_intersection); | ||
| 3282 | } | ||
| 3283 | |||
| 3284 | DEFUN ("bool-vector-set-difference", Fbool_vector_set_difference, | ||
| 3285 | Sbool_vector_set_difference, 2, 3, 0, | ||
| 3286 | doc: /* Return A &~ B, set difference. | ||
| 3287 | If optional third argument C is given, store result into C. | ||
| 3288 | A, B, and C must be bool vectors of the same length. | ||
| 3289 | Return the destination vector if it changed or nil otherwise. */) | ||
| 3290 | (Lisp_Object a, Lisp_Object b, Lisp_Object c) | ||
| 3291 | { | ||
| 3292 | return bool_vector_binop_driver (a, b, c, bool_vector_set_difference); | ||
| 3293 | } | ||
| 3294 | |||
| 3295 | DEFUN ("bool-vector-subsetp", Fbool_vector_subsetp, | ||
| 3296 | Sbool_vector_subsetp, 2, 2, 0, | ||
| 3297 | doc: /* Return t if every t value in A is also t in B, nil otherwise. | ||
| 3298 | A and B must be bool vectors of the same length. */) | ||
| 3299 | (Lisp_Object a, Lisp_Object b) | ||
| 3300 | { | ||
| 3301 | return bool_vector_binop_driver (a, b, b, bool_vector_subsetp); | ||
| 3302 | } | ||
| 3303 | |||
| 3304 | DEFUN ("bool-vector-not", Fbool_vector_not, | ||
| 3305 | Sbool_vector_not, 1, 2, 0, | ||
| 3306 | doc: /* Compute ~A, set complement. | ||
| 3307 | If optional second argument B is given, store result into B. | ||
| 3308 | A and B must be bool vectors of the same length. | ||
| 3309 | Return the destination vector. */) | ||
| 3310 | (Lisp_Object a, Lisp_Object b) | ||
| 3311 | { | ||
| 3312 | EMACS_INT nr_bits; | ||
| 3313 | bits_word *bdata, *adata; | ||
| 3314 | ptrdiff_t i; | ||
| 3315 | |||
| 3316 | CHECK_BOOL_VECTOR (a); | ||
| 3317 | nr_bits = bool_vector_size (a); | ||
| 3318 | |||
| 3319 | if (NILP (b)) | ||
| 3320 | b = make_uninit_bool_vector (nr_bits); | ||
| 3321 | else | ||
| 3322 | { | ||
| 3323 | CHECK_BOOL_VECTOR (b); | ||
| 3324 | if (bool_vector_size (b) != nr_bits) | ||
| 3325 | wrong_length_argument (a, b, Qnil); | ||
| 3326 | } | ||
| 3327 | |||
| 3328 | bdata = bool_vector_data (b); | ||
| 3329 | adata = bool_vector_data (a); | ||
| 3330 | |||
| 3331 | for (i = 0; i < nr_bits / BITS_PER_BITS_WORD; i++) | ||
| 3332 | bdata[i] = BITS_WORD_MAX & ~adata[i]; | ||
| 3333 | |||
| 3334 | if (nr_bits % BITS_PER_BITS_WORD) | ||
| 3335 | { | ||
| 3336 | bits_word mword = bits_word_to_host_endian (adata[i]); | ||
| 3337 | mword = ~mword; | ||
| 3338 | mword &= bool_vector_spare_mask (nr_bits); | ||
| 3339 | bdata[i] = bits_word_to_host_endian (mword); | ||
| 3340 | } | ||
| 3341 | |||
| 3342 | return b; | ||
| 3343 | } | ||
| 3344 | |||
| 3345 | DEFUN ("bool-vector-count-population", Fbool_vector_count_population, | ||
| 3346 | Sbool_vector_count_population, 1, 1, 0, | ||
| 3347 | doc: /* Count how many elements in A are t. | ||
| 3348 | A is a bool vector. To count A's nil elements, subtract the return | ||
| 3349 | value from A's length. */) | ||
| 3350 | (Lisp_Object a) | ||
| 3351 | { | ||
| 3352 | EMACS_INT count; | ||
| 3353 | EMACS_INT nr_bits; | ||
| 3354 | bits_word *adata; | ||
| 3355 | ptrdiff_t i, nwords; | ||
| 3356 | |||
| 3357 | CHECK_BOOL_VECTOR (a); | ||
| 3358 | |||
| 3359 | nr_bits = bool_vector_size (a); | ||
| 3360 | nwords = bool_vector_words (nr_bits); | ||
| 3361 | count = 0; | ||
| 3362 | adata = bool_vector_data (a); | ||
| 3363 | |||
| 3364 | for (i = 0; i < nwords; i++) | ||
| 3365 | count += count_one_bits_word (adata[i]); | ||
| 3366 | |||
| 3367 | return make_number (count); | ||
| 3368 | } | ||
| 3369 | |||
| 3370 | DEFUN ("bool-vector-count-consecutive", Fbool_vector_count_consecutive, | ||
| 3371 | Sbool_vector_count_consecutive, 3, 3, 0, | ||
| 3372 | doc: /* Count how many consecutive elements in A equal B starting at I. | ||
| 3373 | A is a bool vector, B is t or nil, and I is an index into A. */) | ||
| 3374 | (Lisp_Object a, Lisp_Object b, Lisp_Object i) | ||
| 3375 | { | ||
| 3376 | EMACS_INT count; | ||
| 3377 | EMACS_INT nr_bits; | ||
| 3378 | int offset; | ||
| 3379 | bits_word *adata; | ||
| 3380 | bits_word twiddle; | ||
| 3381 | bits_word mword; /* Machine word. */ | ||
| 3382 | ptrdiff_t pos, pos0; | ||
| 3383 | ptrdiff_t nr_words; | ||
| 3384 | |||
| 3385 | CHECK_BOOL_VECTOR (a); | ||
| 3386 | CHECK_NATNUM (i); | ||
| 3387 | |||
| 3388 | nr_bits = bool_vector_size (a); | ||
| 3389 | if (XFASTINT (i) > nr_bits) /* Allow one past the end for convenience */ | ||
| 3390 | args_out_of_range (a, i); | ||
| 3391 | |||
| 3392 | adata = bool_vector_data (a); | ||
| 3393 | nr_words = bool_vector_words (nr_bits); | ||
| 3394 | pos = XFASTINT (i) / BITS_PER_BITS_WORD; | ||
| 3395 | offset = XFASTINT (i) % BITS_PER_BITS_WORD; | ||
| 3396 | count = 0; | ||
| 3397 | |||
| 3398 | /* By XORing with twiddle, we transform the problem of "count | ||
| 3399 | consecutive equal values" into "count the zero bits". The latter | ||
| 3400 | operation usually has hardware support. */ | ||
| 3401 | twiddle = NILP (b) ? 0 : BITS_WORD_MAX; | ||
| 3402 | |||
| 3403 | /* Scan the remainder of the mword at the current offset. */ | ||
| 3404 | if (pos < nr_words && offset != 0) | ||
| 3405 | { | ||
| 3406 | mword = bits_word_to_host_endian (adata[pos]); | ||
| 3407 | mword ^= twiddle; | ||
| 3408 | mword >>= offset; | ||
| 3409 | |||
| 3410 | /* Do not count the pad bits. */ | ||
| 3411 | mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset); | ||
| 3412 | |||
| 3413 | count = count_trailing_zero_bits (mword); | ||
| 3414 | pos++; | ||
| 3415 | if (count + offset < BITS_PER_BITS_WORD) | ||
| 3416 | return make_number (count); | ||
| 3417 | } | ||
| 3418 | |||
| 3419 | /* Scan whole words until we either reach the end of the vector or | ||
| 3420 | find an mword that doesn't completely match. twiddle is | ||
| 3421 | endian-independent. */ | ||
| 3422 | pos0 = pos; | ||
| 3423 | while (pos < nr_words && adata[pos] == twiddle) | ||
| 3424 | pos++; | ||
| 3425 | count += (pos - pos0) * BITS_PER_BITS_WORD; | ||
| 3426 | |||
| 3427 | if (pos < nr_words) | ||
| 3428 | { | ||
| 3429 | /* If we stopped because of a mismatch, see how many bits match | ||
| 3430 | in the current mword. */ | ||
| 3431 | mword = bits_word_to_host_endian (adata[pos]); | ||
| 3432 | mword ^= twiddle; | ||
| 3433 | count += count_trailing_zero_bits (mword); | ||
| 3434 | } | ||
| 3435 | else if (nr_bits % BITS_PER_BITS_WORD != 0) | ||
| 3436 | { | ||
| 3437 | /* If we hit the end, we might have overshot our count. Reduce | ||
| 3438 | the total by the number of spare bits at the end of the | ||
| 3439 | vector. */ | ||
| 3440 | count -= BITS_PER_BITS_WORD - nr_bits % BITS_PER_BITS_WORD; | ||
| 3441 | } | ||
| 3442 | |||
| 3443 | return make_number (count); | ||
| 3444 | } | ||
| 2978 | 3445 | ||
| 2979 | 3446 | ||
| 2980 | void | 3447 | void |
| @@ -2992,6 +3459,7 @@ syms_of_data (void) | |||
| 2992 | DEFSYM (Qerror, "error"); | 3459 | DEFSYM (Qerror, "error"); |
| 2993 | DEFSYM (Quser_error, "user-error"); | 3460 | DEFSYM (Quser_error, "user-error"); |
| 2994 | DEFSYM (Qquit, "quit"); | 3461 | DEFSYM (Qquit, "quit"); |
| 3462 | DEFSYM (Qwrong_length_argument, "wrong-length-argument"); | ||
| 2995 | DEFSYM (Qwrong_type_argument, "wrong-type-argument"); | 3463 | DEFSYM (Qwrong_type_argument, "wrong-type-argument"); |
| 2996 | DEFSYM (Qargs_out_of_range, "args-out-of-range"); | 3464 | DEFSYM (Qargs_out_of_range, "args-out-of-range"); |
| 2997 | DEFSYM (Qvoid_function, "void-function"); | 3465 | DEFSYM (Qvoid_function, "void-function"); |
| @@ -3015,7 +3483,6 @@ syms_of_data (void) | |||
| 3015 | DEFSYM (Qlistp, "listp"); | 3483 | DEFSYM (Qlistp, "listp"); |
| 3016 | DEFSYM (Qconsp, "consp"); | 3484 | DEFSYM (Qconsp, "consp"); |
| 3017 | DEFSYM (Qsymbolp, "symbolp"); | 3485 | DEFSYM (Qsymbolp, "symbolp"); |
| 3018 | DEFSYM (Qkeywordp, "keywordp"); | ||
| 3019 | DEFSYM (Qintegerp, "integerp"); | 3486 | DEFSYM (Qintegerp, "integerp"); |
| 3020 | DEFSYM (Qnatnump, "natnump"); | 3487 | DEFSYM (Qnatnump, "natnump"); |
| 3021 | DEFSYM (Qwholenump, "wholenump"); | 3488 | DEFSYM (Qwholenump, "wholenump"); |
| @@ -3024,11 +3491,11 @@ syms_of_data (void) | |||
| 3024 | DEFSYM (Qsequencep, "sequencep"); | 3491 | DEFSYM (Qsequencep, "sequencep"); |
| 3025 | DEFSYM (Qbufferp, "bufferp"); | 3492 | DEFSYM (Qbufferp, "bufferp"); |
| 3026 | DEFSYM (Qvectorp, "vectorp"); | 3493 | DEFSYM (Qvectorp, "vectorp"); |
| 3494 | DEFSYM (Qbool_vector_p, "bool-vector-p"); | ||
| 3027 | DEFSYM (Qchar_or_string_p, "char-or-string-p"); | 3495 | DEFSYM (Qchar_or_string_p, "char-or-string-p"); |
| 3028 | DEFSYM (Qmarkerp, "markerp"); | 3496 | DEFSYM (Qmarkerp, "markerp"); |
| 3029 | DEFSYM (Qbuffer_or_string_p, "buffer-or-string-p"); | 3497 | DEFSYM (Qbuffer_or_string_p, "buffer-or-string-p"); |
| 3030 | DEFSYM (Qinteger_or_marker_p, "integer-or-marker-p"); | 3498 | DEFSYM (Qinteger_or_marker_p, "integer-or-marker-p"); |
| 3031 | DEFSYM (Qboundp, "boundp"); | ||
| 3032 | DEFSYM (Qfboundp, "fboundp"); | 3499 | DEFSYM (Qfboundp, "fboundp"); |
| 3033 | 3500 | ||
| 3034 | DEFSYM (Qfloatp, "floatp"); | 3501 | DEFSYM (Qfloatp, "floatp"); |
| @@ -3044,10 +3511,6 @@ syms_of_data (void) | |||
| 3044 | 3511 | ||
| 3045 | DEFSYM (Qcdr, "cdr"); | 3512 | DEFSYM (Qcdr, "cdr"); |
| 3046 | 3513 | ||
| 3047 | /* Handle automatic advice activation. */ | ||
| 3048 | DEFSYM (Qad_advice_info, "ad-advice-info"); | ||
| 3049 | DEFSYM (Qad_activate_internal, "ad-activate-internal"); | ||
| 3050 | |||
| 3051 | error_tail = pure_cons (Qerror, Qnil); | 3514 | error_tail = pure_cons (Qerror, Qnil); |
| 3052 | 3515 | ||
| 3053 | /* ERROR is used as a signaler for random errors for which nothing else is | 3516 | /* ERROR is used as a signaler for random errors for which nothing else is |
| @@ -3065,6 +3528,7 @@ syms_of_data (void) | |||
| 3065 | PUT_ERROR (Qquit, Qnil, "Quit"); | 3528 | PUT_ERROR (Qquit, Qnil, "Quit"); |
| 3066 | 3529 | ||
| 3067 | PUT_ERROR (Quser_error, error_tail, ""); | 3530 | PUT_ERROR (Quser_error, error_tail, ""); |
| 3531 | PUT_ERROR (Qwrong_length_argument, error_tail, "Wrong length argument"); | ||
| 3068 | PUT_ERROR (Qwrong_type_argument, error_tail, "Wrong type argument"); | 3532 | PUT_ERROR (Qwrong_type_argument, error_tail, "Wrong type argument"); |
| 3069 | PUT_ERROR (Qargs_out_of_range, error_tail, "Args out of range"); | 3533 | PUT_ERROR (Qargs_out_of_range, error_tail, "Args out of range"); |
| 3070 | PUT_ERROR (Qvoid_function, error_tail, | 3534 | PUT_ERROR (Qvoid_function, error_tail, |
| @@ -3113,10 +3577,6 @@ syms_of_data (void) | |||
| 3113 | PUT_ERROR (Qunderflow_error, Fcons (Qdomain_error, arith_tail), | 3577 | PUT_ERROR (Qunderflow_error, Fcons (Qdomain_error, arith_tail), |
| 3114 | "Arithmetic underflow error"); | 3578 | "Arithmetic underflow error"); |
| 3115 | 3579 | ||
| 3116 | staticpro (&Qnil); | ||
| 3117 | staticpro (&Qt); | ||
| 3118 | staticpro (&Qunbound); | ||
| 3119 | |||
| 3120 | /* Types that type-of returns. */ | 3580 | /* Types that type-of returns. */ |
| 3121 | DEFSYM (Qinteger, "integer"); | 3581 | DEFSYM (Qinteger, "integer"); |
| 3122 | DEFSYM (Qsymbol, "symbol"); | 3582 | DEFSYM (Qsymbol, "symbol"); |
| @@ -3124,6 +3584,7 @@ syms_of_data (void) | |||
| 3124 | DEFSYM (Qcons, "cons"); | 3584 | DEFSYM (Qcons, "cons"); |
| 3125 | DEFSYM (Qmarker, "marker"); | 3585 | DEFSYM (Qmarker, "marker"); |
| 3126 | DEFSYM (Qoverlay, "overlay"); | 3586 | DEFSYM (Qoverlay, "overlay"); |
| 3587 | DEFSYM (Qfinalizer, "finalizer"); | ||
| 3127 | DEFSYM (Qfloat, "float"); | 3588 | DEFSYM (Qfloat, "float"); |
| 3128 | DEFSYM (Qwindow_configuration, "window-configuration"); | 3589 | DEFSYM (Qwindow_configuration, "window-configuration"); |
| 3129 | DEFSYM (Qprocess, "process"); | 3590 | DEFSYM (Qprocess, "process"); |
| @@ -3138,7 +3599,6 @@ syms_of_data (void) | |||
| 3138 | DEFSYM (Qthread, "thread"); | 3599 | DEFSYM (Qthread, "thread"); |
| 3139 | DEFSYM (Qmutex, "mutex"); | 3600 | DEFSYM (Qmutex, "mutex"); |
| 3140 | DEFSYM (Qcondition_variable, "condition-variable"); | 3601 | DEFSYM (Qcondition_variable, "condition-variable"); |
| 3141 | DEFSYM (Qmisc, "misc"); | ||
| 3142 | 3602 | ||
| 3143 | DEFSYM (Qdefun, "defun"); | 3603 | DEFSYM (Qdefun, "defun"); |
| 3144 | 3604 | ||
| @@ -3226,7 +3686,6 @@ syms_of_data (void) | |||
| 3226 | defsubr (&Sleq); | 3686 | defsubr (&Sleq); |
| 3227 | defsubr (&Sgeq); | 3687 | defsubr (&Sgeq); |
| 3228 | defsubr (&Sneq); | 3688 | defsubr (&Sneq); |
| 3229 | defsubr (&Szerop); | ||
| 3230 | defsubr (&Splus); | 3689 | defsubr (&Splus); |
| 3231 | defsubr (&Sminus); | 3690 | defsubr (&Sminus); |
| 3232 | defsubr (&Stimes); | 3691 | defsubr (&Stimes); |
| @@ -3247,6 +3706,15 @@ syms_of_data (void) | |||
| 3247 | defsubr (&Ssubr_arity); | 3706 | defsubr (&Ssubr_arity); |
| 3248 | defsubr (&Ssubr_name); | 3707 | defsubr (&Ssubr_name); |
| 3249 | 3708 | ||
| 3709 | defsubr (&Sbool_vector_exclusive_or); | ||
| 3710 | defsubr (&Sbool_vector_union); | ||
| 3711 | defsubr (&Sbool_vector_intersection); | ||
| 3712 | defsubr (&Sbool_vector_set_difference); | ||
| 3713 | defsubr (&Sbool_vector_not); | ||
| 3714 | defsubr (&Sbool_vector_subsetp); | ||
| 3715 | defsubr (&Sbool_vector_count_consecutive); | ||
| 3716 | defsubr (&Sbool_vector_count_population); | ||
| 3717 | |||
| 3250 | set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->function); | 3718 | set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->function); |
| 3251 | 3719 | ||
| 3252 | DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum, | 3720 | DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum, |