+ SET_INTERVAL_OBJECT (interval_copy, string);
+ STRING_SET_INTERVALS (string, interval_copy);
+}
+\f
+/* Return 1 if strings S1 and S2 have identical properties; 0 otherwise.
+ Assume they have identical characters. */
+
+int
+compare_string_intervals (s1, s2)
+ Lisp_Object s1, s2;
+{
+ INTERVAL i1, i2;
+ int pos = 0;
+ int end = SCHARS (s1);
+
+ i1 = find_interval (STRING_INTERVALS (s1), 0);
+ i2 = find_interval (STRING_INTERVALS (s2), 0);
+
+ while (pos < end)
+ {
+ /* Determine how far we can go before we reach the end of I1 or I2. */
+ int len1 = (i1 != 0 ? INTERVAL_LAST_POS (i1) : end) - pos;
+ int len2 = (i2 != 0 ? INTERVAL_LAST_POS (i2) : end) - pos;
+ int distance = min (len1, len2);
+
+ /* If we ever find a mismatch between the strings,
+ they differ. */
+ if (! intervals_equal (i1, i2))
+ return 0;
+
+ /* Advance POS till the end of the shorter interval,
+ and advance one or both interval pointers for the new position. */
+ pos += distance;
+ if (len1 == distance)
+ i1 = next_interval (i1);
+ if (len2 == distance)
+ i2 = next_interval (i2);
+ }
+ return 1;
+}
+\f
+/* Recursively adjust interval I in the current buffer
+ for setting enable_multibyte_characters to MULTI_FLAG.
+ The range of interval I is START ... END in characters,
+ START_BYTE ... END_BYTE in bytes. */
+
+static void
+set_intervals_multibyte_1 (i, multi_flag, start, start_byte, end, end_byte)
+ INTERVAL i;
+ int multi_flag;
+ int start, start_byte, end, end_byte;
+{
+ /* Fix the length of this interval. */
+ if (multi_flag)
+ i->total_length = end - start;
+ else
+ i->total_length = end_byte - start_byte;
+ CHECK_TOTAL_LENGTH (i);
+
+ if (TOTAL_LENGTH (i) == 0)
+ {
+ delete_interval (i);
+ return;
+ }
+
+ /* Recursively fix the length of the subintervals. */
+ if (i->left)
+ {
+ int left_end, left_end_byte;
+
+ if (multi_flag)
+ {
+ int temp;
+ left_end_byte = start_byte + LEFT_TOTAL_LENGTH (i);
+ left_end = BYTE_TO_CHAR (left_end_byte);
+
+ temp = CHAR_TO_BYTE (left_end);
+
+ /* If LEFT_END_BYTE is in the middle of a character,
+ adjust it and LEFT_END to a char boundary. */
+ if (left_end_byte > temp)
+ {
+ left_end_byte = temp;
+ }
+ if (left_end_byte < temp)
+ {
+ left_end--;
+ left_end_byte = CHAR_TO_BYTE (left_end);
+ }
+ }
+ else
+ {
+ left_end = start + LEFT_TOTAL_LENGTH (i);
+ left_end_byte = CHAR_TO_BYTE (left_end);
+ }
+
+ set_intervals_multibyte_1 (i->left, multi_flag, start, start_byte,
+ left_end, left_end_byte);
+ }
+ if (i->right)
+ {
+ int right_start_byte, right_start;
+
+ if (multi_flag)
+ {
+ int temp;
+
+ right_start_byte = end_byte - RIGHT_TOTAL_LENGTH (i);
+ right_start = BYTE_TO_CHAR (right_start_byte);
+
+ /* If RIGHT_START_BYTE is in the middle of a character,
+ adjust it and RIGHT_START to a char boundary. */
+ temp = CHAR_TO_BYTE (right_start);
+
+ if (right_start_byte < temp)
+ {
+ right_start_byte = temp;
+ }
+ if (right_start_byte > temp)
+ {
+ right_start++;
+ right_start_byte = CHAR_TO_BYTE (right_start);
+ }
+ }
+ else
+ {
+ right_start = end - RIGHT_TOTAL_LENGTH (i);
+ right_start_byte = CHAR_TO_BYTE (right_start);
+ }
+
+ set_intervals_multibyte_1 (i->right, multi_flag,
+ right_start, right_start_byte,
+ end, end_byte);
+ }
+
+ /* Rounding to char boundaries can theoretically ake this interval
+ spurious. If so, delete one child, and copy its property list
+ to this interval. */
+ if (LEFT_TOTAL_LENGTH (i) + RIGHT_TOTAL_LENGTH (i) >= TOTAL_LENGTH (i))
+ {
+ if ((i)->left)
+ {
+ (i)->plist = (i)->left->plist;
+ (i)->left->total_length = 0;
+ delete_interval ((i)->left);
+ }
+ else
+ {
+ (i)->plist = (i)->right->plist;
+ (i)->right->total_length = 0;
+ delete_interval ((i)->right);
+ }
+ }
+}
+
+/* Update the intervals of the current buffer
+ to fit the contents as multibyte (if MULTI_FLAG is 1)
+ or to fit them as non-multibyte (if MULTI_FLAG is 0). */
+
+void
+set_intervals_multibyte (multi_flag)
+ int multi_flag;
+{
+ if (BUF_INTERVALS (current_buffer))
+ set_intervals_multibyte_1 (BUF_INTERVALS (current_buffer), multi_flag,
+ BEG, BEG_BYTE, Z, Z_BYTE);