]> code.delx.au - gnu-emacs/blobdiff - src/fns.c
*** empty log message ***
[gnu-emacs] / src / fns.c
index 3076a000992ca45f2d97bf247d5740cb71a2667d..06d04781789f37c97e29a6a60a6df545ebd44360 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -1,5 +1,5 @@
 /* Random utility Lisp functions.
-   Copyright (C) 1985, 86, 87, 93, 94, 95, 97, 98, 99, 2000, 2001, 02, 2003
+   Copyright (C) 1985, 86, 87, 93, 94, 95, 97, 98, 99, 2000, 2001, 02, 03, 2004
    Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -513,7 +513,8 @@ with the original. */)
     {
       Lisp_Object val;
       int size_in_chars
-       = (XBOOL_VECTOR (arg)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
+       = ((XBOOL_VECTOR (arg)->size + BOOL_VECTOR_BITS_PER_CHAR - 1)
+          / BOOL_VECTOR_BITS_PER_CHAR);
 
       val = Fmake_bool_vector (Flength (arg), Qnil);
       bcopy (XBOOL_VECTOR (arg)->data, XBOOL_VECTOR (val)->data,
@@ -526,27 +527,6 @@ with the original. */)
   return concat (1, &arg, CONSP (arg) ? Lisp_Cons : XTYPE (arg), 0);
 }
 
-/* In string STR of length LEN, see if bytes before STR[I] combine
-   with bytes after STR[I] to form a single character.  If so, return
-   the number of bytes after STR[I] which combine in this way.
-   Otherwize, return 0.  */
-
-static int
-count_combining (str, len, i)
-     unsigned char *str;
-     int len, i;
-{
-  int j = i - 1, bytes;
-
-  if (i == 0 || i == len || CHAR_HEAD_P (str[i]))
-    return 0;
-  while (j >= 0 && !CHAR_HEAD_P (str[j])) j--;
-  if (j < 0 || ! BASE_LEADING_CODE_P (str[j]))
-    return 0;
-  PARSE_MULTIBYTE_SEQ (str + j, len - j, bytes);
-  return (bytes <= i - j ? 0 : bytes - (i - j));
-}
-
 /* This structure holds information of an argument of `concat' that is
    a string and has text properties to be copied.  */
 struct textprop_rec
@@ -709,25 +689,18 @@ concat (nargs, args, target_type, last_special)
          && STRING_MULTIBYTE (this) == some_multibyte)
        {
          int thislen_byte = SBYTES (this);
-         int combined;
 
          bcopy (SDATA (this), SDATA (val) + toindex_byte,
                 SBYTES (this));
-         combined =  (some_multibyte && toindex_byte > 0
-                      ? count_combining (SDATA (val),
-                                         toindex_byte + thislen_byte,
-                                         toindex_byte)
-                      : 0);
          if (! NULL_INTERVAL_P (STRING_INTERVALS (this)))
            {
              textprops[num_textprops].argnum = argnum;
-             /* We ignore text properties on characters being combined.  */
-             textprops[num_textprops].from = combined;
+             textprops[num_textprops].from = 0;
              textprops[num_textprops++].to = toindex;
            }
          toindex_byte += thislen_byte;
-         toindex += thisleni - combined;
-         STRING_SET_CHARS (val, SCHARS (val) - combined);
+         toindex += thisleni;
+         STRING_SET_CHARS (val, SCHARS (val));
        }
       /* Copy a single-byte string to a multibyte string.  */
       else if (STRINGP (this) && STRINGP (val))
@@ -783,8 +756,8 @@ concat (nargs, args, target_type, last_special)
            else if (BOOL_VECTOR_P (this))
              {
                int byte;
-               byte = XBOOL_VECTOR (this)->data[thisindex / BITS_PER_CHAR];
-               if (byte & (1 << (thisindex % BITS_PER_CHAR)))
+               byte = XBOOL_VECTOR (this)->data[thisindex / BOOL_VECTOR_BITS_PER_CHAR];
+               if (byte & (1 << (thisindex % BOOL_VECTOR_BITS_PER_CHAR)))
                  elt = Qt;
                else
                  elt = Qnil;
@@ -813,13 +786,7 @@ concat (nargs, args, target_type, last_special)
                                        SDATA (val) + toindex_byte);
                    else
                      SSET (val, toindex_byte++, XINT (elt));
-                   if (some_multibyte
-                       && toindex_byte > 0
-                       && count_combining (SDATA (val),
-                                           toindex_byte, toindex_byte - 1))
-                     STRING_SET_CHARS (val, SCHARS (val) - 1);
-                   else
-                     toindex++;
+                   toindex++;
                  }
                else
                  /* If we have any multibyte characters,
@@ -1027,6 +994,8 @@ string_make_multibyte (string)
 {
   unsigned char *buf;
   int nbytes;
+  Lisp_Object ret;
+  USE_SAFE_ALLOCA;
 
   if (STRING_MULTIBYTE (string))
     return string;
@@ -1038,11 +1007,14 @@ string_make_multibyte (string)
   if (nbytes == SBYTES (string))
     return string;
 
-  buf = (unsigned char *) alloca (nbytes);
+  SAFE_ALLOCA (buf, unsigned char *, nbytes);
   copy_text (SDATA (string), buf, SBYTES (string),
             0, 1);
 
-  return make_multibyte_string (buf, SCHARS (string), nbytes);
+  ret = make_multibyte_string (buf, SCHARS (string), nbytes);
+  SAFE_FREE (nbytes);
+
+  return ret;
 }
 
 
@@ -1057,6 +1029,8 @@ string_to_multibyte (string)
 {
   unsigned char *buf;
   int nbytes;
+  Lisp_Object ret;
+  USE_SAFE_ALLOCA;
 
   if (STRING_MULTIBYTE (string))
     return string;
@@ -1067,11 +1041,14 @@ string_to_multibyte (string)
   if (nbytes == SBYTES (string))
     return make_multibyte_string (SDATA (string), nbytes, nbytes);
 
-  buf = (unsigned char *) alloca (nbytes);
+  SAFE_ALLOCA (buf, unsigned char *, nbytes);
   bcopy (SDATA (string), buf, SBYTES (string));
   str_to_multibyte (buf, nbytes, SBYTES (string));
 
-  return make_multibyte_string (buf, SCHARS (string), nbytes);
+  ret = make_multibyte_string (buf, SCHARS (string), nbytes);
+  SAFE_FREE (nbytes);
+
+  return ret;
 }
 
 
@@ -1081,17 +1058,24 @@ Lisp_Object
 string_make_unibyte (string)
      Lisp_Object string;
 {
+  int nchars;
   unsigned char *buf;
+  Lisp_Object ret;
+  USE_SAFE_ALLOCA;
 
   if (! STRING_MULTIBYTE (string))
     return string;
 
-  buf = (unsigned char *) alloca (SCHARS (string));
+  nchars = SCHARS (string);
 
+  SAFE_ALLOCA (buf, unsigned char *, nchars);
   copy_text (SDATA (string), buf, SBYTES (string),
             1, 0);
 
-  return make_unibyte_string (buf, SCHARS (string));
+  ret = make_unibyte_string (buf, nchars);
+  SAFE_FREE (nchars);
+
+  return ret;
 }
 
 DEFUN ("string-make-multibyte", Fstring_make_multibyte, Sstring_make_multibyte,
@@ -1560,7 +1544,7 @@ assq_no_quit (key, list)
 DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0,
        doc: /* Return non-nil if KEY is `equal' to the car of an element of LIST.
 The value is actually the first element of LIST whose car equals KEY.  */)
-       (key, list)
+     (key, list)
      Lisp_Object key, list;
 {
   Lisp_Object result, car;
@@ -2138,7 +2122,7 @@ The PLIST is modified by side effects.  */)
 DEFUN ("eql", Feql, Seql, 2, 2, 0,
        doc: /* Return t if the two args are the same Lisp object.
 Floating-point numbers of equal value are `eql', but they may not be `eq'.  */)
-  (obj1, obj2)
+     (obj1, obj2)
      Lisp_Object obj1, obj2;
 {
   if (FLOATP (obj1))
@@ -2245,7 +2229,8 @@ internal_equal (o1, o2, depth, props)
        if (BOOL_VECTOR_P (o1))
          {
            int size_in_chars
-             = (XBOOL_VECTOR (o1)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
+             = ((XBOOL_VECTOR (o1)->size + BOOL_VECTOR_BITS_PER_CHAR - 1)
+                / BOOL_VECTOR_BITS_PER_CHAR);
 
            if (XBOOL_VECTOR (o1)->size != XBOOL_VECTOR (o2)->size)
              return 0;
@@ -2356,7 +2341,8 @@ ARRAY is a vector, string, char-table, or bool-vector.  */)
     {
       register unsigned char *p = XBOOL_VECTOR (array)->data;
       int size_in_chars
-       = (XBOOL_VECTOR (array)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
+       = ((XBOOL_VECTOR (array)->size + BOOL_VECTOR_BITS_PER_CHAR - 1)
+          / BOOL_VECTOR_BITS_PER_CHAR);
 
       charval = (! NILP (item) ? -1 : 0);
       for (index = 0; index < size_in_chars - 1; index++)
@@ -2364,8 +2350,8 @@ ARRAY is a vector, string, char-table, or bool-vector.  */)
       if (index < size_in_chars)
        {
          /* Mask out bits beyond the vector size.  */
-         if (XBOOL_VECTOR (array)->size % BITS_PER_CHAR)
-           charval &= (1 << (XBOOL_VECTOR (array)->size % BITS_PER_CHAR)) - 1;
+         if (XBOOL_VECTOR (array)->size % BOOL_VECTOR_BITS_PER_CHAR)
+           charval &= (1 << (XBOOL_VECTOR (array)->size % BOOL_VECTOR_BITS_PER_CHAR)) - 1;
          p[index] = charval;
        }
     }
@@ -2384,7 +2370,9 @@ This makes STRING unibyte and may change its length.  */)
      (string)
      Lisp_Object string;
 {
-  int len = SBYTES (string);
+  int len;
+  CHECK_STRING (string);
+  len = SBYTES (string);
   bzero (SDATA (string), len);
   STRING_SET_CHARS (string, len);
   STRING_SET_UNIBYTE (string);
@@ -2958,8 +2946,8 @@ mapcar1 (leni, vals, fn, seq)
       for (i = 0; i < leni; i++)
        {
          int byte;
-         byte = XBOOL_VECTOR (seq)->data[i / BITS_PER_CHAR];
-         if (byte & (1 << (i % BITS_PER_CHAR)))
+         byte = XBOOL_VECTOR (seq)->data[i / BOOL_VECTOR_BITS_PER_CHAR];
+         if (byte & (1 << (i % BOOL_VECTOR_BITS_PER_CHAR)))
            dummy = Qt;
          else
            dummy = Qnil;
@@ -3014,13 +3002,15 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string.  */)
   register Lisp_Object *args;
   register int i;
   struct gcpro gcpro1;
+  Lisp_Object ret;
+  USE_SAFE_ALLOCA;
 
   len = Flength (sequence);
   leni = XINT (len);
   nargs = leni + leni - 1;
   if (nargs < 0) return build_string ("");
 
-  args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
+  SAFE_ALLOCA_LISP (args, nargs);
 
   GCPRO1 (separator);
   mapcar1 (leni, args, function, sequence);
@@ -3032,7 +3022,10 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string.  */)
   for (i = 1; i < nargs; i += 2)
     args[i] = separator;
 
-  return Fconcat (nargs, args);
+  ret = Fconcat (nargs, args);
+  SAFE_FREE_LISP (nargs);
+
+  return ret;
 }
 
 DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
@@ -3045,14 +3038,20 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string.  */)
   register Lisp_Object len;
   register int leni;
   register Lisp_Object *args;
+  Lisp_Object ret;
+  USE_SAFE_ALLOCA;
 
   len = Flength (sequence);
   leni = XFASTINT (len);
-  args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object));
+
+  SAFE_ALLOCA_LISP (args, leni);
 
   mapcar1 (leni, args, function, sequence);
 
-  return Flist (leni, args);
+  ret = Flist (leni, args);
+  SAFE_FREE_LISP (leni);
+
+  return ret;
 }
 
 DEFUN ("mapc", Fmapc, Smapc, 2, 2, 0,
@@ -3667,10 +3666,6 @@ The data read from the system are decoded using `locale-coding-system'.  */)
     }                                  \
   while (IS_BASE64_IGNORABLE (c))
 
-/* Don't use alloca for regions larger than this, lest we overflow
-   their stack.  */
-#define MAX_ALLOCA 16*1024
-
 /* Table of characters coding the 64 values.  */
 static char base64_value_to_char[64] =
 {
@@ -3736,6 +3731,7 @@ into shorter lines.  */)
   int allength, length;
   int ibeg, iend, encoded_length;
   int old_pos = PT;
+  USE_SAFE_ALLOCA;
 
   validate_region (&beg, &end);
 
@@ -3750,10 +3746,7 @@ into shorter lines.  */)
   allength = length + length/3 + 1;
   allength += allength / MIME_LINE_LENGTH + 1 + 6;
 
-  if (allength <= MAX_ALLOCA)
-    encoded = (char *) alloca (allength);
-  else
-    encoded = (char *) xmalloc (allength);
+  SAFE_ALLOCA (encoded, char *, allength);
   encoded_length = base64_encode_1 (BYTE_POS_ADDR (ibeg), encoded, length,
                                    NILP (no_line_break),
                                    !NILP (current_buffer->enable_multibyte_characters));
@@ -3763,8 +3756,7 @@ into shorter lines.  */)
   if (encoded_length < 0)
     {
       /* The encoding wasn't possible. */
-      if (length > MAX_ALLOCA)
-       xfree (encoded);
+      SAFE_FREE (allength);
       error ("Multibyte character in data for base64 encoding");
     }
 
@@ -3772,8 +3764,7 @@ into shorter lines.  */)
      and delete the old.  (Insert first in order to preserve markers.)  */
   SET_PT_BOTH (XFASTINT (beg), ibeg);
   insert (encoded, encoded_length);
-  if (allength > MAX_ALLOCA)
-    xfree (encoded);
+  SAFE_FREE (allength);
   del_range_byte (ibeg + encoded_length, iend + encoded_length, 1);
 
   /* If point was outside of the region, restore it exactly; else just
@@ -3799,6 +3790,7 @@ into shorter lines.  */)
   int allength, length, encoded_length;
   char *encoded;
   Lisp_Object encoded_string;
+  USE_SAFE_ALLOCA;
 
   CHECK_STRING (string);
 
@@ -3810,10 +3802,7 @@ into shorter lines.  */)
   allength += allength / MIME_LINE_LENGTH + 1 + 6;
 
   /* We need to allocate enough room for decoding the text. */
-  if (allength <= MAX_ALLOCA)
-    encoded = (char *) alloca (allength);
-  else
-    encoded = (char *) xmalloc (allength);
+  SAFE_ALLOCA (encoded, char *, allength);
 
   encoded_length = base64_encode_1 (SDATA (string),
                                    encoded, length, NILP (no_line_break),
@@ -3824,14 +3813,12 @@ into shorter lines.  */)
   if (encoded_length < 0)
     {
       /* The encoding wasn't possible. */
-      if (length > MAX_ALLOCA)
-       xfree (encoded);
+      SAFE_FREE (allength);
       error ("Multibyte character in data for base64 encoding");
     }
 
   encoded_string = make_unibyte_string (encoded, encoded_length);
-  if (allength > MAX_ALLOCA)
-    xfree (encoded);
+  SAFE_FREE (allength);
 
   return encoded_string;
 }
@@ -3944,6 +3931,7 @@ If the region can't be decoded, signal an error and don't modify the buffer.  */
   int decoded_length;
   int inserted_chars;
   int multibyte = !NILP (current_buffer->enable_multibyte_characters);
+  USE_SAFE_ALLOCA;
 
   validate_region (&beg, &end);
 
@@ -3956,10 +3944,7 @@ If the region can't be decoded, signal an error and don't modify the buffer.  */
      working on a multibyte buffer, each decoded code may occupy at
      most two bytes.  */
   allength = multibyte ? length * 2 : length;
-  if (allength <= MAX_ALLOCA)
-    decoded = (char *) alloca (allength);
-  else
-    decoded = (char *) xmalloc (allength);
+  SAFE_ALLOCA (decoded, char *, allength);
 
   move_gap_both (XFASTINT (beg), ibeg);
   decoded_length = base64_decode_1 (BYTE_POS_ADDR (ibeg), decoded, length,
@@ -3970,8 +3955,7 @@ If the region can't be decoded, signal an error and don't modify the buffer.  */
   if (decoded_length < 0)
     {
       /* The decoding wasn't possible. */
-      if (allength > MAX_ALLOCA)
-       xfree (decoded);
+      SAFE_FREE (allength);
       error ("Invalid base64 data");
     }
 
@@ -3979,8 +3963,8 @@ If the region can't be decoded, signal an error and don't modify the buffer.  */
      and delete the old.  (Insert first in order to preserve markers.)  */
   TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg);
   insert_1_both (decoded, inserted_chars, decoded_length, 0, 1, 0);
-  if (allength > MAX_ALLOCA)
-    xfree (decoded);
+  SAFE_FREE (allength);
+
   /* Delete the original text.  */
   del_range_both (PT, PT_BYTE, XFASTINT (end) + inserted_chars,
                  iend + decoded_length, 1);
@@ -4005,15 +3989,13 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
   char *decoded;
   int length, decoded_length;
   Lisp_Object decoded_string;
+  USE_SAFE_ALLOCA;
 
   CHECK_STRING (string);
 
   length = SBYTES (string);
   /* We need to allocate enough room for decoding the text. */
-  if (length <= MAX_ALLOCA)
-    decoded = (char *) alloca (length);
-  else
-    decoded = (char *) xmalloc (length);
+  SAFE_ALLOCA (decoded, char *, length);
 
   /* The decoded result should be unibyte. */
   decoded_length = base64_decode_1 (SDATA (string), decoded, length,
@@ -4025,8 +4007,7 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
   else
     decoded_string = Qnil;
 
-  if (length > MAX_ALLOCA)
-    xfree (decoded);
+  SAFE_FREE (length);
   if (!STRINGP (decoded_string))
     error ("Invalid base64 data");