X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/e1528d010f497f97d660902b8a8727fc1b77f53b..d311d28c3f8a3c43e6ef33d68b852c5ea7f13239:/src/fns.c diff --git a/src/fns.c b/src/fns.c index 6c9e05655f..5d75c42aea 100644 --- a/src/fns.c +++ b/src/fns.c @@ -53,6 +53,8 @@ Lisp_Object Qcursor_in_echo_area; static Lisp_Object Qwidget_type; static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper; +static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512; + static int internal_equal (Lisp_Object , Lisp_Object, int, int); #ifndef HAVE_UNISTD_H @@ -77,10 +79,14 @@ Other values of LIMIT are ignored. */) { EMACS_INT val; Lisp_Object lispy_val; - EMACS_UINT denominator; if (EQ (limit, Qt)) - seed_random (getpid () + time (NULL)); + { + EMACS_TIME t; + EMACS_GET_TIME (t); + seed_random (getpid () ^ EMACS_SECS (t) ^ EMACS_USECS (t)); + } + if (NATNUMP (limit) && XFASTINT (limit) != 0) { /* Try to take our random number from the higher bits of VAL, @@ -90,7 +96,7 @@ Other values of LIMIT are ignored. */) it's possible to get a quotient larger than n; discarding these values eliminates the bias that would otherwise appear when using a large n. */ - denominator = ((EMACS_UINT) 1 << VALBITS) / XFASTINT (limit); + EMACS_INT denominator = (INTMASK + 1) / XFASTINT (limit); do val = get_random () / denominator; while (val >= XFASTINT (limit)); @@ -170,7 +176,7 @@ which is at least the number of distinct elements. */) uintmax_t lolen = 1; if (! CONSP (list)) - return 0; + return make_number (0); /* halftail is used to detect circular lists. */ for (tail = halftail = list; ; ) @@ -244,8 +250,8 @@ If string STR1 is greater, the value is a positive number N; N - 1 is the number of characters that match at the beginning. */) (Lisp_Object str1, Lisp_Object start1, Lisp_Object end1, Lisp_Object str2, Lisp_Object start2, Lisp_Object end2, Lisp_Object ignore_case) { - register EMACS_INT end1_char, end2_char; - register EMACS_INT i1, i1_byte, i2, i2_byte; + register ptrdiff_t end1_char, end2_char; + register ptrdiff_t i1, i1_byte, i2, i2_byte; CHECK_STRING (str1); CHECK_STRING (str2); @@ -260,19 +266,23 @@ If string STR1 is greater, the value is a positive number N; if (! NILP (end2)) CHECK_NATNUM (end2); - i1 = XINT (start1); - i2 = XINT (start2); - - i1_byte = string_char_to_byte (str1, i1); - i2_byte = string_char_to_byte (str2, i2); - end1_char = SCHARS (str1); if (! NILP (end1) && end1_char > XINT (end1)) end1_char = XINT (end1); + if (end1_char < XINT (start1)) + args_out_of_range (str1, start1); end2_char = SCHARS (str2); if (! NILP (end2) && end2_char > XINT (end2)) end2_char = XINT (end2); + if (end2_char < XINT (start2)) + args_out_of_range (str2, start2); + + i1 = XINT (start1); + i2 = XINT (start2); + + i1_byte = string_char_to_byte (str1, i1); + i2_byte = string_char_to_byte (str2, i2); while (i1 < end1_char && i2 < end2_char) { @@ -335,8 +345,8 @@ Case is significant. Symbols are also allowed; their print names are used instead. */) (register Lisp_Object s1, Lisp_Object s2) { - register EMACS_INT end; - register EMACS_INT i1, i1_byte, i2, i2_byte; + register ptrdiff_t end; + register ptrdiff_t i1, i1_byte, i2, i2_byte; if (SYMBOLP (s1)) s1 = SYMBOL_NAME (s1); @@ -459,8 +469,8 @@ with the original. */) struct textprop_rec { ptrdiff_t argnum; /* refer to ARGS (arguments of `concat') */ - EMACS_INT from; /* refer to ARGS[argnum] (argument string) */ - EMACS_INT to; /* refer to VAL (the target string) */ + ptrdiff_t from; /* refer to ARGS[argnum] (argument string) */ + ptrdiff_t to; /* refer to VAL (the target string) */ }; static Lisp_Object @@ -470,8 +480,8 @@ concat (ptrdiff_t nargs, Lisp_Object *args, Lisp_Object val; register Lisp_Object tail; register Lisp_Object this; - EMACS_INT toindex; - EMACS_INT toindex_byte = 0; + ptrdiff_t toindex; + ptrdiff_t toindex_byte = 0; register EMACS_INT result_len; register EMACS_INT result_len_byte; ptrdiff_t argnum; @@ -524,10 +534,10 @@ concat (ptrdiff_t nargs, Lisp_Object *args, { /* We must count the number of bytes needed in the string as well as the number of characters. */ - EMACS_INT i; + ptrdiff_t i; Lisp_Object ch; int c; - EMACS_INT this_len_byte; + ptrdiff_t this_len_byte; if (VECTORP (this) || COMPILEDP (this)) for (i = 0; i < len; i++) @@ -536,6 +546,8 @@ concat (ptrdiff_t nargs, Lisp_Object *args, CHECK_CHARACTER (ch); c = XFASTINT (ch); this_len_byte = CHAR_BYTES (c); + if (STRING_BYTES_BOUND - result_len_byte < this_len_byte) + string_overflow (); result_len_byte += this_len_byte; if (! ASCII_CHAR_P (c) && ! CHAR_BYTE8_P (c)) some_multibyte = 1; @@ -549,6 +561,8 @@ concat (ptrdiff_t nargs, Lisp_Object *args, CHECK_CHARACTER (ch); c = XFASTINT (ch); this_len_byte = CHAR_BYTES (c); + if (STRING_BYTES_BOUND - result_len_byte < this_len_byte) + string_overflow (); result_len_byte += this_len_byte; if (! ASCII_CHAR_P (c) && ! CHAR_BYTE8_P (c)) some_multibyte = 1; @@ -558,17 +572,20 @@ concat (ptrdiff_t nargs, Lisp_Object *args, if (STRING_MULTIBYTE (this)) { some_multibyte = 1; - result_len_byte += SBYTES (this); + this_len_byte = SBYTES (this); } else - result_len_byte += count_size_as_multibyte (SDATA (this), - SCHARS (this)); + this_len_byte = count_size_as_multibyte (SDATA (this), + SCHARS (this)); + if (STRING_BYTES_BOUND - result_len_byte < this_len_byte) + string_overflow (); + result_len_byte += this_len_byte; } } result_len += len; - if (STRING_BYTES_BOUND < result_len) - string_overflow (); + if (MOST_POSITIVE_FIXNUM < result_len) + memory_full (SIZE_MAX); } if (! some_multibyte) @@ -596,14 +613,14 @@ concat (ptrdiff_t nargs, Lisp_Object *args, prev = Qnil; if (STRINGP (val)) - SAFE_ALLOCA (textprops, struct textprop_rec *, sizeof (struct textprop_rec) * nargs); + SAFE_NALLOCA (textprops, 1, nargs); for (argnum = 0; argnum < nargs; argnum++) { Lisp_Object thislen; - EMACS_INT thisleni = 0; - register EMACS_INT thisindex = 0; - register EMACS_INT thisindex_byte = 0; + ptrdiff_t thisleni = 0; + register ptrdiff_t thisindex = 0; + register ptrdiff_t thisindex_byte = 0; this = args[argnum]; if (!CONSP (this)) @@ -613,7 +630,7 @@ concat (ptrdiff_t nargs, Lisp_Object *args, if (STRINGP (this) && STRINGP (val) && STRING_MULTIBYTE (this) == some_multibyte) { - EMACS_INT thislen_byte = SBYTES (this); + ptrdiff_t thislen_byte = SBYTES (this); memcpy (SDATA (val) + toindex_byte, SDATA (this), SBYTES (this)); if (! NULL_INTERVAL_P (STRING_INTERVALS (this))) @@ -714,7 +731,7 @@ concat (ptrdiff_t nargs, Lisp_Object *args, if (num_textprops > 0) { Lisp_Object props; - EMACS_INT last_to_end = -1; + ptrdiff_t last_to_end = -1; for (argnum = 0; argnum < num_textprops; argnum++) { @@ -738,8 +755,8 @@ concat (ptrdiff_t nargs, Lisp_Object *args, } static Lisp_Object string_char_byte_cache_string; -static EMACS_INT string_char_byte_cache_charpos; -static EMACS_INT string_char_byte_cache_bytepos; +static ptrdiff_t string_char_byte_cache_charpos; +static ptrdiff_t string_char_byte_cache_bytepos; void clear_string_char_byte_cache (void) @@ -749,12 +766,12 @@ clear_string_char_byte_cache (void) /* Return the byte index corresponding to CHAR_INDEX in STRING. */ -EMACS_INT -string_char_to_byte (Lisp_Object string, EMACS_INT char_index) +ptrdiff_t +string_char_to_byte (Lisp_Object string, ptrdiff_t char_index) { - EMACS_INT i_byte; - EMACS_INT best_below, best_below_byte; - EMACS_INT best_above, best_above_byte; + ptrdiff_t i_byte; + ptrdiff_t best_below, best_below_byte; + ptrdiff_t best_above, best_above_byte; best_below = best_below_byte = 0; best_above = SCHARS (string); @@ -809,12 +826,12 @@ string_char_to_byte (Lisp_Object string, EMACS_INT char_index) /* Return the character index corresponding to BYTE_INDEX in STRING. */ -EMACS_INT -string_byte_to_char (Lisp_Object string, EMACS_INT byte_index) +ptrdiff_t +string_byte_to_char (Lisp_Object string, ptrdiff_t byte_index) { - EMACS_INT i, i_byte; - EMACS_INT best_below, best_below_byte; - EMACS_INT best_above, best_above_byte; + ptrdiff_t i, i_byte; + ptrdiff_t best_below, best_below_byte; + ptrdiff_t best_above, best_above_byte; best_below = best_below_byte = 0; best_above = SCHARS (string); @@ -877,7 +894,7 @@ static Lisp_Object string_make_multibyte (Lisp_Object string) { unsigned char *buf; - EMACS_INT nbytes; + ptrdiff_t nbytes; Lisp_Object ret; USE_SAFE_ALLOCA; @@ -910,7 +927,7 @@ Lisp_Object string_to_multibyte (Lisp_Object string) { unsigned char *buf; - EMACS_INT nbytes; + ptrdiff_t nbytes; Lisp_Object ret; USE_SAFE_ALLOCA; @@ -939,7 +956,7 @@ string_to_multibyte (Lisp_Object string) Lisp_Object string_make_unibyte (Lisp_Object string) { - EMACS_INT nchars; + ptrdiff_t nchars; unsigned char *buf; Lisp_Object ret; USE_SAFE_ALLOCA; @@ -1004,7 +1021,7 @@ If STRING is multibyte and contains a character of charset if (STRING_MULTIBYTE (string)) { - EMACS_INT bytes = SBYTES (string); + ptrdiff_t bytes = SBYTES (string); unsigned char *str = (unsigned char *) xmalloc (bytes); memcpy (str, SDATA (string), bytes); @@ -1037,7 +1054,7 @@ If you're not sure, whether to use `string-as-multibyte' or if (! STRING_MULTIBYTE (string)) { Lisp_Object new_string; - EMACS_INT nchars, nbytes; + ptrdiff_t nchars, nbytes; parse_str_as_multibyte (SDATA (string), SBYTES (string), @@ -1086,9 +1103,9 @@ an error is signaled. */) if (STRING_MULTIBYTE (string)) { - EMACS_INT chars = SCHARS (string); + ptrdiff_t chars = SCHARS (string); unsigned char *str = (unsigned char *) xmalloc (chars); - EMACS_INT converted = str_to_unibyte (SDATA (string), str, chars, 0); + ptrdiff_t converted = str_to_unibyte (SDATA (string), str, chars, 0); if (converted < chars) error ("Can't convert the %"pI"dth character to unibyte", converted); @@ -1139,27 +1156,19 @@ value is a new vector that contains the elements between index FROM (Lisp_Object string, register Lisp_Object from, Lisp_Object to) { Lisp_Object res; - EMACS_INT size; - EMACS_INT size_byte = 0; + ptrdiff_t size; EMACS_INT from_char, to_char; - EMACS_INT from_byte = 0, to_byte = 0; CHECK_VECTOR_OR_STRING (string); CHECK_NUMBER (from); if (STRINGP (string)) - { - size = SCHARS (string); - size_byte = SBYTES (string); - } + size = SCHARS (string); else size = ASIZE (string); if (NILP (to)) - { - to_char = size; - to_byte = size_byte; - } + to_char = size; else { CHECK_NUMBER (to); @@ -1167,23 +1176,19 @@ value is a new vector that contains the elements between index FROM to_char = XINT (to); if (to_char < 0) to_char += size; - - if (STRINGP (string)) - to_byte = string_char_to_byte (string, to_char); } from_char = XINT (from); if (from_char < 0) from_char += size; - if (STRINGP (string)) - from_byte = string_char_to_byte (string, from_char); - if (!(0 <= from_char && from_char <= to_char && to_char <= size)) args_out_of_range_3 (string, make_number (from_char), make_number (to_char)); - if (STRINGP (string)) { + ptrdiff_t to_byte = + (NILP (to) ? SBYTES (string) : string_char_to_byte (string, to_char)); + ptrdiff_t from_byte = string_char_to_byte (string, from_char); res = make_specified_string (SSDATA (string) + from_byte, to_char - from_char, to_byte - from_byte, STRING_MULTIBYTE (string)); @@ -1207,47 +1212,41 @@ If FROM or TO is negative, it counts from the end. With one argument, just copy STRING without its properties. */) (Lisp_Object string, register Lisp_Object from, Lisp_Object to) { - EMACS_INT size, size_byte; + ptrdiff_t size; EMACS_INT from_char, to_char; - EMACS_INT from_byte, to_byte; + ptrdiff_t from_byte, to_byte; CHECK_STRING (string); size = SCHARS (string); - size_byte = SBYTES (string); if (NILP (from)) - from_char = from_byte = 0; + from_char = 0; else { CHECK_NUMBER (from); from_char = XINT (from); if (from_char < 0) from_char += size; - - from_byte = string_char_to_byte (string, from_char); } if (NILP (to)) - { - to_char = size; - to_byte = size_byte; - } + to_char = size; else { CHECK_NUMBER (to); - to_char = XINT (to); if (to_char < 0) to_char += size; - - to_byte = string_char_to_byte (string, to_char); } if (!(0 <= from_char && from_char <= to_char && to_char <= size)) args_out_of_range_3 (string, make_number (from_char), make_number (to_char)); + from_byte = NILP (from) ? 0 : string_char_to_byte (string, from_char); + to_byte = + NILP (to) ? SBYTES (string) : string_char_to_byte (string, to_char); return make_specified_string (SSDATA (string) + from_byte, to_char - from_char, to_byte - from_byte, STRING_MULTIBYTE (string)); @@ -1257,11 +1256,11 @@ With one argument, just copy STRING without its properties. */) both in characters and in bytes. */ Lisp_Object -substring_both (Lisp_Object string, EMACS_INT from, EMACS_INT from_byte, - EMACS_INT to, EMACS_INT to_byte) +substring_both (Lisp_Object string, ptrdiff_t from, ptrdiff_t from_byte, + ptrdiff_t to, ptrdiff_t to_byte) { Lisp_Object res; - EMACS_INT size; + ptrdiff_t size; CHECK_VECTOR_OR_STRING (string); @@ -1595,7 +1594,7 @@ to be sure of changing the value of `foo'. */) { if (VECTORP (seq)) { - EMACS_INT i, n; + ptrdiff_t i, n; for (i = n = 0; i < ASIZE (seq); ++i) if (NILP (Fequal (AREF (seq, i), elt))) @@ -1614,7 +1613,7 @@ to be sure of changing the value of `foo'. */) } else if (STRINGP (seq)) { - EMACS_INT i, ibyte, nchars, nbytes, cbytes; + ptrdiff_t i, ibyte, nchars, nbytes, cbytes; int c; for (i = nchars = nbytes = ibyte = 0; @@ -1666,7 +1665,7 @@ to be sure of changing the value of `foo'. */) { unsigned char *from = SDATA (seq) + ibyte; unsigned char *to = SDATA (tem) + nbytes; - EMACS_INT n; + ptrdiff_t n; ++nchars; nbytes += cbytes; @@ -2073,7 +2072,7 @@ internal_equal (register Lisp_Object o1, register Lisp_Object o2, int depth, int case Lisp_Vectorlike: { register int i; - EMACS_INT size = ASIZE (o1); + ptrdiff_t size = ASIZE (o1); /* Pseudovectors have the type encoded in the size field, so this test actually checks that the objects have the same type as well as the same size. */ @@ -2140,7 +2139,7 @@ DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0, ARRAY is a vector, string, char-table, or bool-vector. */) (Lisp_Object array, Lisp_Object item) { - register EMACS_INT size, idx; + register ptrdiff_t size, idx; if (VECTORP (array)) { @@ -2168,7 +2167,7 @@ ARRAY is a vector, string, char-table, or bool-vector. */) { unsigned char str[MAX_MULTIBYTE_LENGTH]; int len = CHAR_STRING (charval, str); - EMACS_INT size_byte = SBYTES (array); + ptrdiff_t size_byte = SBYTES (array); if (INT_MULTIPLY_OVERFLOW (SCHARS (array), len) || SCHARS (array) * len != size_byte) @@ -2183,18 +2182,16 @@ ARRAY is a vector, string, char-table, or bool-vector. */) else if (BOOL_VECTOR_P (array)) { register unsigned char *p = XBOOL_VECTOR (array)->data; - EMACS_INT size_in_chars; - size = XBOOL_VECTOR (array)->size; - size_in_chars - = ((size + BOOL_VECTOR_BITS_PER_CHAR - 1) - / BOOL_VECTOR_BITS_PER_CHAR); + size = + ((XBOOL_VECTOR (array)->size + BOOL_VECTOR_BITS_PER_CHAR - 1) + / BOOL_VECTOR_BITS_PER_CHAR); - if (size_in_chars) + if (size) { - memset (p, ! NILP (item) ? -1 : 0, size_in_chars); + memset (p, ! NILP (item) ? -1 : 0, size); /* Clear any extraneous bits in the last byte. */ - p[size_in_chars - 1] &= (1 << (size % BOOL_VECTOR_BITS_PER_CHAR)) - 1; + p[size - 1] &= (1 << (size % BOOL_VECTOR_BITS_PER_CHAR)) - 1; } } else @@ -2208,7 +2205,7 @@ DEFUN ("clear-string", Fclear_string, Sclear_string, This makes STRING unibyte and may change its length. */) (Lisp_Object string) { - EMACS_INT len; + ptrdiff_t len; CHECK_STRING (string); len = SBYTES (string); memset (SDATA (string), 0, len); @@ -2318,12 +2315,12 @@ mapcar1 (EMACS_INT leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq) } else if (STRINGP (seq)) { - EMACS_INT i_byte; + ptrdiff_t i_byte; for (i = 0, i_byte = 0; i < leni;) { int c; - EMACS_INT i_before = i; + ptrdiff_t i_before = i; FETCH_STRING_CHAR_ADVANCE (c, seq, i, i_byte); XSETFASTINT (dummy, c); @@ -2356,7 +2353,8 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string. */) { Lisp_Object len; register EMACS_INT leni; - ptrdiff_t i, nargs; + EMACS_INT nargs; + ptrdiff_t i; register Lisp_Object *args; struct gcpro gcpro1; Lisp_Object ret; @@ -2611,6 +2609,7 @@ is not loaded; so load the file FILENAME. If FILENAME is omitted, the printname of FEATURE is used as the file name, and `load' will try to load this name appended with the suffix `.elc' or `.el', in that order. The name without appended suffix will not be used. +See `get-load-suffixes' for the complete list of suffixes. If the optional third argument NOERROR is non-nil, then return nil if the file is not found instead of signaling an error. Normally the return value is FEATURE. @@ -2642,7 +2641,7 @@ The normal messages at start and end of loading FILENAME are suppressed. */) if (NILP (tem)) { - int count = SPECPDL_INDEX (); + ptrdiff_t count = SPECPDL_INDEX (); int nesting = 0; /* This is to make sure that loadup.el gives a clear picture @@ -2945,9 +2944,9 @@ static const short base64_char_to_value[128] = base64 characters. */ -static EMACS_INT base64_encode_1 (const char *, char *, EMACS_INT, int, int); -static EMACS_INT base64_decode_1 (const char *, char *, EMACS_INT, int, - EMACS_INT *); +static ptrdiff_t base64_encode_1 (const char *, char *, ptrdiff_t, int, int); +static ptrdiff_t base64_decode_1 (const char *, char *, ptrdiff_t, int, + ptrdiff_t *); DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region, 2, 3, "r", @@ -2958,9 +2957,9 @@ into shorter lines. */) (Lisp_Object beg, Lisp_Object end, Lisp_Object no_line_break) { char *encoded; - EMACS_INT allength, length; - EMACS_INT ibeg, iend, encoded_length; - EMACS_INT old_pos = PT; + ptrdiff_t allength, length; + ptrdiff_t ibeg, iend, encoded_length; + ptrdiff_t old_pos = PT; USE_SAFE_ALLOCA; validate_region (&beg, &end); @@ -3016,7 +3015,7 @@ Optional second argument NO-LINE-BREAK means do not break long lines into shorter lines. */) (Lisp_Object string, Lisp_Object no_line_break) { - EMACS_INT allength, length, encoded_length; + ptrdiff_t allength, length, encoded_length; char *encoded; Lisp_Object encoded_string; USE_SAFE_ALLOCA; @@ -3052,12 +3051,12 @@ into shorter lines. */) return encoded_string; } -static EMACS_INT -base64_encode_1 (const char *from, char *to, EMACS_INT length, +static ptrdiff_t +base64_encode_1 (const char *from, char *to, ptrdiff_t length, int line_break, int multibyte) { int counter = 0; - EMACS_INT i = 0; + ptrdiff_t i = 0; char *e = to; int c; unsigned int value; @@ -3156,11 +3155,11 @@ Return the length of the decoded text. If the region can't be decoded, signal an error and don't modify the buffer. */) (Lisp_Object beg, Lisp_Object end) { - EMACS_INT ibeg, iend, length, allength; + ptrdiff_t ibeg, iend, length, allength; char *decoded; - EMACS_INT old_pos = PT; - EMACS_INT decoded_length; - EMACS_INT inserted_chars; + ptrdiff_t old_pos = PT; + ptrdiff_t decoded_length; + ptrdiff_t inserted_chars; int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); USE_SAFE_ALLOCA; @@ -3218,7 +3217,7 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string, (Lisp_Object string) { char *decoded; - EMACS_INT length, decoded_length; + ptrdiff_t length, decoded_length; Lisp_Object decoded_string; USE_SAFE_ALLOCA; @@ -3250,15 +3249,15 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string, form. If NCHARS_RETRUN is not NULL, store the number of produced characters in *NCHARS_RETURN. */ -static EMACS_INT -base64_decode_1 (const char *from, char *to, EMACS_INT length, - int multibyte, EMACS_INT *nchars_return) +static ptrdiff_t +base64_decode_1 (const char *from, char *to, ptrdiff_t length, + int multibyte, ptrdiff_t *nchars_return) { - EMACS_INT i = 0; /* Used inside READ_QUADRUPLET_BYTE */ + ptrdiff_t i = 0; /* Used inside READ_QUADRUPLET_BYTE */ char *e = to; unsigned char c; unsigned long value; - EMACS_INT nchars = 0; + ptrdiff_t nchars = 0; while (1) { @@ -3388,11 +3387,13 @@ check_hash_table (Lisp_Object obj) /* Value is the next integer I >= N, N >= 0 which is "almost" a prime - number. */ + number. A number is "almost" a prime number if it is not divisible + by any integer in the range 2 .. (NEXT_ALMOST_PRIME_LIMIT - 1). */ EMACS_INT next_almost_prime (EMACS_INT n) { + verify (NEXT_ALMOST_PRIME_LIMIT == 11); for (n |= 1; ; n += 2) if (n % 3 != 0 && n % 5 != 0 && n % 7 != 0) return n; @@ -3423,23 +3424,31 @@ get_key_arg (Lisp_Object key, ptrdiff_t nargs, Lisp_Object *args, char *used) /* Return a Lisp vector which has the same contents as VEC but has - size NEW_SIZE, NEW_SIZE >= VEC->size. Entries in the resulting - vector that are not copied from VEC are set to INIT. */ + at least INCR_MIN more entries, where INCR_MIN is positive. + If NITEMS_MAX is not -1, do not grow the vector to be any larger + than NITEMS_MAX. Entries in the resulting + vector that are not copied from VEC are set to nil. */ Lisp_Object -larger_vector (Lisp_Object vec, EMACS_INT new_size, Lisp_Object init) +larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t size_max) { struct Lisp_Vector *v; - EMACS_INT i, old_size; - + ptrdiff_t i, incr, incr_max, old_size, new_size; + ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / sizeof *v->contents; + ptrdiff_t n_max = (0 <= size_max && size_max < C_language_max + ? size_max : C_language_max); xassert (VECTORP (vec)); + xassert (0 < incr_min && -1 <= size_max); old_size = ASIZE (vec); - xassert (new_size >= old_size); - + incr_max = n_max - old_size; + incr = max (incr_min, min (old_size >> 1, incr_max)); + if (incr_max < incr) + memory_full (SIZE_MAX); + new_size = old_size + incr; v = allocate_vector (new_size); memcpy (v->contents, XVECTOR (vec)->contents, old_size * sizeof *v->contents); for (i = old_size; i < new_size; ++i) - v->contents[i] = init; + v->contents[i] = Qnil; XSETVECTOR (vec, v); return vec; } @@ -3560,6 +3569,10 @@ hashfn_user_defined (struct Lisp_Hash_Table *h, Lisp_Object key) return XUINT (hash); } +/* An upper bound on the size of a hash table index. It must fit in + ptrdiff_t and be a valid Emacs fixnum. */ +#define INDEX_SIZE_BOUND \ + ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, PTRDIFF_MAX / sizeof (Lisp_Object))) /* Create and initialize a new hash table. @@ -3590,7 +3603,8 @@ make_hash_table (Lisp_Object test, Lisp_Object size, Lisp_Object rehash_size, { struct Lisp_Hash_Table *h; Lisp_Object table; - EMACS_INT index_size, i, sz; + EMACS_INT index_size, sz; + ptrdiff_t i; double index_float; /* Preconditions. */ @@ -3607,10 +3621,10 @@ make_hash_table (Lisp_Object test, Lisp_Object size, Lisp_Object rehash_size, sz = XFASTINT (size); index_float = sz / XFLOAT_DATA (rehash_threshold); - index_size = (index_float < MOST_POSITIVE_FIXNUM + 1 + index_size = (index_float < INDEX_SIZE_BOUND + 1 ? next_almost_prime (index_float) - : MOST_POSITIVE_FIXNUM + 1); - if (MOST_POSITIVE_FIXNUM < max (index_size, 2 * sz)) + : INDEX_SIZE_BOUND + 1); + if (INDEX_SIZE_BOUND < max (index_size, 2 * sz)) error ("Hash table too large"); /* Allocate a table and initialize it. */ @@ -3711,9 +3725,9 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h) { if (NILP (h->next_free)) { - EMACS_INT old_size = HASH_TABLE_SIZE (h); - EMACS_INT i, new_size, index_size; - EMACS_INT nsize; + ptrdiff_t old_size = HASH_TABLE_SIZE (h); + EMACS_INT new_size, index_size, nsize; + ptrdiff_t i; double index_float; if (INTEGERP (h->rehash_size)) @@ -3721,26 +3735,27 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h) else { double float_new_size = old_size * XFLOAT_DATA (h->rehash_size); - if (float_new_size < MOST_POSITIVE_FIXNUM + 1) + if (float_new_size < INDEX_SIZE_BOUND + 1) { new_size = float_new_size; if (new_size <= old_size) new_size = old_size + 1; } else - new_size = MOST_POSITIVE_FIXNUM + 1; + new_size = INDEX_SIZE_BOUND + 1; } index_float = new_size / XFLOAT_DATA (h->rehash_threshold); - index_size = (index_float < MOST_POSITIVE_FIXNUM + 1 + index_size = (index_float < INDEX_SIZE_BOUND + 1 ? next_almost_prime (index_float) - : MOST_POSITIVE_FIXNUM + 1); + : INDEX_SIZE_BOUND + 1); nsize = max (index_size, 2 * new_size); - if (nsize > MOST_POSITIVE_FIXNUM) + if (INDEX_SIZE_BOUND < nsize) error ("Hash table too large to resize"); - h->key_and_value = larger_vector (h->key_and_value, 2 * new_size, Qnil); - h->next = larger_vector (h->next, new_size, Qnil); - h->hash = larger_vector (h->hash, new_size, Qnil); + h->key_and_value = larger_vector (h->key_and_value, + 2 * (new_size - old_size), -1); + h->next = larger_vector (h->next, new_size - old_size, -1); + h->hash = larger_vector (h->hash, new_size - old_size, -1); h->index = Fmake_vector (make_number (index_size), Qnil); /* Update the free list. Do it so that new entries are added at @@ -3768,7 +3783,7 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h) if (!NILP (HASH_HASH (h, i))) { EMACS_UINT hash_code = XUINT (HASH_HASH (h, i)); - EMACS_INT start_of_bucket = hash_code % ASIZE (h->index); + ptrdiff_t start_of_bucket = hash_code % ASIZE (h->index); HASH_NEXT (h, i) = HASH_INDEX (h, start_of_bucket); HASH_INDEX (h, start_of_bucket) = make_number (i); } @@ -3780,11 +3795,11 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h) the hash code of KEY. Value is the index of the entry in H matching KEY, or -1 if not found. */ -EMACS_INT +ptrdiff_t hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash) { EMACS_UINT hash_code; - EMACS_INT start_of_bucket; + ptrdiff_t start_of_bucket; Lisp_Object idx; hash_code = h->hashfn (h, key); @@ -3797,7 +3812,7 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash) /* We need not gcpro idx since it's either an integer or nil. */ while (!NILP (idx)) { - EMACS_INT i = XFASTINT (idx); + ptrdiff_t i = XFASTINT (idx); if (EQ (key, HASH_KEY (h, i)) || (h->cmpfn && h->cmpfn (h, key, hash_code, @@ -3814,11 +3829,11 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash) HASH is a previously computed hash code of KEY. Value is the index of the entry in H matching KEY. */ -EMACS_INT +ptrdiff_t hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value, EMACS_UINT hash) { - EMACS_INT start_of_bucket, i; + ptrdiff_t start_of_bucket, i; xassert ((hash & ~INTMASK) == 0); @@ -3849,7 +3864,7 @@ static void hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key) { EMACS_UINT hash_code; - EMACS_INT start_of_bucket; + ptrdiff_t start_of_bucket; Lisp_Object idx, prev; hash_code = h->hashfn (h, key); @@ -3860,7 +3875,7 @@ hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key) /* We need not gcpro idx, prev since they're either integers or nil. */ while (!NILP (idx)) { - EMACS_INT i = XFASTINT (idx); + ptrdiff_t i = XFASTINT (idx); if (EQ (key, HASH_KEY (h, i)) || (h->cmpfn @@ -3898,7 +3913,7 @@ hash_clear (struct Lisp_Hash_Table *h) { if (h->count > 0) { - EMACS_INT i, size = HASH_TABLE_SIZE (h); + ptrdiff_t i, size = HASH_TABLE_SIZE (h); for (i = 0; i < size; ++i) { @@ -3936,7 +3951,7 @@ init_weak_hash_tables (void) static int sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p) { - EMACS_INT bucket, n; + ptrdiff_t bucket, n; int marked; n = ASIZE (h->index) & ~ARRAY_MARK_FLAG; @@ -3951,7 +3966,7 @@ sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p) prev = Qnil; for (idx = HASH_INDEX (h, bucket); !NILP (idx); idx = next) { - EMACS_INT i = XFASTINT (idx); + ptrdiff_t i = XFASTINT (idx); int key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i)); int value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i)); int remove_p; @@ -4091,25 +4106,33 @@ sweep_weak_hash_tables (void) #define SXHASH_REDUCE(X) \ ((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK) -/* Return a hash for string PTR which has length LEN. The hash - code returned is guaranteed to fit in a Lisp integer. */ +/* Return a hash for string PTR which has length LEN. The hash value + can be any EMACS_UINT value. */ -static EMACS_UINT -sxhash_string (unsigned char *ptr, EMACS_INT len) +EMACS_UINT +hash_string (char const *ptr, ptrdiff_t len) { - unsigned char *p = ptr; - unsigned char *end = p + len; + char const *p = ptr; + char const *end = p + len; unsigned char c; EMACS_UINT hash = 0; while (p != end) { c = *p++; - if (c >= 0140) - c -= 40; hash = SXHASH_COMBINE (hash, c); } + return hash; +} + +/* Return a hash for string PTR which has length LEN. The hash + code returned is guaranteed to fit in a Lisp integer. */ + +static EMACS_UINT +sxhash_string (char const *ptr, ptrdiff_t len) +{ + EMACS_UINT hash = hash_string (ptr, len); return SXHASH_REDUCE (hash); } @@ -4224,7 +4247,7 @@ sxhash (Lisp_Object obj, int depth) /* Fall through. */ case Lisp_String: - hash = sxhash_string (SDATA (obj), SCHARS (obj)); + hash = sxhash_string (SSDATA (obj), SBYTES (obj)); break; /* This can be everything from a vector to an overlay. */ @@ -4467,7 +4490,7 @@ If KEY is not found, return DFLT which defaults to nil. */) (Lisp_Object key, Lisp_Object table, Lisp_Object dflt) { struct Lisp_Hash_Table *h = check_hash_table (table); - EMACS_INT i = hash_lookup (h, key, NULL); + ptrdiff_t i = hash_lookup (h, key, NULL); return i >= 0 ? HASH_VALUE (h, i) : dflt; } @@ -4479,7 +4502,7 @@ VALUE. In any case, return VALUE. */) (Lisp_Object key, Lisp_Object value, Lisp_Object table) { struct Lisp_Hash_Table *h = check_hash_table (table); - EMACS_INT i; + ptrdiff_t i; EMACS_UINT hash; i = hash_lookup (h, key, &hash); @@ -4509,7 +4532,7 @@ FUNCTION is called with two arguments, KEY and VALUE. */) { struct Lisp_Hash_Table *h = check_hash_table (table); Lisp_Object args[3]; - EMACS_INT i; + ptrdiff_t i; for (i = 0; i < HASH_TABLE_SIZE (h); ++i) if (!NILP (HASH_HASH (h, i))) @@ -4544,31 +4567,31 @@ including negative integers. */) /************************************************************************ - MD5 and SHA1 + MD5, SHA-1, and SHA-2 ************************************************************************/ #include "md5.h" #include "sha1.h" +#include "sha256.h" +#include "sha512.h" -/* Convert a possibly-signed character to an unsigned character. This is - a bit safer than casting to unsigned char, since it catches some type - errors that the cast doesn't. */ -static inline unsigned char to_uchar (char ch) { return ch; } - -/* TYPE: 0 for md5, 1 for sha1. */ +/* ALGORITHM is a symbol: md5, sha1, sha224 and so on. */ static Lisp_Object -crypto_hash_function (int type, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror, Lisp_Object binary) +secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror, Lisp_Object binary) { int i; - EMACS_INT size; - EMACS_INT size_byte = 0; + ptrdiff_t size; EMACS_INT start_char = 0, end_char = 0; - EMACS_INT start_byte = 0, end_byte = 0; + ptrdiff_t start_byte, end_byte; register EMACS_INT b, e; register struct buffer *bp; EMACS_INT temp; - Lisp_Object res=Qnil; + int digest_size; + void *(*hash_func) (const char *, size_t, void *); + Lisp_Object digest; + + CHECK_SYMBOL (algorithm); if (STRINGP (object)) { @@ -4597,7 +4620,6 @@ crypto_hash_function (int type, Lisp_Object object, Lisp_Object start, Lisp_Obje object = code_convert_string (object, coding_system, Qnil, 1, 0, 1); size = SCHARS (object); - size_byte = SBYTES (object); if (!NILP (start)) { @@ -4607,15 +4629,10 @@ crypto_hash_function (int type, Lisp_Object object, Lisp_Object start, Lisp_Obje if (start_char < 0) start_char += size; - - start_byte = string_char_to_byte (object, start_char); } if (NILP (end)) - { - end_char = size; - end_byte = size_byte; - } + end_char = size; else { CHECK_NUMBER (end); @@ -4624,13 +4641,15 @@ crypto_hash_function (int type, Lisp_Object object, Lisp_Object start, Lisp_Obje if (end_char < 0) end_char += size; - - end_byte = string_char_to_byte (object, end_char); } if (!(0 <= start_char && start_char <= end_char && end_char <= size)) args_out_of_range_3 (object, make_number (start_char), make_number (end_char)); + + start_byte = NILP (start) ? 0 : string_char_to_byte (object, start_char); + end_byte = + NILP (end) ? SBYTES (object) : string_char_to_byte (object, end_char); } else { @@ -4686,13 +4705,13 @@ crypto_hash_function (int type, Lisp_Object object, Lisp_Object start, Lisp_Obje force_raw_text = 1; } - if (NILP (coding_system) && !NILP (Fbuffer_file_name(object))) + if (NILP (coding_system) && !NILP (Fbuffer_file_name (object))) { /* Check file-coding-system-alist. */ Lisp_Object args[4], val; args[0] = Qwrite_region; args[1] = start; args[2] = end; - args[3] = Fbuffer_file_name(object); + args[3] = Fbuffer_file_name (object); val = Ffind_operation_coding_system (4, args); if (CONSP (val) && !NILP (XCDR (val))) coding_system = XCDR (val); @@ -4737,49 +4756,65 @@ crypto_hash_function (int type, Lisp_Object object, Lisp_Object start, Lisp_Obje if (STRING_MULTIBYTE (object)) object = code_convert_string (object, coding_system, Qnil, 1, 0, 0); + start_byte = 0; + end_byte = SBYTES (object); } - switch (type) + if (EQ (algorithm, Qmd5)) { - case 0: /* MD5 */ - { - char digest[16]; - md5_buffer (SSDATA (object) + start_byte, - SBYTES (object) - (size_byte - end_byte), - digest); + digest_size = MD5_DIGEST_SIZE; + hash_func = md5_buffer; + } + else if (EQ (algorithm, Qsha1)) + { + digest_size = SHA1_DIGEST_SIZE; + hash_func = sha1_buffer; + } + else if (EQ (algorithm, Qsha224)) + { + digest_size = SHA224_DIGEST_SIZE; + hash_func = sha224_buffer; + } + else if (EQ (algorithm, Qsha256)) + { + digest_size = SHA256_DIGEST_SIZE; + hash_func = sha256_buffer; + } + else if (EQ (algorithm, Qsha384)) + { + digest_size = SHA384_DIGEST_SIZE; + hash_func = sha384_buffer; + } + else if (EQ (algorithm, Qsha512)) + { + digest_size = SHA512_DIGEST_SIZE; + hash_func = sha512_buffer; + } + else + error ("Invalid algorithm arg: %s", SDATA (Fsymbol_name (algorithm))); - if (NILP (binary)) - { - char value[33]; - for (i = 0; i < 16; i++) - sprintf (&value[2 * i], "%02x", to_uchar (digest[i])); - res = make_string (value, 32); - } - else - res = make_string (digest, 16); - break; - } + /* allocate 2 x digest_size so that it can be re-used to hold the + hexified value */ + digest = make_uninit_string (digest_size * 2); - case 1: /* SHA1 */ - { - char digest[20]; - sha1_buffer (SSDATA (object) + start_byte, - SBYTES (object) - (size_byte - end_byte), - digest); - if (NILP (binary)) - { - char value[41]; - for (i = 0; i < 20; i++) - sprintf (&value[2 * i], "%02x", to_uchar (digest[i])); - res = make_string (value, 40); - } - else - res = make_string (digest, 20); - break; - } - } + hash_func (SSDATA (object) + start_byte, + end_byte - start_byte, + SSDATA (digest)); - return res; + if (NILP (binary)) + { + unsigned char *p = SDATA (digest); + for (i = digest_size - 1; i >= 0; i--) + { + static char const hexdigit[16] = "0123456789abcdef"; + int p_i = p[i]; + p[2 * i] = hexdigit[p_i >> 4]; + p[2 * i + 1] = hexdigit[p_i & 0xf]; + } + return digest; + } + else + return make_unibyte_string (SSDATA (digest), digest_size); } DEFUN ("md5", Fmd5, Smd5, 1, 5, 0, @@ -4811,54 +4846,46 @@ If NOERROR is non-nil, silently assume the `raw-text' coding if the guesswork fails. Normally, an error is signaled in such case. */) (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror) { - return crypto_hash_function (0, object, start, end, coding_system, noerror, Qnil); + return secure_hash (Qmd5, object, start, end, coding_system, noerror, Qnil); } -DEFUN ("sha1", Fsha1, Ssha1, 1, 4, 0, - doc: /* Return the SHA-1 (Secure Hash Algorithm) of an OBJECT. - -OBJECT is either a string or a buffer. Optional arguments START and -END are character positions specifying which portion of OBJECT for -computing the hash. If BINARY is non-nil, return a string in binary -form. */) - (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary) +DEFUN ("secure-hash", Fsecure_hash, Ssecure_hash, 2, 5, 0, + doc: /* Return the secure hash of an OBJECT. +ALGORITHM is a symbol: md5, sha1, sha224, sha256, sha384 or sha512. +OBJECT is either a string or a buffer. +Optional arguments START and END are character positions specifying +which portion of OBJECT for computing the hash. If BINARY is non-nil, +return a string in binary form. */) + (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary) { - return crypto_hash_function (1, object, start, end, Qnil, Qnil, binary); + return secure_hash (algorithm, object, start, end, Qnil, Qnil, binary); } - void syms_of_fns (void) { + DEFSYM (Qmd5, "md5"); + DEFSYM (Qsha1, "sha1"); + DEFSYM (Qsha224, "sha224"); + DEFSYM (Qsha256, "sha256"); + DEFSYM (Qsha384, "sha384"); + DEFSYM (Qsha512, "sha512"); + /* Hash table stuff. */ - Qhash_table_p = intern_c_string ("hash-table-p"); - staticpro (&Qhash_table_p); - Qeq = intern_c_string ("eq"); - staticpro (&Qeq); - Qeql = intern_c_string ("eql"); - staticpro (&Qeql); - Qequal = intern_c_string ("equal"); - staticpro (&Qequal); - QCtest = intern_c_string (":test"); - staticpro (&QCtest); - QCsize = intern_c_string (":size"); - staticpro (&QCsize); - QCrehash_size = intern_c_string (":rehash-size"); - staticpro (&QCrehash_size); - QCrehash_threshold = intern_c_string (":rehash-threshold"); - staticpro (&QCrehash_threshold); - QCweakness = intern_c_string (":weakness"); - staticpro (&QCweakness); - Qkey = intern_c_string ("key"); - staticpro (&Qkey); - Qvalue = intern_c_string ("value"); - staticpro (&Qvalue); - Qhash_table_test = intern_c_string ("hash-table-test"); - staticpro (&Qhash_table_test); - Qkey_or_value = intern_c_string ("key-or-value"); - staticpro (&Qkey_or_value); - Qkey_and_value = intern_c_string ("key-and-value"); - staticpro (&Qkey_and_value); + DEFSYM (Qhash_table_p, "hash-table-p"); + DEFSYM (Qeq, "eq"); + DEFSYM (Qeql, "eql"); + DEFSYM (Qequal, "equal"); + DEFSYM (QCtest, ":test"); + DEFSYM (QCsize, ":size"); + DEFSYM (QCrehash_size, ":rehash-size"); + DEFSYM (QCrehash_threshold, ":rehash-threshold"); + DEFSYM (QCweakness, ":weakness"); + DEFSYM (Qkey, "key"); + DEFSYM (Qvalue, "value"); + DEFSYM (Qhash_table_test, "hash-table-test"); + DEFSYM (Qkey_or_value, "key-or-value"); + DEFSYM (Qkey_and_value, "key-and-value"); defsubr (&Ssxhash); defsubr (&Smake_hash_table); @@ -4877,18 +4904,12 @@ syms_of_fns (void) defsubr (&Smaphash); defsubr (&Sdefine_hash_table_test); - Qstring_lessp = intern_c_string ("string-lessp"); - staticpro (&Qstring_lessp); - Qprovide = intern_c_string ("provide"); - staticpro (&Qprovide); - Qrequire = intern_c_string ("require"); - staticpro (&Qrequire); - Qyes_or_no_p_history = intern_c_string ("yes-or-no-p-history"); - staticpro (&Qyes_or_no_p_history); - Qcursor_in_echo_area = intern_c_string ("cursor-in-echo-area"); - staticpro (&Qcursor_in_echo_area); - Qwidget_type = intern_c_string ("widget-type"); - staticpro (&Qwidget_type); + DEFSYM (Qstring_lessp, "string-lessp"); + DEFSYM (Qprovide, "provide"); + DEFSYM (Qrequire, "require"); + DEFSYM (Qyes_or_no_p_history, "yes-or-no-p-history"); + DEFSYM (Qcursor_in_echo_area, "cursor-in-echo-area"); + DEFSYM (Qwidget_type, "widget-type"); staticpro (&string_char_byte_cache_string); string_char_byte_cache_string = Qnil; @@ -4902,18 +4923,13 @@ syms_of_fns (void) doc: /* A list of symbols which are the features of the executing Emacs. Used by `featurep' and `require', and altered by `provide'. */); Vfeatures = Fcons (intern_c_string ("emacs"), Qnil); - Qsubfeatures = intern_c_string ("subfeatures"); - staticpro (&Qsubfeatures); + DEFSYM (Qsubfeatures, "subfeatures"); #ifdef HAVE_LANGINFO_CODESET - Qcodeset = intern_c_string ("codeset"); - staticpro (&Qcodeset); - Qdays = intern_c_string ("days"); - staticpro (&Qdays); - Qmonths = intern_c_string ("months"); - staticpro (&Qmonths); - Qpaper = intern_c_string ("paper"); - staticpro (&Qpaper); + DEFSYM (Qcodeset, "codeset"); + DEFSYM (Qdays, "days"); + DEFSYM (Qmonths, "months"); + DEFSYM (Qpaper, "paper"); #endif /* HAVE_LANGINFO_CODESET */ DEFVAR_BOOL ("use-dialog-box", use_dialog_box, @@ -4998,7 +5014,7 @@ this variable. */); defsubr (&Sbase64_encode_string); defsubr (&Sbase64_decode_string); defsubr (&Smd5); - defsubr (&Ssha1); + defsubr (&Ssecure_hash); defsubr (&Slocale_info); }