]> code.delx.au - gnu-emacs/blobdiff - src/editfns.c
(message2_nolog): Fix arg types.
[gnu-emacs] / src / editfns.c
index fa4f486c69972cab5ab5482044028a888110edb0..b3b797e636fb9f4903e03510e99071273406a403 100644 (file)
@@ -40,11 +40,16 @@ Boston, MA 02111-1307, USA.  */
 #define min(a, b) ((a) < (b) ? (a) : (b))
 #define max(a, b) ((a) > (b) ? (a) : (b))
 
+#ifndef NULL
+#define NULL 0
+#endif
+
 extern char **environ;
 extern Lisp_Object make_time ();
 extern void insert_from_buffer ();
 static int tm_diff ();
 static void update_buffer_properties ();
+size_t emacs_strftime ();
 void set_time_zone_rule ();
 
 Lisp_Object Vbuffer_access_fontify_functions;
@@ -122,7 +127,7 @@ DEFUN ("char-to-string", Fchar_to_string, Schar_to_string, 1, 1, 0,
      Lisp_Object character;
 {
   int len;
-  char workbuf[4], *str;
+  unsigned char workbuf[4], *str;
 
   CHECK_NUMBER (character, 0);
 
@@ -154,8 +159,8 @@ INDEX not pointing at character boundary is an error.")
   (str, idx)
      Lisp_Object str, idx;
 {
-  register int idxval, len;
-  register unsigned char *p;
+  register int idxval, len, i;
+  register unsigned char *p, *q;
   register Lisp_Object val;
 
   CHECK_STRING (str, 0);
@@ -163,9 +168,25 @@ INDEX not pointing at character boundary is an error.")
   idxval = XINT (idx);
   if (idxval < 0 || idxval >= (len = XVECTOR (str)->size))
     args_out_of_range (str, idx);
+
   p = XSTRING (str)->data + idxval;
-  if (!CHAR_HEAD_P (p))
-    error ("Not character boundary");
+  if (!NILP (current_buffer->enable_multibyte_characters)
+      && !CHAR_HEAD_P (p)
+      && idxval > 0)
+    {
+      /* We must check if P points to a tailing byte of a multibyte
+         form.  If so, we signal error.  */
+      i = idxval - 1;
+      q = p - 1;
+      while (i > 0 && *q >= 0xA0) i--, q--;
+
+      if (*q == LEADING_CODE_COMPOSITION)
+       i = multibyte_form_length (XSTRING (str)->data + i, len - i);
+      else
+       i = BYTES_BY_CHAR_HEAD (*q);
+      if (q + i > p)
+       error ("Not character boundary");
+    }
 
   len = XSTRING (str)->size - idxval;
   XSETFASTINT (val, STRING_CHAR (p, len));
@@ -610,18 +631,17 @@ is returned as a character.")
       n = XINT (pos);
     }
 
+  if (n <= BEGV || n > ZV)
+    return Qnil;
+
   if (!NILP (current_buffer->enable_multibyte_characters))
     {
       DEC_POS (n);
-      if (n < BEGV || n >= ZV)
-       return Qnil;
       XSETFASTINT (val, FETCH_CHAR (n));
     }
   else
     {
       n--;
-      if (n < BEGV || n >= ZV)
-       return Qnil;
       XSETFASTINT (val, FETCH_BYTE (n));
     }
    return val;
@@ -816,17 +836,18 @@ by text that describes the specified date and time in TIME:\n\
 \n\
 %Y is the year, %y within the century, %C the century.\n\
 %G is the year corresponding to the ISO week, %g within the century.\n\
-%m is the numeric month, %b and %h the abbreviated name, %B the full name.\n\
+%m is the numeric month.\n\
+%b and %h are the locale's abbreviated month name, %B the full name.\n\
 %d is the day of the month, zero-padded, %e is blank-padded.\n\
 %u is the numeric day of week from 1 (Monday) to 7, %w from 0 (Sunday) to 6.\n\
-%a is the abbreviated name of the day of week, %A the full name.\n\
+%a is the locale's abbreviated name of the day of week, %A the full name.\n\
 %U is the week number starting on Sunday, %W starting on Monday,\n\
  %V according to ISO 8601.\n\
 %j is the day of the year.\n\
 \n\
 %H is the hour on a 24-hour clock, %I is on a 12-hour clock, %k is like %H\n\
  only blank-padded, %l is like %I blank-padded.\n\
-%p is AM or PM.\n\
+%p is the locale's equivalent of either AM or PM.\n\
 %M is the minute.\n\
 %S is the second.\n\
 %Z is the time zone name, %z is the numeric form.\n\
@@ -839,7 +860,7 @@ by text that describes the specified date and time in TIME:\n\
 %R is like \"%H:%M\", %T is like \"%H:%M:%S\", %r is like \"%I:%M:%S %p\".\n\
 %X is the locale's \"preferred\" time format.\n\
 \n\
-Finally, %n is like \n, %t is like \t, %% is a literal %.\n\
+Finally, %n is a newline, %t is a tab, %% is a literal %.\n\
 \n\
 Certain flags and modifiers are available with some format controls.\n\
 The flags are `_' and `-'.  For certain characters X, %_X is like %X,\n\
@@ -851,6 +872,7 @@ The modifiers are `E' and `O'.  For certain characters X,\n\
 %OX is like %X, but uses the locale's number symbols.\n\
 \n\
 For example, to produce full ISO 8601 format, use \"%Y-%m-%dT%T%z\".")
+  (format_string, time, universal)
 */
 
 DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0,
@@ -874,16 +896,15 @@ DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0,
       char *buf = (char *) alloca (size + 1);
       int result;
 
+      buf[0] = '\1';
       result = emacs_strftime (buf, size, XSTRING (format_string)->data,
                               (NILP (universal) ? localtime (&value)
                                : gmtime (&value)));
-      if (result > 0 && result < size)
+      if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0'))
        return build_string (buf);
-      if (result < 0)
-       error ("Invalid time format specification");
 
       /* If buffer was too small, make it bigger and try again.  */
-      result = emacs_strftime (buf, 0, XSTRING (format_string)->data,
+      result = emacs_strftime (NULL, 0x7fffffff, XSTRING (format_string)->data,
                               (NILP (universal) ? localtime (&value)
                                : gmtime (&value)));
       size = result + 1;
@@ -1265,9 +1286,11 @@ set_time_zone_rule (tzstring)
    type of object is Lisp_String).  INHERIT is passed to
    INSERT_FROM_STRING_FUNC as the last argument.  */
 
+void
 general_insert_function (insert_func, insert_from_string_func,
                         inherit, nargs, args)
-     int (*insert_func)(), (*insert_from_string_func)();
+     void (*insert_func) P_ ((unsigned char *, int));
+     void (*insert_from_string_func) P_ ((Lisp_Object, int, int, int));
      int inherit, nargs;
      register Lisp_Object *args;
 {
@@ -1280,7 +1303,7 @@ general_insert_function (insert_func, insert_from_string_func,
     retry:
       if (INTEGERP (val))
        {
-         char workbuf[4], *str;
+         unsigned char workbuf[4], *str;
          int len;
 
          if (!NILP (current_buffer->enable_multibyte_characters))
@@ -1896,9 +1919,10 @@ DEFUN ("widen", Fwiden, Swiden, 0, 0, "",
 This allows the buffer's full text to be seen and edited.")
   ()
 {
+  if (BEG != BEGV || Z != ZV)
+    current_buffer->clip_changed = 1;
   BEGV = BEG;
   SET_BUF_ZV (current_buffer, Z);
-  current_buffer->clip_changed = 1;
   /* Changing the buffer bounds invalidates any recorded current column.  */
   invalidate_current_column ();
   return Qnil;
@@ -1928,13 +1952,15 @@ or markers) bounding the text that should remain visible.")
   if (!(BEG <= XINT (start) && XINT (start) <= XINT (end) && XINT (end) <= Z))
     args_out_of_range (start, end);
 
+  if (BEGV != XFASTINT (start) || ZV != XFASTINT (end))
+    current_buffer->clip_changed = 1;
+
   BEGV = XFASTINT (start);
   SET_BUF_ZV (current_buffer, XFASTINT (end));
   if (PT < XFASTINT (start))
     SET_PT (XFASTINT (start));
   if (PT > XFASTINT (end))
     SET_PT (XFASTINT (end));
-  current_buffer->clip_changed = 1;
   /* Changing the buffer bounds invalidates any recorded current column.  */
   invalidate_current_column ();
   return Qnil;
@@ -1960,6 +1986,7 @@ save_restriction_restore (data)
   register struct buffer *buf;
   register int newhead, newtail;
   register Lisp_Object tem;
+  int obegv, ozv;
 
   buf = XBUFFER (XCONS (data)->car);
 
@@ -1974,9 +2001,15 @@ save_restriction_restore (data)
       newhead = 0;
       newtail = 0;
     }
+
+  obegv = BUF_BEGV (buf);
+  ozv = BUF_ZV (buf);
+
   BUF_BEGV (buf) = BUF_BEG (buf) + newhead;
   SET_BUF_ZV (buf, BUF_Z (buf) - newtail);
-  current_buffer->clip_changed = 1;
+
+  if (obegv != BUF_BEGV (buf) || ozv != BUF_ZV (buf))
+    current_buffer->clip_changed = 1;
 
   /* If point is outside the new visible range, move it inside. */
   SET_BUF_PT (buf,