#include <time.h>
#include <setjmp.h>
+#include <intprops.h>
+
#include "lisp.h"
#include "commands.h"
#include "character.h"
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
{
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,
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));
return lispy_val;
}
\f
+/* Heuristic on how many iterations of a tight loop can be safely done
+ before it's time to do a QUIT. This must be a power of 2. */
+enum { QUIT_COUNT_HEURISTIC = 1 << 16 };
+
/* Random data-structure functions */
DEFUN ("length", Flength, Slength, 1, 1, 0,
(register Lisp_Object sequence)
{
register Lisp_Object val;
- register int i;
if (STRINGP (sequence))
XSETFASTINT (val, SCHARS (sequence));
XSETFASTINT (val, ASIZE (sequence) & PSEUDOVECTOR_SIZE_MASK);
else if (CONSP (sequence))
{
- i = 0;
- while (CONSP (sequence))
+ EMACS_INT i = 0;
+
+ do
{
- sequence = XCDR (sequence);
++i;
-
- if (!CONSP (sequence))
- break;
-
+ if ((i & (QUIT_COUNT_HEURISTIC - 1)) == 0)
+ {
+ if (MOST_POSITIVE_FIXNUM < i)
+ error ("List too long");
+ QUIT;
+ }
sequence = XCDR (sequence);
- ++i;
- QUIT;
}
+ while (CONSP (sequence));
CHECK_LIST_END (sequence, sequence);
which is at least the number of distinct elements. */)
(Lisp_Object list)
{
- Lisp_Object tail, halftail, length;
- int len = 0;
+ Lisp_Object tail, halftail;
+ double hilen = 0;
+ uintmax_t lolen = 1;
+
+ if (! CONSP (list))
+ return make_number (0);
/* halftail is used to detect circular lists. */
- halftail = list;
- for (tail = list; CONSP (tail); tail = XCDR (tail))
+ for (tail = halftail = list; ; )
{
- if (EQ (tail, halftail) && len != 0)
+ tail = XCDR (tail);
+ if (! CONSP (tail))
break;
- len++;
- if ((len & 1) == 0)
- halftail = XCDR (halftail);
+ if (EQ (tail, halftail))
+ break;
+ lolen++;
+ if ((lolen & 1) == 0)
+ {
+ halftail = XCDR (halftail);
+ if ((lolen & (QUIT_COUNT_HEURISTIC - 1)) == 0)
+ {
+ QUIT;
+ if (lolen == 0)
+ hilen += UINTMAX_MAX + 1.0;
+ }
+ }
}
- XSETINT (length, len);
- return length;
+ /* If the length does not fit into a fixnum, return a float.
+ On all known practical machines this returns an upper bound on
+ the true length. */
+ return hilen ? make_float (hilen + lolen) : make_fixnum_or_float (lolen);
}
DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0,
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);
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)
{
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);
return i1 < SCHARS (s2) ? Qt : Qnil;
}
\f
-static Lisp_Object concat (size_t nargs, Lisp_Object *args,
+static Lisp_Object concat (ptrdiff_t nargs, Lisp_Object *args,
enum Lisp_Type target_type, int last_special);
/* ARGSUSED */
Each argument may be a list, vector or string.
The last argument is not copied, just used as the tail of the new list.
usage: (append &rest SEQUENCES) */)
- (size_t nargs, Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
return concat (nargs, args, Lisp_Cons, 1);
}
The result is a string whose elements are the elements of all the arguments.
Each argument may be a string or a list or vector of characters (integers).
usage: (concat &rest SEQUENCES) */)
- (size_t nargs, Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
return concat (nargs, args, Lisp_String, 0);
}
The result is a vector whose elements are the elements of all the arguments.
Each argument may be a list, vector or string.
usage: (vconcat &rest SEQUENCES) */)
- (size_t nargs, Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
return concat (nargs, args, Lisp_Vectorlike, 0);
}
if (BOOL_VECTOR_P (arg))
{
Lisp_Object val;
- int size_in_chars
+ ptrdiff_t size_in_chars
= ((XBOOL_VECTOR (arg)->size + BOOL_VECTOR_BITS_PER_CHAR - 1)
/ BOOL_VECTOR_BITS_PER_CHAR);
a string and has text properties to be copied. */
struct textprop_rec
{
- int 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 argnum; /* refer to ARGS (arguments of `concat') */
+ ptrdiff_t from; /* refer to ARGS[argnum] (argument string) */
+ ptrdiff_t to; /* refer to VAL (the target string) */
};
static Lisp_Object
-concat (size_t nargs, Lisp_Object *args,
+concat (ptrdiff_t nargs, Lisp_Object *args,
enum Lisp_Type target_type, int last_special)
{
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;
- register size_t argnum;
+ ptrdiff_t argnum;
Lisp_Object last_tail;
Lisp_Object prev;
int some_multibyte;
here, and copy the text properties after the concatenation. */
struct textprop_rec *textprops = NULL;
/* Number of elements in textprops. */
- int num_textprops = 0;
+ ptrdiff_t num_textprops = 0;
USE_SAFE_ALLOCA;
tail = Qnil;
{
/* 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;
- EMACS_INT this_len_byte;
+ int c;
+ ptrdiff_t this_len_byte;
if (VECTORP (this) || COMPILEDP (this))
for (i = 0; i < len; i++)
{
ch = AREF (this, i);
CHECK_CHARACTER (ch);
- this_len_byte = CHAR_BYTES (XINT (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 (XINT (ch)) && ! CHAR_BYTE8_P (XINT (ch)))
+ if (! ASCII_CHAR_P (c) && ! CHAR_BYTE8_P (c))
some_multibyte = 1;
}
else if (BOOL_VECTOR_P (this) && XBOOL_VECTOR (this)->size > 0)
{
ch = XCAR (this);
CHECK_CHARACTER (ch);
- this_len_byte = CHAR_BYTES (XINT (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 (XINT (ch)) && ! CHAR_BYTE8_P (XINT (ch)))
+ if (! ASCII_CHAR_P (c) && ! CHAR_BYTE8_P (c))
some_multibyte = 1;
}
else if (STRINGP (this))
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 (result_len < 0)
- error ("String overflow");
+ if (MOST_POSITIVE_FIXNUM < result_len)
+ memory_full (SIZE_MAX);
}
if (! some_multibyte)
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))
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)))
{
int c;
if (STRING_MULTIBYTE (this))
- {
- FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, this,
- thisindex,
- thisindex_byte);
- XSETFASTINT (elt, c);
- }
+ FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, this,
+ thisindex,
+ thisindex_byte);
else
{
- XSETFASTINT (elt, SREF (this, thisindex)); thisindex++;
- if (some_multibyte
- && !ASCII_CHAR_P (XINT (elt))
- && XINT (elt) < 0400)
- {
- c = BYTE8_TO_CHAR (XINT (elt));
- XSETINT (elt, c);
- }
+ c = SREF (this, thisindex); thisindex++;
+ if (some_multibyte && !ASCII_CHAR_P (c))
+ c = BYTE8_TO_CHAR (c);
}
+ XSETFASTINT (elt, c);
}
else if (BOOL_VECTOR_P (this))
{
}
else
{
- CHECK_NUMBER (elt);
+ int c;
+ CHECK_CHARACTER (elt);
+ c = XFASTINT (elt);
if (some_multibyte)
- toindex_byte += CHAR_STRING (XINT (elt),
- SDATA (val) + toindex_byte);
+ toindex_byte += CHAR_STRING (c, SDATA (val) + toindex_byte);
else
- SSET (val, toindex_byte++, XINT (elt));
+ SSET (val, toindex_byte++, c);
toindex++;
}
}
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++)
{
}
\f
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)
/* 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);
\f
/* 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);
string_make_multibyte (Lisp_Object string)
{
unsigned char *buf;
- EMACS_INT nbytes;
+ ptrdiff_t nbytes;
Lisp_Object ret;
USE_SAFE_ALLOCA;
string_to_multibyte (Lisp_Object string)
{
unsigned char *buf;
- EMACS_INT nbytes;
+ ptrdiff_t nbytes;
Lisp_Object ret;
USE_SAFE_ALLOCA;
Lisp_Object
string_make_unibyte (Lisp_Object string)
{
- EMACS_INT nchars;
+ ptrdiff_t nchars;
unsigned char *buf;
Lisp_Object ret;
USE_SAFE_ALLOCA;
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);
if (! STRING_MULTIBYTE (string))
{
Lisp_Object new_string;
- EMACS_INT nchars, nbytes;
+ ptrdiff_t nchars, nbytes;
parse_str_as_multibyte (SDATA (string),
SBYTES (string),
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);
(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);
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));
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));
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);
doc: /* Take cdr N times on LIST, return the result. */)
(Lisp_Object n, Lisp_Object list)
{
- register int i, num;
+ EMACS_INT i, num;
CHECK_NUMBER (n);
num = XINT (n);
for (i = 0; i < num && !NILP (list); i++)
{
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)))
}
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;
{
unsigned char *from = SDATA (seq) + ibyte;
unsigned char *to = SDATA (tem) + nbytes;
- EMACS_INT n;
+ ptrdiff_t n;
++nchars;
nbytes += cbytes;
Lisp_Object front, back;
register Lisp_Object len, tem;
struct gcpro gcpro1, gcpro2;
- register int length;
+ EMACS_INT length;
front = list;
len = Flength (list);
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. */
ARRAY is a vector, string, char-table, or bool-vector. */)
(Lisp_Object array, Lisp_Object item)
{
- register EMACS_INT size, idx;
- int charval;
+ register ptrdiff_t size, idx;
if (VECTORP (array))
{
else if (STRINGP (array))
{
register unsigned char *p = SDATA (array);
- CHECK_NUMBER (item);
- charval = XINT (item);
+ int charval;
+ CHECK_CHARACTER (item);
+ charval = XFASTINT (item);
size = SCHARS (array);
if (STRING_MULTIBYTE (array))
{
unsigned char str[MAX_MULTIBYTE_LENGTH];
int len = CHAR_STRING (charval, str);
- EMACS_INT size_byte = SBYTES (array);
- unsigned char *p1 = p, *endp = p + size_byte;
- int i;
+ ptrdiff_t size_byte = SBYTES (array);
- if (size != size_byte)
- while (p1 < endp)
- {
- int this_len = BYTES_BY_CHAR_HEAD (*p1);
- if (len != this_len)
- error ("Attempt to change byte length of a string");
- p1 += this_len;
- }
- for (i = 0; i < size_byte; i++)
- *p++ = str[i % len];
+ if (INT_MULTIPLY_OVERFLOW (SCHARS (array), len)
+ || SCHARS (array) * len != size_byte)
+ error ("Attempt to change byte length of a string");
+ for (idx = 0; idx < size_byte; idx++)
+ *p++ = str[idx % len];
}
else
for (idx = 0; idx < size; idx++)
else if (BOOL_VECTOR_P (array))
{
register unsigned char *p = XBOOL_VECTOR (array)->data;
- int size_in_chars
- = ((XBOOL_VECTOR (array)->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);
- charval = (! NILP (item) ? -1 : 0);
- for (idx = 0; idx < size_in_chars - 1; idx++)
- p[idx] = charval;
- if (idx < size_in_chars)
+ if (size)
{
- /* Mask out bits beyond the vector size. */
- if (XBOOL_VECTOR (array)->size % BOOL_VECTOR_BITS_PER_CHAR)
- charval &= (1 << (XBOOL_VECTOR (array)->size % BOOL_VECTOR_BITS_PER_CHAR)) - 1;
- p[idx] = charval;
+ memset (p, ! NILP (item) ? -1 : 0, size);
+
+ /* Clear any extraneous bits in the last byte. */
+ p[size - 1] &= (1 << (size % BOOL_VECTOR_BITS_PER_CHAR)) - 1;
}
}
else
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);
doc: /* Concatenate any number of lists by altering them.
Only the last argument is not altered, and need not be a list.
usage: (nconc &rest LISTS) */)
- (size_t nargs, Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
- register size_t argnum;
+ ptrdiff_t argnum;
register Lisp_Object tail, tem, val;
val = tail = Qnil;
{
for (i = 0; i < leni; i++)
{
- int byte;
+ unsigned char byte;
byte = XBOOL_VECTOR (seq)->data[i / BOOL_VECTOR_BITS_PER_CHAR];
dummy = (byte & (1 << (i % BOOL_VECTOR_BITS_PER_CHAR))) ? Qt : Qnil;
dummy = call1 (fn, dummy);
}
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);
{
Lisp_Object len;
register EMACS_INT leni;
- int nargs;
+ EMACS_INT nargs;
+ ptrdiff_t i;
register Lisp_Object *args;
- register EMACS_INT i;
struct gcpro gcpro1;
Lisp_Object ret;
USE_SAFE_ALLOCA;
while (loads-- > 0)
{
- Lisp_Object load = (NILP (use_floats) ?
- make_number ((int) (100.0 * load_ave[loads]))
+ Lisp_Object load = (NILP (use_floats)
+ ? make_number (100.0 * load_ave[loads])
: make_float (load_ave[loads]));
ret = Fcons (load, ret);
}
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.
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
doc: /* Apply the value of WIDGET's PROPERTY to the widget itself.
ARGS are passed as extra arguments to the function.
usage: (widget-apply WIDGET PROPERTY &rest ARGS) */)
- (size_t nargs, Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
/* This function can GC. */
Lisp_Object newargs[3];
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",
(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);
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;
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;
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;
(Lisp_Object string)
{
char *decoded;
- EMACS_INT length, decoded_length;
+ ptrdiff_t length, decoded_length;
Lisp_Object decoded_string;
USE_SAFE_ALLOCA;
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)
{
/* Function prototypes. */
static struct Lisp_Hash_Table *check_hash_table (Lisp_Object);
-static size_t get_key_arg (Lisp_Object, size_t, Lisp_Object *, char *);
+static ptrdiff_t get_key_arg (Lisp_Object, ptrdiff_t, Lisp_Object *, char *);
static void maybe_resize_hash_table (struct Lisp_Hash_Table *);
static int sweep_weak_table (struct Lisp_Hash_Table *, int);
/* 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)
{
- if (n % 2 == 0)
- n += 1;
- if (n % 3 == 0)
- n += 2;
- if (n % 7 == 0)
- n += 4;
- return n;
+ verify (NEXT_ALMOST_PRIME_LIMIT == 11);
+ for (n |= 1; ; n += 2)
+ if (n % 3 != 0 && n % 5 != 0 && n % 7 != 0)
+ return n;
}
0. This function is used to extract a keyword/argument pair from
a DEFUN parameter list. */
-static size_t
-get_key_arg (Lisp_Object key, size_t nargs, Lisp_Object *args, char *used)
+static ptrdiff_t
+get_key_arg (Lisp_Object key, ptrdiff_t nargs, Lisp_Object *args, char *used)
{
- size_t i;
+ ptrdiff_t i;
for (i = 1; i < nargs; i++)
if (!used[i - 1] && EQ (args[i - 1], key))
/* 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;
}
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.
{
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. */
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. */
{
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))
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
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);
}
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);
/* 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,
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);
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);
/* 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
{
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)
{
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;
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;
#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);
}
/* 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. */
is nil.
usage: (make-hash-table &rest KEYWORD-ARGS) */)
- (size_t nargs, Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
Lisp_Object test, size, rehash_size, rehash_threshold, weak;
Lisp_Object user_test, user_hash;
char *used;
- size_t i;
+ ptrdiff_t i;
/* The vector `used' is used to keep track of arguments that
have been consumed. */
(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;
}
DEFUN ("puthash", Fputhash, Sputhash, 3, 3, 0,
doc: /* Associate KEY with VALUE in hash table TABLE.
If KEY is already present in table, replace its current value with
-VALUE. */)
+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);
{
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)))
\f
/************************************************************************
- 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))
{
object = code_convert_string (object, coding_system, Qnil, 1, 0, 1);
size = SCHARS (object);
- size_byte = SBYTES (object);
if (!NILP (start))
{
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);
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
{
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);
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,
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);
}
-
\f
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);
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;
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,
defsubr (&Sbase64_encode_string);
defsubr (&Sbase64_decode_string);
defsubr (&Smd5);
- defsubr (&Ssha1);
+ defsubr (&Ssecure_hash);
defsubr (&Slocale_info);
}