diff options
| author | Joakim Verona | 2012-09-03 17:30:17 +0200 |
|---|---|---|
| committer | Joakim Verona | 2012-09-03 17:30:17 +0200 |
| commit | 4a37733c693d59a9b83a3fb2d0c7f9461d149f60 (patch) | |
| tree | a33402e09342f748baebf0e4f5a1e40538e620f4 /src/fns.c | |
| parent | 5436d1df5e2ba0b4d4f72b03a1cd09b20403654b (diff) | |
| parent | dcde497f27945c3ca4ce8c21f655ef6f627acdd2 (diff) | |
| download | emacs-4a37733c693d59a9b83a3fb2d0c7f9461d149f60.tar.gz emacs-4a37733c693d59a9b83a3fb2d0c7f9461d149f60.zip | |
upstream
Diffstat (limited to 'src/fns.c')
| -rw-r--r-- | src/fns.c | 118 |
1 files changed, 46 insertions, 72 deletions
| @@ -52,10 +52,6 @@ static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper; | |||
| 52 | static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512; | 52 | static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512; |
| 53 | 53 | ||
| 54 | static int internal_equal (Lisp_Object , Lisp_Object, int, int); | 54 | static int internal_equal (Lisp_Object , Lisp_Object, int, int); |
| 55 | |||
| 56 | #ifndef HAVE_UNISTD_H | ||
| 57 | extern long time (); | ||
| 58 | #endif | ||
| 59 | 55 | ||
| 60 | DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, | 56 | DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, |
| 61 | doc: /* Return the argument unchanged. */) | 57 | doc: /* Return the argument unchanged. */) |
| @@ -74,32 +70,16 @@ Other values of LIMIT are ignored. */) | |||
| 74 | (Lisp_Object limit) | 70 | (Lisp_Object limit) |
| 75 | { | 71 | { |
| 76 | EMACS_INT val; | 72 | EMACS_INT val; |
| 77 | Lisp_Object lispy_val; | ||
| 78 | 73 | ||
| 79 | if (EQ (limit, Qt)) | 74 | if (EQ (limit, Qt)) |
| 80 | { | 75 | init_random (); |
| 81 | EMACS_TIME t = current_emacs_time (); | 76 | else if (STRINGP (limit)) |
| 82 | seed_random (getpid () ^ EMACS_SECS (t) ^ EMACS_NSECS (t)); | 77 | seed_random (SSDATA (limit), SBYTES (limit)); |
| 83 | } | ||
| 84 | 78 | ||
| 79 | val = get_random (); | ||
| 85 | if (NATNUMP (limit) && XFASTINT (limit) != 0) | 80 | if (NATNUMP (limit) && XFASTINT (limit) != 0) |
| 86 | { | 81 | val %= XFASTINT (limit); |
| 87 | /* Try to take our random number from the higher bits of VAL, | 82 | return make_number (val); |
| 88 | not the lower, since (says Gentzel) the low bits of `random' | ||
| 89 | are less random than the higher ones. We do this by using the | ||
| 90 | quotient rather than the remainder. At the high end of the RNG | ||
| 91 | it's possible to get a quotient larger than n; discarding | ||
| 92 | these values eliminates the bias that would otherwise appear | ||
| 93 | when using a large n. */ | ||
| 94 | EMACS_INT denominator = (INTMASK + 1) / XFASTINT (limit); | ||
| 95 | do | ||
| 96 | val = get_random () / denominator; | ||
| 97 | while (val >= XFASTINT (limit)); | ||
| 98 | } | ||
| 99 | else | ||
| 100 | val = get_random (); | ||
| 101 | XSETINT (lispy_val, val); | ||
| 102 | return lispy_val; | ||
| 103 | } | 83 | } |
| 104 | 84 | ||
| 105 | /* Heuristic on how many iterations of a tight loop can be safely done | 85 | /* Heuristic on how many iterations of a tight loop can be safely done |
| @@ -1100,7 +1080,7 @@ an error is signaled. */) | |||
| 1100 | { | 1080 | { |
| 1101 | ptrdiff_t chars = SCHARS (string); | 1081 | ptrdiff_t chars = SCHARS (string); |
| 1102 | unsigned char *str = xmalloc (chars); | 1082 | unsigned char *str = xmalloc (chars); |
| 1103 | ptrdiff_t converted = str_to_unibyte (SDATA (string), str, chars, 0); | 1083 | ptrdiff_t converted = str_to_unibyte (SDATA (string), str, chars); |
| 1104 | 1084 | ||
| 1105 | if (converted < chars) | 1085 | if (converted < chars) |
| 1106 | error ("Can't convert the %"pD"dth character to unibyte", converted); | 1086 | error ("Can't convert the %"pD"dth character to unibyte", converted); |
| @@ -2139,12 +2119,8 @@ ARRAY is a vector, string, char-table, or bool-vector. */) | |||
| 2139 | register ptrdiff_t size, idx; | 2119 | register ptrdiff_t size, idx; |
| 2140 | 2120 | ||
| 2141 | if (VECTORP (array)) | 2121 | if (VECTORP (array)) |
| 2142 | { | 2122 | for (idx = 0, size = ASIZE (array); idx < size; idx++) |
| 2143 | register Lisp_Object *p = XVECTOR (array)->contents; | 2123 | ASET (array, idx, item); |
| 2144 | size = ASIZE (array); | ||
| 2145 | for (idx = 0; idx < size; idx++) | ||
| 2146 | p[idx] = item; | ||
| 2147 | } | ||
| 2148 | else if (CHAR_TABLE_P (array)) | 2124 | else if (CHAR_TABLE_P (array)) |
| 2149 | { | 2125 | { |
| 2150 | int i; | 2126 | int i; |
| @@ -3663,7 +3639,7 @@ make_hash_table (Lisp_Object test, Lisp_Object size, Lisp_Object rehash_size, | |||
| 3663 | 3639 | ||
| 3664 | /* Set up the free list. */ | 3640 | /* Set up the free list. */ |
| 3665 | for (i = 0; i < sz - 1; ++i) | 3641 | for (i = 0; i < sz - 1; ++i) |
| 3666 | set_hash_next (h, i, make_number (i + 1)); | 3642 | set_hash_next_slot (h, i, make_number (i + 1)); |
| 3667 | h->next_free = make_number (0); | 3643 | h->next_free = make_number (0); |
| 3668 | 3644 | ||
| 3669 | XSET_HASH_TABLE (table, h); | 3645 | XSET_HASH_TABLE (table, h); |
| @@ -3760,17 +3736,17 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h) | |||
| 3760 | } | 3736 | } |
| 3761 | #endif | 3737 | #endif |
| 3762 | 3738 | ||
| 3763 | h->key_and_value = larger_vector (h->key_and_value, | 3739 | set_hash_key_and_value (h, larger_vector (h->key_and_value, |
| 3764 | 2 * (new_size - old_size), -1); | 3740 | 2 * (new_size - old_size), -1)); |
| 3765 | h->next = larger_vector (h->next, new_size - old_size, -1); | 3741 | set_hash_next (h, larger_vector (h->next, new_size - old_size, -1)); |
| 3766 | h->hash = larger_vector (h->hash, new_size - old_size, -1); | 3742 | set_hash_hash (h, larger_vector (h->hash, new_size - old_size, -1)); |
| 3767 | h->index = Fmake_vector (make_number (index_size), Qnil); | 3743 | set_hash_index (h, Fmake_vector (make_number (index_size), Qnil)); |
| 3768 | 3744 | ||
| 3769 | /* Update the free list. Do it so that new entries are added at | 3745 | /* Update the free list. Do it so that new entries are added at |
| 3770 | the end of the free list. This makes some operations like | 3746 | the end of the free list. This makes some operations like |
| 3771 | maphash faster. */ | 3747 | maphash faster. */ |
| 3772 | for (i = old_size; i < new_size - 1; ++i) | 3748 | for (i = old_size; i < new_size - 1; ++i) |
| 3773 | set_hash_next (h, i, make_number (i + 1)); | 3749 | set_hash_next_slot (h, i, make_number (i + 1)); |
| 3774 | 3750 | ||
| 3775 | if (!NILP (h->next_free)) | 3751 | if (!NILP (h->next_free)) |
| 3776 | { | 3752 | { |
| @@ -3781,7 +3757,7 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h) | |||
| 3781 | !NILP (next)) | 3757 | !NILP (next)) |
| 3782 | last = next; | 3758 | last = next; |
| 3783 | 3759 | ||
| 3784 | set_hash_next (h, XFASTINT (last), make_number (old_size)); | 3760 | set_hash_next_slot (h, XFASTINT (last), make_number (old_size)); |
| 3785 | } | 3761 | } |
| 3786 | else | 3762 | else |
| 3787 | XSETFASTINT (h->next_free, old_size); | 3763 | XSETFASTINT (h->next_free, old_size); |
| @@ -3792,8 +3768,8 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h) | |||
| 3792 | { | 3768 | { |
| 3793 | EMACS_UINT hash_code = XUINT (HASH_HASH (h, i)); | 3769 | EMACS_UINT hash_code = XUINT (HASH_HASH (h, i)); |
| 3794 | ptrdiff_t start_of_bucket = hash_code % ASIZE (h->index); | 3770 | ptrdiff_t start_of_bucket = hash_code % ASIZE (h->index); |
| 3795 | set_hash_next (h, i, HASH_INDEX (h, start_of_bucket)); | 3771 | set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket)); |
| 3796 | set_hash_index (h, start_of_bucket, make_number (i)); | 3772 | set_hash_index_slot (h, start_of_bucket, make_number (i)); |
| 3797 | } | 3773 | } |
| 3798 | } | 3774 | } |
| 3799 | } | 3775 | } |
| @@ -3852,16 +3828,16 @@ hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value, | |||
| 3852 | /* Store key/value in the key_and_value vector. */ | 3828 | /* Store key/value in the key_and_value vector. */ |
| 3853 | i = XFASTINT (h->next_free); | 3829 | i = XFASTINT (h->next_free); |
| 3854 | h->next_free = HASH_NEXT (h, i); | 3830 | h->next_free = HASH_NEXT (h, i); |
| 3855 | set_hash_key (h, i, key); | 3831 | set_hash_key_slot (h, i, key); |
| 3856 | set_hash_value (h, i, value); | 3832 | set_hash_value_slot (h, i, value); |
| 3857 | 3833 | ||
| 3858 | /* Remember its hash code. */ | 3834 | /* Remember its hash code. */ |
| 3859 | set_hash_hash (h, i, make_number (hash)); | 3835 | set_hash_hash_slot (h, i, make_number (hash)); |
| 3860 | 3836 | ||
| 3861 | /* Add new entry to its collision chain. */ | 3837 | /* Add new entry to its collision chain. */ |
| 3862 | start_of_bucket = hash % ASIZE (h->index); | 3838 | start_of_bucket = hash % ASIZE (h->index); |
| 3863 | set_hash_next (h, i, HASH_INDEX (h, start_of_bucket)); | 3839 | set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket)); |
| 3864 | set_hash_index (h, start_of_bucket, make_number (i)); | 3840 | set_hash_index_slot (h, start_of_bucket, make_number (i)); |
| 3865 | return i; | 3841 | return i; |
| 3866 | } | 3842 | } |
| 3867 | 3843 | ||
| @@ -3892,16 +3868,16 @@ hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key) | |||
| 3892 | { | 3868 | { |
| 3893 | /* Take entry out of collision chain. */ | 3869 | /* Take entry out of collision chain. */ |
| 3894 | if (NILP (prev)) | 3870 | if (NILP (prev)) |
| 3895 | set_hash_index (h, start_of_bucket, HASH_NEXT (h, i)); | 3871 | set_hash_index_slot (h, start_of_bucket, HASH_NEXT (h, i)); |
| 3896 | else | 3872 | else |
| 3897 | set_hash_next (h, XFASTINT (prev), HASH_NEXT (h, i)); | 3873 | set_hash_next_slot (h, XFASTINT (prev), HASH_NEXT (h, i)); |
| 3898 | 3874 | ||
| 3899 | /* Clear slots in key_and_value and add the slots to | 3875 | /* Clear slots in key_and_value and add the slots to |
| 3900 | the free list. */ | 3876 | the free list. */ |
| 3901 | set_hash_key (h, i, Qnil); | 3877 | set_hash_key_slot (h, i, Qnil); |
| 3902 | set_hash_value (h, i, Qnil); | 3878 | set_hash_value_slot (h, i, Qnil); |
| 3903 | set_hash_hash (h, i, Qnil); | 3879 | set_hash_hash_slot (h, i, Qnil); |
| 3904 | set_hash_next (h, i, h->next_free); | 3880 | set_hash_next_slot (h, i, h->next_free); |
| 3905 | h->next_free = make_number (i); | 3881 | h->next_free = make_number (i); |
| 3906 | h->count--; | 3882 | h->count--; |
| 3907 | eassert (h->count >= 0); | 3883 | eassert (h->count >= 0); |
| @@ -3927,10 +3903,10 @@ hash_clear (struct Lisp_Hash_Table *h) | |||
| 3927 | 3903 | ||
| 3928 | for (i = 0; i < size; ++i) | 3904 | for (i = 0; i < size; ++i) |
| 3929 | { | 3905 | { |
| 3930 | set_hash_next (h, i, i < size - 1 ? make_number (i + 1) : Qnil); | 3906 | set_hash_next_slot (h, i, i < size - 1 ? make_number (i + 1) : Qnil); |
| 3931 | set_hash_key (h, i, Qnil); | 3907 | set_hash_key_slot (h, i, Qnil); |
| 3932 | set_hash_value (h, i, Qnil); | 3908 | set_hash_value_slot (h, i, Qnil); |
| 3933 | set_hash_hash (h, i, Qnil); | 3909 | set_hash_hash_slot (h, i, Qnil); |
| 3934 | } | 3910 | } |
| 3935 | 3911 | ||
| 3936 | for (i = 0; i < ASIZE (h->index); ++i) | 3912 | for (i = 0; i < ASIZE (h->index); ++i) |
| @@ -3971,8 +3947,8 @@ sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p) | |||
| 3971 | for (idx = HASH_INDEX (h, bucket); !NILP (idx); idx = next) | 3947 | for (idx = HASH_INDEX (h, bucket); !NILP (idx); idx = next) |
| 3972 | { | 3948 | { |
| 3973 | ptrdiff_t i = XFASTINT (idx); | 3949 | ptrdiff_t i = XFASTINT (idx); |
| 3974 | int key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i)); | 3950 | bool key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i)); |
| 3975 | int value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i)); | 3951 | bool value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i)); |
| 3976 | int remove_p; | 3952 | int remove_p; |
| 3977 | 3953 | ||
| 3978 | if (EQ (h->weak, Qkey)) | 3954 | if (EQ (h->weak, Qkey)) |
| @@ -3994,18 +3970,18 @@ sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p) | |||
| 3994 | { | 3970 | { |
| 3995 | /* Take out of collision chain. */ | 3971 | /* Take out of collision chain. */ |
| 3996 | if (NILP (prev)) | 3972 | if (NILP (prev)) |
| 3997 | set_hash_index (h, bucket, next); | 3973 | set_hash_index_slot (h, bucket, next); |
| 3998 | else | 3974 | else |
| 3999 | set_hash_next (h, XFASTINT (prev), next); | 3975 | set_hash_next_slot (h, XFASTINT (prev), next); |
| 4000 | 3976 | ||
| 4001 | /* Add to free list. */ | 3977 | /* Add to free list. */ |
| 4002 | set_hash_next (h, i, h->next_free); | 3978 | set_hash_next_slot (h, i, h->next_free); |
| 4003 | h->next_free = idx; | 3979 | h->next_free = idx; |
| 4004 | 3980 | ||
| 4005 | /* Clear key, value, and hash. */ | 3981 | /* Clear key, value, and hash. */ |
| 4006 | set_hash_key (h, i, Qnil); | 3982 | set_hash_key_slot (h, i, Qnil); |
| 4007 | set_hash_value (h, i, Qnil); | 3983 | set_hash_value_slot (h, i, Qnil); |
| 4008 | set_hash_hash (h, i, Qnil); | 3984 | set_hash_hash_slot (h, i, Qnil); |
| 4009 | 3985 | ||
| 4010 | h->count--; | 3986 | h->count--; |
| 4011 | } | 3987 | } |
| @@ -4512,7 +4488,7 @@ VALUE. In any case, return VALUE. */) | |||
| 4512 | 4488 | ||
| 4513 | i = hash_lookup (h, key, &hash); | 4489 | i = hash_lookup (h, key, &hash); |
| 4514 | if (i >= 0) | 4490 | if (i >= 0) |
| 4515 | set_hash_value (h, i, value); | 4491 | set_hash_value_slot (h, i, value); |
| 4516 | else | 4492 | else |
| 4517 | hash_put (h, key, value, hash); | 4493 | hash_put (h, key, value, hash); |
| 4518 | 4494 | ||
| @@ -4660,13 +4636,12 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_ | |||
| 4660 | { | 4636 | { |
| 4661 | struct buffer *prev = current_buffer; | 4637 | struct buffer *prev = current_buffer; |
| 4662 | 4638 | ||
| 4663 | record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); | 4639 | record_unwind_current_buffer (); |
| 4664 | 4640 | ||
| 4665 | CHECK_BUFFER (object); | 4641 | CHECK_BUFFER (object); |
| 4666 | 4642 | ||
| 4667 | bp = XBUFFER (object); | 4643 | bp = XBUFFER (object); |
| 4668 | if (bp != current_buffer) | 4644 | set_buffer_internal (bp); |
| 4669 | set_buffer_internal (bp); | ||
| 4670 | 4645 | ||
| 4671 | if (NILP (start)) | 4646 | if (NILP (start)) |
| 4672 | b = BEGV; | 4647 | b = BEGV; |
| @@ -4753,8 +4728,7 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_ | |||
| 4753 | } | 4728 | } |
| 4754 | 4729 | ||
| 4755 | object = make_buffer_string (b, e, 0); | 4730 | object = make_buffer_string (b, e, 0); |
| 4756 | if (prev != current_buffer) | 4731 | set_buffer_internal (prev); |
| 4757 | set_buffer_internal (prev); | ||
| 4758 | /* Discard the unwind protect for recovering the current | 4732 | /* Discard the unwind protect for recovering the current |
| 4759 | buffer. */ | 4733 | buffer. */ |
| 4760 | specpdl_ptr--; | 4734 | specpdl_ptr--; |