#define MAX_BUFPOS_GAP_SIZE_3 (65535/3)
#define MAX_BYTIND_GAP_SIZE_3 (3 * MAX_BUFPOS_GAP_SIZE_3)
+#ifndef UTF2000
short three_to_one_table[1 + MAX_BYTIND_GAP_SIZE_3];
+#endif
/* Various macros modelled along the lines of those in buffer.h.
Purposefully omitted from buffer.h because files other than this
bufmax = buf->text->mule_bufmax;
bytmin = buf->text->mule_bytmin;
bytmax = buf->text->mule_bytmax;
+#ifdef UTF2000
+ size = buf->text->mule_size;
+#else
size = (1 << buf->text->mule_shifter) + !!buf->text->mule_three_p;
+#endif
/* The basic idea here is that we shift the "known region" up or down
until it overlaps the specified position. We do this by moving
discovered isn't too large, because we use a fixed-length
table to divide by 3. */
+#ifdef UTF2000
+ buf->text->mule_size = size;
+#endif
if (size == 3)
{
int gap = bytmax - bytmin;
+#ifndef UTF2000
buf->text->mule_three_p = 1;
buf->text->mule_shifter = 1;
+#endif
if (gap > MAX_BYTIND_GAP_SIZE_3)
{
}
else
{
+#ifndef UTF2000
buf->text->mule_three_p = 0;
if (size == 4)
buf->text->mule_shifter = 2;
else
buf->text->mule_shifter = size - 1;
+#endif
}
buf->text->mule_bufmin = bufmin;
bufmax = buf->text->mule_bufmax;
bytmin = buf->text->mule_bytmin;
bytmax = buf->text->mule_bytmax;
+#ifdef UTF2000
+ size = buf->text->mule_size;
+#else
size = (1 << buf->text->mule_shifter) + !!buf->text->mule_three_p;
+#endif
/* The basic idea here is that we shift the "known region" up or down
until it overlaps the specified position. We do this by moving
discovered isn't too large, because we use a fixed-length
table to divide by 3. */
+#ifdef UTF2000
+ buf->text->mule_size = size;
+ #endif
if (size == 3)
{
int gap = bytmax - bytmin;
+#ifndef UTF2000
buf->text->mule_three_p = 1;
buf->text->mule_shifter = 1;
+#endif
if (gap > MAX_BYTIND_GAP_SIZE_3)
{
}
else
{
+#ifndef UTF2000
buf->text->mule_three_p = 0;
if (size == 4)
buf->text->mule_shifter = 2;
else
buf->text->mule_shifter = size - 1;
+#endif
}
buf->text->mule_bufmin = bufmin;
Bytecount bytelength,
Charcount charlength)
{
+#ifdef UTF2000
+ int size = buf->text->mule_size;
+#else
int size = (1 << buf->text->mule_shifter) + !!buf->text->mule_three_p;
+#endif
int i;
/* Adjust the cache of known positions. */
Bytecount old_gap_size;
/* If we have to get more space, get enough to last a while. We use
- a geometric progession that saves on realloc space. */
+ a geometric progression that saves on realloc space. */
increment += 2000 + ((BI_BUF_Z (buf) - BI_BUF_BEG (buf)) / 8);
if (increment > BUF_END_GAP_SIZE (buf))
of the specified region, that will also be handled correctly.
begin_multiple_change() returns a number (actually a specpdl depth)
- that you must pass to end_multiple_change() when you are done. */
+ that you must pass to end_multiple_change() when you are done.
+
+ FSF Emacs 20 implements a similar feature, accessible from Lisp
+ through a `combine-after-change-calls' special form, which is
+ essentially equivalent to this function. We should consider
+ whether we want to introduce a similar Lisp form. */
int
begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end)
/* We should first reset the variable and then change the buffer,
because Fset_buffer() can throw. */
inside_change_hook = 0;
- Fset_buffer (buffer);
+ if (XBUFFER (buffer) != current_buffer)
+ Fset_buffer (buffer);
return Qnil;
}
if (!inside_change_hook)
{
Lisp_Object buffer;
+ int speccount;
/* Are we in a multiple-change session? */
if (buf->text->changes->in_multiple_change &&
}
/* Now in any case run the before-change-functions if any. */
+ speccount = specpdl_depth ();
+ record_unwind_protect (change_function_restore, Fcurrent_buffer ());
+ inside_change_hook = 1;
MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
{
/* Obsolete, for compatibility */
|| !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer)))
{
- int speccount = specpdl_depth ();
- record_unwind_protect (change_function_restore, Fcurrent_buffer ());
set_buffer_internal (buf);
- inside_change_hook = 1;
va_run_hook_with_args (Qbefore_change_functions, 2,
make_int (start), make_int (end));
/* Obsolete, for compatibility */
va_run_hook_with_args (Qbefore_change_function, 2,
make_int (start), make_int (end));
- unbind_to (speccount, Qnil);
}
}
+ /* Make sure endpoints remain valid. before-change-functions
+ might have modified the buffer. */
+ if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf);
+ if (start > BUF_ZV (buf)) start = BUF_ZV (buf);
+ if (end < BUF_BEGV (buf)) end = BUF_BEGV (buf);
+ if (end > BUF_ZV (buf)) end = BUF_ZV (buf);
+
MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
{
XSETBUFFER (buffer, mbuf);
- report_extent_modification (buffer, start, end,
- &inside_change_hook, 0);
+ report_extent_modification (buffer, start, end, 0);
}
+ unbind_to (speccount, Qnil);
/* Only now do we indicate that the before-change-functions have
been called, in case some function throws out. */
if (!inside_change_hook)
{
Lisp_Object buffer;
+ int speccount;
if (buf->text->changes->in_multiple_change &&
buf->text->changes->mc_begin != 0)
return; /* after-change-functions signalled when all changes done */
}
+ speccount = specpdl_depth ();
+ record_unwind_protect (change_function_restore, Fcurrent_buffer ());
+ inside_change_hook = 1;
MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
{
XSETBUFFER (buffer, mbuf);
/* Obsolete, for compatibility */
|| !NILP (symbol_value_in_buffer (Qafter_change_function, buffer)))
{
- int speccount = specpdl_depth ();
- record_unwind_protect (change_function_restore, Fcurrent_buffer ());
set_buffer_internal (buf);
- inside_change_hook = 1;
/* The actual after-change functions take slightly
different arguments than what we were passed. */
va_run_hook_with_args (Qafter_change_functions, 3,
va_run_hook_with_args (Qafter_change_function, 3,
make_int (start), make_int (new_end),
make_int (orig_end - start));
- unbind_to (speccount, Qnil);
}
}
+ /* Make sure endpoints remain valid. after-change-functions
+ might have modified the buffer. */
+ if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf);
+ if (start > BUF_ZV (buf)) start = BUF_ZV (buf);
+ if (new_end < BUF_BEGV (buf)) new_end = BUF_BEGV (buf);
+ if (new_end > BUF_ZV (buf)) new_end = BUF_ZV (buf);
+ if (orig_end < BUF_BEGV (buf)) orig_end = BUF_BEGV (buf);
+ if (orig_end > BUF_ZV (buf)) orig_end = BUF_ZV (buf);
+
MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
{
XSETBUFFER (buffer, mbuf);
- report_extent_modification (buffer, start, new_end,
- &inside_change_hook, 1);
+ report_extent_modification (buffer, start, new_end, 1);
}
+ unbind_to (speccount, Qnil); /* sets inside_change_hook back to 0 */
}
}
/* Make a string from a buffer. This needs to take into account the gap,
and add any necessary extents from the buffer. */
-Lisp_Object
-make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length)
+static Lisp_Object
+make_string_from_buffer_1 (struct buffer *buf, Bufpos pos, Charcount length,
+ int no_extents)
{
/* This function can GC */
- Lisp_Object val;
- struct gcpro gcpro1;
- Bytind bi_ind;
- Bytecount bi_len;
-
- bi_ind = bufpos_to_bytind (buf, pos);
- bi_len = bufpos_to_bytind (buf, pos + length) - bi_ind;
+ Bytind bi_ind = bufpos_to_bytind (buf, pos);
+ Bytecount bi_len = bufpos_to_bytind (buf, pos + length) - bi_ind;
+ Lisp_Object val = make_uninit_string (bi_len);
- val = make_uninit_string (bi_len);
+ struct gcpro gcpro1;
GCPRO1 (val);
- add_string_extents (val, buf, bi_ind, bi_len);
+ if (!no_extents)
+ add_string_extents (val, buf, bi_ind, bi_len);
{
Bytecount len1 = BI_BUF_GPT (buf) - bi_ind;
return val;
}
+Lisp_Object
+make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length)
+{
+ return make_string_from_buffer_1 (buf, pos, length, 0);
+}
+
+Lisp_Object
+make_string_from_buffer_no_extents (struct buffer *buf, Bufpos pos,
+ Charcount length)
+{
+ return make_string_from_buffer_1 (buf, pos, length, 1);
+}
+
void
barf_if_buffer_read_only (struct buffer *buf, Bufpos from, Bufpos to)
{
}
void
-find_charsets_in_bufbyte_string (unsigned char *charsets, CONST Bufbyte *str,
+find_charsets_in_bufbyte_string (Charset_ID *charsets, CONST Bufbyte *str,
Bytecount len)
{
#ifndef MULE
charsets[0] = 1;
#else
CONST Bufbyte *strend = str + len;
- memset (charsets, 0, NUM_LEADING_BYTES);
+ memset (charsets, 0, NUM_LEADING_BYTES * sizeof(Charset_ID));
while (str < strend)
{
- charsets[CHAR_LEADING_BYTE (charptr_emchar (str)) - 128] = 1;
+#ifdef UTF2000
+ charsets[CHAR_CHARSET_ID (charptr_emchar (str))
+ - MIN_LEADING_BYTE] = 1;
+#else /* I'm not sure the definition for UTF2000 works with leading-byte
+ representation. */
+ charsets[CHAR_LEADING_BYTE (charptr_emchar (str))
+ - MIN_LEADING_BYTE] = 1;
+#endif
INC_CHARPTR (str);
}
#endif
}
void
-find_charsets_in_emchar_string (unsigned char *charsets, CONST Emchar *str,
+find_charsets_in_emchar_string (Charset_ID *charsets, CONST Emchar *str,
Charcount len)
{
#ifndef MULE
#else
int i;
- memset (charsets, 0, NUM_LEADING_BYTES);
+ memset (charsets, 0, NUM_LEADING_BYTES * sizeof(Charset_ID));
for (i = 0; i < len; i++)
{
- charsets[CHAR_LEADING_BYTE (str[i]) - 128] = 1;
+#ifdef UTF2000
+ charsets[CHAR_CHARSET_ID (str[i]) - MIN_LEADING_BYTE] = 1;
+#else /* I'm not sure the definition for UTF2000 works with leading-byte
+ representation. */
+ charsets[CHAR_LEADING_BYTE (str[i]) - MIN_LEADING_BYTE] = 1;
+#endif
}
#endif
}
{
#ifdef MULE
Emchar ch = charptr_emchar (str);
- cols += XCHARSET_COLUMNS (CHAR_CHARSET (ch));
+ cols += CHAR_COLUMNS (ch);
#else
cols++;
#endif
int i;
for (i = 0; i < len; i++)
- cols += XCHARSET_COLUMNS (CHAR_CHARSET (str[i]));
+ cols += CHAR_COLUMNS (str[i]);
return cols;
#else /* not MULE */
}
}
-int
+Charcount
convert_bufbyte_string_into_emchar_string (CONST Bufbyte *str, Bytecount len,
Emchar *arr)
{
/************************************************************************/
void
-vars_of_insdel (void)
+reinit_vars_of_insdel (void)
{
+#ifndef UTF2000
int i;
+#endif
inside_change_hook = 0;
in_first_change = 0;
+#ifndef UTF2000
for (i = 0; i <= MAX_BYTIND_GAP_SIZE_3; i++)
three_to_one_table[i] = i / 3;
+#endif
+}
+
+void
+vars_of_insdel (void)
+{
+ reinit_vars_of_insdel ();
}
void
b->text->mule_bufmin = b->text->mule_bufmax = 1;
b->text->mule_bytmin = b->text->mule_bytmax = 1;
+#ifdef UTF2000
+ b->text->mule_size = 0;
+#else
b->text->mule_shifter = 0;
b->text->mule_three_p = 0;
+#endif
for (i = 0; i < 16; i++)
{