aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2020-04-17 07:57:25 -0700
committerPaul Eggert2020-04-17 09:17:35 -0700
commit27d101832ada36e431ae6cdecb5c82a180566377 (patch)
tree13e20d71f22cf4736bbfa02be54735b1484610bb /src
parent3e46a2315f1a999f5811f57a60a2a55f95d8fbb0 (diff)
downloademacs-27d101832ada36e431ae6cdecb5c82a180566377.tar.gz
emacs-27d101832ada36e431ae6cdecb5c82a180566377.zip
Prefer more inline functions in character.h
* src/buffer.h (fetch_char_advance, fetch_char_advance_no_check) (buf_next_char_len, next_char_len, buf_prev_char_len) (prev_char_len, inc_both, dec_both): New inline functions, replacing the old character.h macros FETCH_CHAR_ADVANCE, FETCH_CHAR_ADVANCE_NO_CHECK, BUF_INC_POS, INC_POS, BUF_DEC_POS, DEC_POS, INC_BOTH, DEC_BOTH respectively. All callers changed. These new functions all assume buffer primitives and so need to be here rather than in character.h. * src/casefiddle.c (make_char_unibyte): New static function, replacing the old MAKE_CHAR_UNIBYTE macro. All callers changed. (do_casify_unibyte_string): Use SINGLE_BYTE_CHAR_P instead of open-coding it. * src/ccl.c (GET_TRANSLATION_TABLE): New static function, replacing the old macro of the same name. * src/character.c (string_char): Omit 2nd arg. 3rd arg can no longer be NULL. All callers changed. * src/character.h (SINGLE_BYTE_CHAR_P): Move up. (MAKE_CHAR_UNIBYTE, MAKE_CHAR_MULTIBYTE, PREV_CHAR_BOUNDARY) (STRING_CHAR_AND_LENGTH, STRING_CHAR_ADVANCE) (FETCH_STRING_CHAR_ADVANCE) (FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE) (FETCH_STRING_CHAR_ADVANCE_NO_CHECK, FETCH_CHAR_ADVANCE) (FETCH_CHAR_ADVANCE_NO_CHECK, INC_POS, DEC_POS, INC_BOTH) (DEC_BOTH, BUF_INC_POS, BUF_DEC_POS): Remove. (make_char_multibyte): New static function, replacing the old macro MAKE_CHAR_MULTIBYTE. All callers changed. (CHAR_STRING_ADVANCE): Remove; all callers changed to use CHAR_STRING. (NEXT_CHAR_BOUNDARY): Remove; it was unused. (raw_prev_char_len): New inline function, replacing the old PREV_CHAR_BOUNDARY macro. All callers changed. (string_char_and_length): New inline function, replacing the old STRING_CHAR_AND_LENGTH macro. All callers changed. (STRING_CHAR): Rewrite in terms of string_char_and_length. (string_char_advance): New inline function, replacing the old STRING_CHAR_ADVANCE macro. All callers changed. (fetch_string_char_advance): New inline function, replacing the old FETCH_STRING_CHAR_ADVANCE macro. All callers changed. (fetch_string_char_as_multibyte_advance): New inline function, replacing the old FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE macro. All callers changed. (fetch_string_char_advance_no_check): New inline function, replacing the old FETCH_STRING_CHAR_ADVANCE_NO_CHECK macro. All callers changed. * src/regex-emacs.c (HEAD_ADDR_VSTRING): Remove; no longer used. * src/syntax.c (scan_lists): Use dec_bytepos instead of open-coding it. * src/xdisp.c (string_char_and_length): Rename from string_char_and_length to avoid name conflict with new function in character.h. All callers changed.
Diffstat (limited to 'src')
-rw-r--r--src/bidi.c20
-rw-r--r--src/buffer.c8
-rw-r--r--src/buffer.h101
-rw-r--r--src/bytecode.c2
-rw-r--r--src/casefiddle.c30
-rw-r--r--src/ccl.c11
-rw-r--r--src/character.c31
-rw-r--r--src/character.h449
-rw-r--r--src/charset.c4
-rw-r--r--src/chartab.c10
-rw-r--r--src/cmds.c2
-rw-r--r--src/coding.c61
-rw-r--r--src/composite.c42
-rw-r--r--src/dispextern.h4
-rw-r--r--src/editfns.c26
-rw-r--r--src/fns.c52
-rw-r--r--src/font.c38
-rw-r--r--src/ftcrfont.c5
-rw-r--r--src/indent.c24
-rw-r--r--src/insdel.c7
-rw-r--r--src/keyboard.c10
-rw-r--r--src/keymap.c6
-rw-r--r--src/lread.c33
-rw-r--r--src/marker.c10
-rw-r--r--src/menu.c4
-rw-r--r--src/msdos.c2
-rw-r--r--src/nsfont.m2
-rw-r--r--src/print.c31
-rw-r--r--src/regex-emacs.c28
-rw-r--r--src/search.c46
-rw-r--r--src/syntax.c113
-rw-r--r--src/sysdep.c14
-rw-r--r--src/xdisp.c71
-rw-r--r--src/xfont.c2
-rw-r--r--src/xterm.c2
35 files changed, 579 insertions, 722 deletions
diff --git a/src/bidi.c b/src/bidi.c
index 3abde7fcb09..1017bd2d523 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -109,7 +109,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
109 ------------------- 109 -------------------
110 110
111 In a nutshell, fetching the next character boils down to calling 111 In a nutshell, fetching the next character boils down to calling
112 STRING_CHAR_AND_LENGTH, passing it the address of a buffer or 112 string_char_and_length, passing it the address of a buffer or
113 string position. See bidi_fetch_char. However, if the next 113 string position. See bidi_fetch_char. However, if the next
114 character is "covered" by a display property of some kind, 114 character is "covered" by a display property of some kind,
115 bidi_fetch_char returns the u+FFFC "object replacement character" 115 bidi_fetch_char returns the u+FFFC "object replacement character"
@@ -1269,7 +1269,6 @@ bidi_fetch_char (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t *disp_pos,
1269 ptrdiff_t endpos 1269 ptrdiff_t endpos
1270 = (string->s || STRINGP (string->lstring)) ? string->schars : ZV; 1270 = (string->s || STRINGP (string->lstring)) ? string->schars : ZV;
1271 struct text_pos pos; 1271 struct text_pos pos;
1272 int len;
1273 1272
1274 /* If we got past the last known position of display string, compute 1273 /* If we got past the last known position of display string, compute
1275 the position of the next one. That position could be at CHARPOS. */ 1274 the position of the next one. That position could be at CHARPOS. */
@@ -1341,10 +1340,10 @@ bidi_fetch_char (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t *disp_pos,
1341 normal_char: 1340 normal_char:
1342 if (string->s) 1341 if (string->s)
1343 { 1342 {
1344
1345 if (!string->unibyte) 1343 if (!string->unibyte)
1346 { 1344 {
1347 ch = STRING_CHAR_AND_LENGTH (string->s + bytepos, len); 1345 int len;
1346 ch = string_char_and_length (string->s + bytepos, &len);
1348 *ch_len = len; 1347 *ch_len = len;
1349 } 1348 }
1350 else 1349 else
@@ -1357,8 +1356,9 @@ bidi_fetch_char (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t *disp_pos,
1357 { 1356 {
1358 if (!string->unibyte) 1357 if (!string->unibyte)
1359 { 1358 {
1360 ch = STRING_CHAR_AND_LENGTH (SDATA (string->lstring) + bytepos, 1359 int len;
1361 len); 1360 ch = string_char_and_length (SDATA (string->lstring) + bytepos,
1361 &len);
1362 *ch_len = len; 1362 *ch_len = len;
1363 } 1363 }
1364 else 1364 else
@@ -1369,9 +1369,11 @@ bidi_fetch_char (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t *disp_pos,
1369 } 1369 }
1370 else 1370 else
1371 { 1371 {
1372 ch = STRING_CHAR_AND_LENGTH (BYTE_POS_ADDR (bytepos), len); 1372 int len;
1373 ch = string_char_and_length (BYTE_POS_ADDR (bytepos), &len);
1373 *ch_len = len; 1374 *ch_len = len;
1374 } 1375 }
1376
1375 *nchars = 1; 1377 *nchars = 1;
1376 } 1378 }
1377 1379
@@ -1550,7 +1552,7 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
1550 display string? And what if a display string covering some 1552 display string? And what if a display string covering some
1551 of the text over which we scan back includes 1553 of the text over which we scan back includes
1552 paragraph_start_re? */ 1554 paragraph_start_re? */
1553 DEC_BOTH (pos, pos_byte); 1555 dec_both (&pos, &pos_byte);
1554 if (bpc && region_cache_backward (cache_buffer, bpc, pos, &next)) 1556 if (bpc && region_cache_backward (cache_buffer, bpc, pos, &next))
1555 { 1557 {
1556 pos = next, pos_byte = CHAR_TO_BYTE (pos); 1558 pos = next, pos_byte = CHAR_TO_BYTE (pos);
@@ -1763,7 +1765,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
1763 /* FXIME: What if p is covered by a display 1765 /* FXIME: What if p is covered by a display
1764 string? See also a FIXME inside 1766 string? See also a FIXME inside
1765 bidi_find_paragraph_start. */ 1767 bidi_find_paragraph_start. */
1766 DEC_BOTH (p, pbyte); 1768 dec_both (&p, &pbyte);
1767 prevpbyte = bidi_find_paragraph_start (p, pbyte); 1769 prevpbyte = bidi_find_paragraph_start (p, pbyte);
1768 } 1770 }
1769 pstartbyte = prevpbyte; 1771 pstartbyte = prevpbyte;
diff --git a/src/buffer.c b/src/buffer.c
index f3532a86189..5398414e6eb 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2308,7 +2308,7 @@ advance_to_char_boundary (ptrdiff_t byte_pos)
2308 c = FETCH_BYTE (byte_pos); 2308 c = FETCH_BYTE (byte_pos);
2309 } 2309 }
2310 while (! CHAR_HEAD_P (c) && byte_pos > BEG); 2310 while (! CHAR_HEAD_P (c) && byte_pos > BEG);
2311 INC_POS (byte_pos); 2311 byte_pos += next_char_len (byte_pos);
2312 if (byte_pos < orig_byte_pos) 2312 if (byte_pos < orig_byte_pos)
2313 byte_pos = orig_byte_pos; 2313 byte_pos = orig_byte_pos;
2314 /* If C is a constituent of a multibyte sequence, BYTE_POS was 2314 /* If C is a constituent of a multibyte sequence, BYTE_POS was
@@ -2552,8 +2552,6 @@ current buffer is cleared. */)
2552 p = BEG_ADDR; 2552 p = BEG_ADDR;
2553 while (1) 2553 while (1)
2554 { 2554 {
2555 int c, bytes;
2556
2557 if (pos == stop) 2555 if (pos == stop)
2558 { 2556 {
2559 if (pos == Z) 2557 if (pos == Z)
@@ -2565,7 +2563,7 @@ current buffer is cleared. */)
2565 p++, pos++; 2563 p++, pos++;
2566 else if (CHAR_BYTE8_HEAD_P (*p)) 2564 else if (CHAR_BYTE8_HEAD_P (*p))
2567 { 2565 {
2568 c = STRING_CHAR_AND_LENGTH (p, bytes); 2566 int bytes, c = string_char_and_length (p, &bytes);
2569 /* Delete all bytes for this 8-bit character but the 2567 /* Delete all bytes for this 8-bit character but the
2570 last one, and change the last one to the character 2568 last one, and change the last one to the character
2571 code. */ 2569 code. */
@@ -2582,7 +2580,7 @@ current buffer is cleared. */)
2582 } 2580 }
2583 else 2581 else
2584 { 2582 {
2585 bytes = BYTES_BY_CHAR_HEAD (*p); 2583 int bytes = BYTES_BY_CHAR_HEAD (*p);
2586 p += bytes, pos += bytes; 2584 p += bytes, pos += bytes;
2587 } 2585 }
2588 } 2586 }
diff --git a/src/buffer.h b/src/buffer.h
index 9875b8a447b..3da49414bb8 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1562,6 +1562,107 @@ CHARACTER_WIDTH (int c)
1562 : !NILP (BVAR (current_buffer, ctl_arrow)) ? 2 : 4); 1562 : !NILP (BVAR (current_buffer, ctl_arrow)) ? 2 : 4);
1563} 1563}
1564 1564
1565
1566/* Like fetch_string_char_advance, but fetch character from the current
1567 buffer. */
1568
1569INLINE int
1570fetch_char_advance (ptrdiff_t *charidx, ptrdiff_t *byteidx)
1571{
1572 int output;
1573 ptrdiff_t c = *charidx, b = *byteidx;
1574 c++;
1575 unsigned char *chp = BYTE_POS_ADDR (b);
1576 if (!NILP (BVAR (current_buffer, enable_multibyte_characters)))
1577 {
1578 int chlen;
1579 output = string_char_and_length (chp, &chlen);
1580 b += chlen;
1581 }
1582 else
1583 {
1584 output = *chp;
1585 b++;
1586 }
1587 *charidx = c;
1588 *byteidx = b;
1589 return output;
1590}
1591
1592
1593/* Like fetch_char_advance, but assumes the current buffer is multibyte. */
1594
1595INLINE int
1596fetch_char_advance_no_check (ptrdiff_t *charidx, ptrdiff_t *byteidx)
1597{
1598 int output;
1599 ptrdiff_t c = *charidx, b = *byteidx;
1600 c++;
1601 unsigned char *chp = BYTE_POS_ADDR (b);
1602 int chlen;
1603 output = string_char_and_length (chp, &chlen);
1604 b += chlen;
1605 *charidx = c;
1606 *byteidx = b;
1607 return output;
1608}
1609
1610/* Return the number of bytes in the multibyte character in BUF
1611 that starts at position POS_BYTE. This relies on the fact that
1612 *GPT_ADDR and *Z_ADDR are always accessible and the values are
1613 '\0'. No range checking of POS_BYTE. */
1614
1615INLINE int
1616buf_next_char_len (struct buffer *buf, ptrdiff_t pos_byte)
1617{
1618 unsigned char *chp = BUF_BYTE_ADDRESS (buf, pos_byte);
1619 return BYTES_BY_CHAR_HEAD (*chp);
1620}
1621
1622INLINE int
1623next_char_len (ptrdiff_t pos_byte)
1624{
1625 return buf_next_char_len (current_buffer, pos_byte);
1626}
1627
1628/* Return the number of bytes in the multibyte character in BUF just
1629 before POS_BYTE. No range checking of POS_BYTE. */
1630
1631INLINE int
1632buf_prev_char_len (struct buffer *buf, ptrdiff_t pos_byte)
1633{
1634 unsigned char *chp
1635 = (BUF_BEG_ADDR (buf) + pos_byte - BEG_BYTE
1636 + (pos_byte <= BUF_GPT_BYTE (buf) ? 0 : BUF_GAP_SIZE (buf)));
1637 return raw_prev_char_len (chp);
1638}
1639
1640INLINE int
1641prev_char_len (ptrdiff_t pos_byte)
1642{
1643 return buf_prev_char_len (current_buffer, pos_byte);
1644}
1645
1646/* Increment both *CHARPOS and *BYTEPOS, each in the appropriate way. */
1647
1648INLINE void
1649inc_both (ptrdiff_t *charpos, ptrdiff_t *bytepos)
1650{
1651 (*charpos)++;
1652 (*bytepos) += (!NILP (BVAR (current_buffer, enable_multibyte_characters))
1653 ? next_char_len (*bytepos) : 1);
1654}
1655
1656/* Decrement both *CHARPOS and *BYTEPOS, each in the appropriate way. */
1657
1658INLINE void
1659dec_both (ptrdiff_t *charpos, ptrdiff_t *bytepos)
1660{
1661 (*charpos)--;
1662 (*bytepos) -= (!NILP (BVAR (current_buffer, enable_multibyte_characters))
1663 ? prev_char_len (*bytepos) : 1);
1664}
1665
1565INLINE_HEADER_END 1666INLINE_HEADER_END
1566 1667
1567#endif /* EMACS_BUFFER_H */ 1668#endif /* EMACS_BUFFER_H */
diff --git a/src/bytecode.c b/src/bytecode.c
index 4624379756d..3c90544f3f2 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -1172,7 +1172,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1172 CHECK_CHARACTER (TOP); 1172 CHECK_CHARACTER (TOP);
1173 int c = XFIXNAT (TOP); 1173 int c = XFIXNAT (TOP);
1174 if (NILP (BVAR (current_buffer, enable_multibyte_characters))) 1174 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
1175 MAKE_CHAR_MULTIBYTE (c); 1175 c = make_char_multibyte (c);
1176 XSETFASTINT (TOP, syntax_code_spec[SYNTAX (c)]); 1176 XSETFASTINT (TOP, syntax_code_spec[SYNTAX (c)]);
1177 } 1177 }
1178 NEXT; 1178 NEXT;
diff --git a/src/casefiddle.c b/src/casefiddle.c
index 5018b7bb1cd..9a711a8fba6 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -220,6 +220,13 @@ case_character (struct casing_str_buf *buf, struct casing_context *ctx,
220 return changed; 220 return changed;
221} 221}
222 222
223/* If C is not ASCII, make it unibyte. */
224static int
225make_char_unibyte (int c)
226{
227 return ASCII_CHAR_P (c) ? c : CHAR_TO_BYTE8 (c);
228}
229
223static Lisp_Object 230static Lisp_Object
224do_casify_natnum (struct casing_context *ctx, Lisp_Object obj) 231do_casify_natnum (struct casing_context *ctx, Lisp_Object obj)
225{ 232{
@@ -243,13 +250,13 @@ do_casify_natnum (struct casing_context *ctx, Lisp_Object obj)
243 || !NILP (BVAR (current_buffer, 250 || !NILP (BVAR (current_buffer,
244 enable_multibyte_characters))); 251 enable_multibyte_characters)));
245 if (! multibyte) 252 if (! multibyte)
246 MAKE_CHAR_MULTIBYTE (ch); 253 ch = make_char_multibyte (ch);
247 int cased = case_single_character (ctx, ch); 254 int cased = case_single_character (ctx, ch);
248 if (cased == ch) 255 if (cased == ch)
249 return obj; 256 return obj;
250 257
251 if (! multibyte) 258 if (! multibyte)
252 MAKE_CHAR_UNIBYTE (cased); 259 cased = make_char_unibyte (cased);
253 return make_fixed_natnum (cased | flags); 260 return make_fixed_natnum (cased | flags);
254} 261}
255 262
@@ -278,7 +285,7 @@ do_casify_multibyte_string (struct casing_context *ctx, Lisp_Object obj)
278 { 285 {
279 if (dst_end - o < sizeof (struct casing_str_buf)) 286 if (dst_end - o < sizeof (struct casing_str_buf))
280 string_overflow (); 287 string_overflow ();
281 int ch = STRING_CHAR_ADVANCE (src); 288 int ch = string_char_advance (&src);
282 case_character ((struct casing_str_buf *) o, ctx, ch, 289 case_character ((struct casing_str_buf *) o, ctx, ch,
283 size > 1 ? src : NULL); 290 size > 1 ? src : NULL);
284 n += ((struct casing_str_buf *) o)->len_chars; 291 n += ((struct casing_str_buf *) o)->len_chars;
@@ -299,15 +306,14 @@ do_casify_unibyte_string (struct casing_context *ctx, Lisp_Object obj)
299 obj = Fcopy_sequence (obj); 306 obj = Fcopy_sequence (obj);
300 for (i = 0; i < size; i++) 307 for (i = 0; i < size; i++)
301 { 308 {
302 ch = SREF (obj, i); 309 ch = make_char_multibyte (SREF (obj, i));
303 MAKE_CHAR_MULTIBYTE (ch);
304 cased = case_single_character (ctx, ch); 310 cased = case_single_character (ctx, ch);
305 if (ch == cased) 311 if (ch == cased)
306 continue; 312 continue;
307 MAKE_CHAR_UNIBYTE (cased); 313 cased = make_char_unibyte (cased);
308 /* If the char can't be converted to a valid byte, just don't 314 /* If the char can't be converted to a valid byte, just don't
309 change it. */ 315 change it. */
310 if (cased >= 0 && cased < 256) 316 if (SINGLE_BYTE_CHAR_P (cased))
311 SSET (obj, i, cased); 317 SSET (obj, i, cased);
312 } 318 }
313 return obj; 319 return obj;
@@ -397,9 +403,7 @@ do_casify_unibyte_region (struct casing_context *ctx,
397 403
398 for (ptrdiff_t pos = *startp; pos < end; ++pos) 404 for (ptrdiff_t pos = *startp; pos < end; ++pos)
399 { 405 {
400 int ch = FETCH_BYTE (pos); 406 int ch = make_char_multibyte (FETCH_BYTE (pos));
401 MAKE_CHAR_MULTIBYTE (ch);
402
403 int cased = case_single_character (ctx, ch); 407 int cased = case_single_character (ctx, ch);
404 if (cased == ch) 408 if (cased == ch)
405 continue; 409 continue;
@@ -408,8 +412,7 @@ do_casify_unibyte_region (struct casing_context *ctx,
408 if (first < 0) 412 if (first < 0)
409 first = pos; 413 first = pos;
410 414
411 MAKE_CHAR_UNIBYTE (cased); 415 FETCH_BYTE (pos) = make_char_unibyte (cased);
412 FETCH_BYTE (pos) = cased;
413 } 416 }
414 417
415 *startp = first; 418 *startp = first;
@@ -433,8 +436,7 @@ do_casify_multibyte_region (struct casing_context *ctx,
433 436
434 for (; size; --size) 437 for (; size; --size)
435 { 438 {
436 int len; 439 int len, ch = string_char_and_length (BYTE_POS_ADDR (pos_byte), &len);
437 int ch = STRING_CHAR_AND_LENGTH (BYTE_POS_ADDR (pos_byte), len);
438 struct casing_str_buf buf; 440 struct casing_str_buf buf;
439 if (!case_character (&buf, ctx, ch, 441 if (!case_character (&buf, ctx, ch,
440 size > 1 ? BYTE_POS_ADDR (pos_byte + len) : NULL)) 442 size > 1 ? BYTE_POS_ADDR (pos_byte + len) : NULL))
diff --git a/src/ccl.c b/src/ccl.c
index ac44dc1f608..0f82b97f6a9 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -855,6 +855,13 @@ struct ccl_prog_stack
855/* For the moment, we only support depth 256 of stack. */ 855/* For the moment, we only support depth 256 of stack. */
856static struct ccl_prog_stack ccl_prog_stack_struct[256]; 856static struct ccl_prog_stack ccl_prog_stack_struct[256];
857 857
858/* Return a translation table of id number ID. */
859static Lisp_Object
860GET_TRANSLATION_TABLE (int id)
861{
862 return XCDR (XVECTOR (Vtranslation_table_vector)->contents[id]);
863}
864
858void 865void
859ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size, int dst_size, Lisp_Object charset_list) 866ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size, int dst_size, Lisp_Object charset_list)
860{ 867{
@@ -2101,7 +2108,7 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
2101 source[j++] = *p++; 2108 source[j++] = *p++;
2102 else 2109 else
2103 while (j < CCL_EXECUTE_BUF_SIZE && p < endp) 2110 while (j < CCL_EXECUTE_BUF_SIZE && p < endp)
2104 source[j++] = STRING_CHAR_ADVANCE (p); 2111 source[j++] = string_char_advance (&p);
2105 consumed_chars += j; 2112 consumed_chars += j;
2106 consumed_bytes = p - SDATA (str); 2113 consumed_bytes = p - SDATA (str);
2107 2114
@@ -2126,7 +2133,7 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
2126 if (NILP (unibyte_p)) 2133 if (NILP (unibyte_p))
2127 { 2134 {
2128 for (j = 0; j < ccl.produced; j++) 2135 for (j = 0; j < ccl.produced; j++)
2129 CHAR_STRING_ADVANCE (destination[j], outp); 2136 outp += CHAR_STRING (destination[j], outp);
2130 } 2137 }
2131 else 2138 else
2132 { 2139 {
diff --git a/src/character.c b/src/character.c
index c938e9fe412..303c83ccec3 100644
--- a/src/character.c
+++ b/src/character.c
@@ -141,15 +141,11 @@ char_string (unsigned int c, unsigned char *p)
141} 141}
142 142
143 143
144/* Return a character whose multibyte form is at P. If LEN is not 144/* Return a character whose multibyte form is at P. Set *LEN to the
145 NULL, it must be a pointer to integer. In that case, set *LEN to 145 byte length of the multibyte form. */
146 the byte length of the multibyte form. If ADVANCED is not NULL, it
147 must be a pointer to unsigned char. In that case, set *ADVANCED to
148 the ending address (i.e., the starting address of the next
149 character) of the multibyte form. */
150 146
151int 147int
152string_char (const unsigned char *p, const unsigned char **advanced, int *len) 148string_char (const unsigned char *p, int *len)
153{ 149{
154 int c; 150 int c;
155 const unsigned char *saved_p = p; 151 const unsigned char *saved_p = p;
@@ -157,7 +153,7 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len)
157 if (*p < 0x80 || ! (*p & 0x20) || ! (*p & 0x10)) 153 if (*p < 0x80 || ! (*p & 0x20) || ! (*p & 0x10))
158 { 154 {
159 /* 1-, 2-, and 3-byte sequences can be handled by the macro. */ 155 /* 1-, 2-, and 3-byte sequences can be handled by the macro. */
160 c = STRING_CHAR_ADVANCE (p); 156 c = string_char_advance (&p);
161 } 157 }
162 else if (! (*p & 0x08)) 158 else if (! (*p & 0x08))
163 { 159 {
@@ -185,10 +181,7 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len)
185 p += 5; 181 p += 5;
186 } 182 }
187 183
188 if (len) 184 *len = p - saved_p;
189 *len = p - saved_p;
190 if (advanced)
191 *advanced = p;
192 return c; 185 return c;
193} 186}
194 187
@@ -248,8 +241,7 @@ DEFUN ("unibyte-char-to-multibyte", Funibyte_char_to_multibyte,
248 c = XFIXNAT (ch); 241 c = XFIXNAT (ch);
249 if (c >= 0x100) 242 if (c >= 0x100)
250 error ("Not a unibyte character: %d", c); 243 error ("Not a unibyte character: %d", c);
251 MAKE_CHAR_MULTIBYTE (c); 244 return make_fixnum (make_char_multibyte (c));
252 return make_fixnum (c);
253} 245}
254 246
255DEFUN ("multibyte-char-to-unibyte", Fmultibyte_char_to_unibyte, 247DEFUN ("multibyte-char-to-unibyte", Fmultibyte_char_to_unibyte,
@@ -340,8 +332,7 @@ c_string_width (const unsigned char *str, ptrdiff_t len, int precision,
340 332
341 while (i_byte < len) 333 while (i_byte < len)
342 { 334 {
343 int bytes; 335 int bytes, c = string_char_and_length (str + i_byte, &bytes);
344 int c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes);
345 ptrdiff_t thiswidth = char_width (c, dp); 336 ptrdiff_t thiswidth = char_width (c, dp);
346 337
347 if (0 < precision && precision - width < thiswidth) 338 if (0 < precision && precision - width < thiswidth)
@@ -418,7 +409,7 @@ lisp_string_width (Lisp_Object string, ptrdiff_t precision,
418 if (multibyte) 409 if (multibyte)
419 { 410 {
420 int cbytes; 411 int cbytes;
421 c = STRING_CHAR_AND_LENGTH (str + i_byte, cbytes); 412 c = string_char_and_length (str + i_byte, &cbytes);
422 bytes = cbytes; 413 bytes = cbytes;
423 } 414 }
424 else 415 else
@@ -706,7 +697,7 @@ str_as_unibyte (unsigned char *str, ptrdiff_t bytes)
706 len = BYTES_BY_CHAR_HEAD (c); 697 len = BYTES_BY_CHAR_HEAD (c);
707 if (CHAR_BYTE8_HEAD_P (c)) 698 if (CHAR_BYTE8_HEAD_P (c))
708 { 699 {
709 c = STRING_CHAR_ADVANCE (p); 700 c = string_char_advance (&p);
710 *to++ = CHAR_TO_BYTE8 (c); 701 *to++ = CHAR_TO_BYTE8 (c);
711 } 702 }
712 else 703 else
@@ -730,7 +721,7 @@ str_to_unibyte (const unsigned char *src, unsigned char *dst, ptrdiff_t chars)
730 721
731 for (i = 0; i < chars; i++) 722 for (i = 0; i < chars; i++)
732 { 723 {
733 int c = STRING_CHAR_ADVANCE (src); 724 int c = string_char_advance (&src);
734 725
735 if (CHAR_BYTE8_P (c)) 726 if (CHAR_BYTE8_P (c))
736 c = CHAR_TO_BYTE8 (c); 727 c = CHAR_TO_BYTE8 (c);
@@ -823,7 +814,7 @@ string_escape_byte8 (Lisp_Object string)
823 814
824 if (CHAR_BYTE8_HEAD_P (c)) 815 if (CHAR_BYTE8_HEAD_P (c))
825 { 816 {
826 c = STRING_CHAR_ADVANCE (src); 817 c = string_char_advance (&src);
827 c = CHAR_TO_BYTE8 (c); 818 c = CHAR_TO_BYTE8 (c);
828 dst += sprintf ((char *) dst, "\\%03o", c + 0u); 819 dst += sprintf ((char *) dst, "\\%03o", c + 0u);
829 } 820 }
diff --git a/src/character.h b/src/character.h
index d4bc718af72..81320dedd17 100644
--- a/src/character.h
+++ b/src/character.h
@@ -81,14 +81,20 @@ enum
81}; 81};
82 82
83extern int char_string (unsigned, unsigned char *); 83extern int char_string (unsigned, unsigned char *);
84extern int string_char (const unsigned char *, 84extern int string_char (const unsigned char *, int *);
85 const unsigned char **, int *);
86 85
87/* UTF-8 encodings. Use \x escapes, so they are portable to pre-C11 86/* UTF-8 encodings. Use \x escapes, so they are portable to pre-C11
88 compilers and can be concatenated with ordinary string literals. */ 87 compilers and can be concatenated with ordinary string literals. */
89#define uLSQM "\xE2\x80\x98" /* U+2018 LEFT SINGLE QUOTATION MARK */ 88#define uLSQM "\xE2\x80\x98" /* U+2018 LEFT SINGLE QUOTATION MARK */
90#define uRSQM "\xE2\x80\x99" /* U+2019 RIGHT SINGLE QUOTATION MARK */ 89#define uRSQM "\xE2\x80\x99" /* U+2019 RIGHT SINGLE QUOTATION MARK */
91 90
91/* True iff C is a character of code less than 0x100. */
92INLINE bool
93SINGLE_BYTE_CHAR_P (intmax_t c)
94{
95 return 0 <= c && c < 0x100;
96}
97
92/* True iff C is a character that corresponds to a raw 8-bit 98/* True iff C is a character that corresponds to a raw 8-bit
93 byte. */ 99 byte. */
94INLINE bool 100INLINE bool
@@ -133,17 +139,13 @@ CHAR_BYTE8_HEAD_P (int byte)
133 return byte == 0xC0 || byte == 0xC1; 139 return byte == 0xC0 || byte == 0xC1;
134} 140}
135 141
136/* If C is not ASCII, make it unibyte. */
137#define MAKE_CHAR_UNIBYTE(c) \
138 do { \
139 if (! ASCII_CHAR_P (c)) \
140 c = CHAR_TO_BYTE8 (c); \
141 } while (false)
142
143
144/* If C is not ASCII, make it multibyte. Assumes C < 256. */ 142/* If C is not ASCII, make it multibyte. Assumes C < 256. */
145#define MAKE_CHAR_MULTIBYTE(c) \ 143INLINE int
146 (eassert ((c) >= 0 && (c) < 256), (c) = UNIBYTE_TO_CHAR (c)) 144make_char_multibyte (int c)
145{
146 eassert (SINGLE_BYTE_CHAR_P (c));
147 return UNIBYTE_TO_CHAR (c);
148}
147 149
148/* This is the maximum byte length of multibyte form. */ 150/* This is the maximum byte length of multibyte form. */
149enum { MAX_MULTIBYTE_LENGTH = 5 }; 151enum { MAX_MULTIBYTE_LENGTH = 5 };
@@ -181,13 +183,6 @@ CHECK_CHARACTER_CDR (Lisp_Object x)
181 CHECK_CHARACTER (XCDR (x)); 183 CHECK_CHARACTER (XCDR (x));
182} 184}
183 185
184/* True iff C is a character of code less than 0x100. */
185INLINE bool
186SINGLE_BYTE_CHAR_P (intmax_t c)
187{
188 return 0 <= c && c < 0x100;
189}
190
191/* True if character C has a printable glyph. */ 186/* True if character C has a printable glyph. */
192INLINE bool 187INLINE bool
193CHAR_PRINTABLE_P (int c) 188CHAR_PRINTABLE_P (int c)
@@ -264,29 +259,6 @@ BYTE8_STRING (int b, unsigned char *p)
264} 259}
265 260
266 261
267/* Store multibyte form of the character C in P and advance P to the
268 end of the multibyte form. The caller should allocate at least
269 MAX_MULTIBYTE_LENGTH bytes area at P in advance. */
270
271#define CHAR_STRING_ADVANCE(c, p) \
272 do { \
273 if ((c) <= MAX_1_BYTE_CHAR) \
274 *(p)++ = (c); \
275 else if ((c) <= MAX_2_BYTE_CHAR) \
276 *(p)++ = (0xC0 | ((c) >> 6)), \
277 *(p)++ = (0x80 | ((c) & 0x3F)); \
278 else if ((c) <= MAX_3_BYTE_CHAR) \
279 *(p)++ = (0xE0 | ((c) >> 12)), \
280 *(p)++ = (0x80 | (((c) >> 6) & 0x3F)), \
281 *(p)++ = (0x80 | ((c) & 0x3F)); \
282 else \
283 { \
284 verify (sizeof (c) <= sizeof (unsigned)); \
285 (p) += char_string (c, p); \
286 } \
287 } while (false)
288
289
290/* True iff BYTE starts a non-ASCII character in a multibyte form. */ 262/* True iff BYTE starts a non-ASCII character in a multibyte form. */
291INLINE bool 263INLINE bool
292LEADING_CODE_P (int byte) 264LEADING_CODE_P (int byte)
@@ -365,281 +337,144 @@ MULTIBYTE_LENGTH_NO_CHECK (unsigned char const *p)
365 : 0); 337 : 0);
366} 338}
367 339
368/* If P is before LIMIT, advance P to the next character boundary. 340
341/* Return number of bytes in the multibyte character just before P.
369 Assumes that P is already at a character boundary of the same 342 Assumes that P is already at a character boundary of the same
370 multibyte form whose end address is LIMIT. */ 343 multibyte form, and is not at the start of that form. */
371 344
372#define NEXT_CHAR_BOUNDARY(p, limit) \ 345INLINE int
373 do { \ 346raw_prev_char_len (unsigned char const *p)
374 if ((p) < (limit)) \ 347{
375 (p) += BYTES_BY_CHAR_HEAD (*(p)); \ 348 for (int len = 1; ; len++)
376 } while (false) 349 if (CHAR_HEAD_P (p[-len]))
350 return len;
351}
377 352
378 353
379/* If P is after LIMIT, advance P to the previous character boundary. 354/* Return the character code of character whose multibyte form is at P,
380 Assumes that P is already at a character boundary of the same 355 and set *LENGTH to its length. */
381 multibyte form whose beginning address is LIMIT. */ 356
382 357INLINE int
383#define PREV_CHAR_BOUNDARY(p, limit) \ 358string_char_and_length (unsigned char const *p, int *length)
384 do { \ 359{
385 if ((p) > (limit)) \ 360 int c, len;
386 { \ 361
387 const unsigned char *chp = (p); \ 362 if (! (p[0] & 0x80))
388 do { \ 363 {
389 chp--; \ 364 len = 1;
390 } while (chp >= limit && ! CHAR_HEAD_P (*chp)); \ 365 c = p[0];
391 (p) = (BYTES_BY_CHAR_HEAD (*chp) == (p) - chp) ? chp : (p) - 1; \ 366 }
392 } \ 367 else if (! (p[0] & 0x20))
393 } while (false) 368 {
369 len = 2;
370 c = ((((p[0] & 0x1F) << 6)
371 | (p[1] & 0x3F))
372 + (p[0] < 0xC2 ? 0x3FFF80 : 0));
373 }
374 else if (! (p[0] & 0x10))
375 {
376 len = 3;
377 c = (((p[0] & 0x0F) << 12)
378 | ((p[1] & 0x3F) << 6)
379 | (p[2] & 0x3F));
380 }
381 else
382 c = string_char (p, &len);
383
384 eassume (0 < len && len <= MAX_MULTIBYTE_LENGTH);
385 *length = len;
386 return c;
387}
394 388
395/* Return the character code of character whose multibyte form is at P. */ 389/* Return the character code of character whose multibyte form is at P. */
396 390
397INLINE int 391INLINE int
398STRING_CHAR (unsigned char const *p) 392STRING_CHAR (unsigned char const *p)
399{ 393{
400 return (!(p[0] & 0x80) 394 int len;
401 ? p[0] 395 return string_char_and_length (p, &len);
402 : ! (p[0] & 0x20) 396}
403 ? ((((p[0] & 0x1F) << 6) 397
404 | (p[1] & 0x3F)) 398
405 + (p[0] < 0xC2 ? 0x3FFF80 : 0)) 399/* Like STRING_CHAR (*PP), but advance *PP to the end of multibyte form. */
406 : ! (p[0] & 0x10) 400
407 ? (((p[0] & 0x0F) << 12) 401INLINE int
408 | ((p[1] & 0x3F) << 6) 402string_char_advance (unsigned char const **pp)
409 | (p[2] & 0x3F)) 403{
410 : string_char (p, NULL, NULL)); 404 unsigned char const *p = *pp;
411} 405 int len, c = string_char_and_length (p, &len);
412 406 *pp = p + len;
413 407 return c;
414/* Like STRING_CHAR, but set ACTUAL_LEN to the length of multibyte 408}
415 form. */ 409
416 410
417#define STRING_CHAR_AND_LENGTH(p, actual_len) \ 411/* Return the next character from Lisp string STRING at byte position
418 (!((p)[0] & 0x80) \ 412 *BYTEIDX, character position *CHARIDX. Update *BYTEIDX and
419 ? ((actual_len) = 1, (p)[0]) \ 413 *CHARIDX past the character fetched. */
420 : ! ((p)[0] & 0x20) \ 414
421 ? ((actual_len) = 2, \ 415INLINE int
422 (((((p)[0] & 0x1F) << 6) \ 416fetch_string_char_advance (Lisp_Object string,
423 | ((p)[1] & 0x3F)) \ 417 ptrdiff_t *charidx, ptrdiff_t *byteidx)
424 + (((unsigned char) (p)[0]) < 0xC2 ? 0x3FFF80 : 0))) \ 418{
425 : ! ((p)[0] & 0x10) \ 419 int output;
426 ? ((actual_len) = 3, \ 420 ptrdiff_t b = *byteidx;
427 ((((p)[0] & 0x0F) << 12) \ 421 unsigned char *chp = SDATA (string) + b;
428 | (((p)[1] & 0x3F) << 6) \ 422 if (STRING_MULTIBYTE (string))
429 | ((p)[2] & 0x3F))) \ 423 {
430 : string_char ((p), NULL, &actual_len)) 424 int chlen;
431 425 output = string_char_and_length (chp, &chlen);
432 426 b += chlen;
433/* Like STRING_CHAR, but advance P to the end of multibyte form. */ 427 }
434 428 else
435#define STRING_CHAR_ADVANCE(p) \ 429 {
436 (!((p)[0] & 0x80) \ 430 output = *chp;
437 ? *(p)++ \ 431 b++;
438 : ! ((p)[0] & 0x20) \ 432 }
439 ? ((p) += 2, \ 433 (*charidx)++;
440 ((((p)[-2] & 0x1F) << 6) \ 434 *byteidx = b;
441 | ((p)[-1] & 0x3F) \ 435 return output;
442 | ((unsigned char) ((p)[-2]) < 0xC2 ? 0x3FFF80 : 0))) \ 436}
443 : ! ((p)[0] & 0x10) \ 437
444 ? ((p) += 3, \ 438/* Like fetch_string_char_advance, but return a multibyte character
445 ((((p)[-3] & 0x0F) << 12) \
446 | (((p)[-2] & 0x3F) << 6) \
447 | ((p)[-1] & 0x3F))) \
448 : string_char ((p), &(p), NULL))
449
450
451/* Fetch the "next" character from Lisp string STRING at byte position
452 BYTEIDX, character position CHARIDX. Store it into OUTPUT.
453
454 All the args must be side-effect-free.
455 BYTEIDX and CHARIDX must be lvalues;
456 we increment them past the character fetched. */
457
458#define FETCH_STRING_CHAR_ADVANCE(OUTPUT, STRING, CHARIDX, BYTEIDX) \
459 do \
460 { \
461 CHARIDX++; \
462 if (STRING_MULTIBYTE (STRING)) \
463 { \
464 unsigned char *chp = &SDATA (STRING)[BYTEIDX]; \
465 int chlen; \
466 \
467 OUTPUT = STRING_CHAR_AND_LENGTH (chp, chlen); \
468 BYTEIDX += chlen; \
469 } \
470 else \
471 { \
472 OUTPUT = SREF (STRING, BYTEIDX); \
473 BYTEIDX++; \
474 } \
475 } \
476 while (false)
477
478/* Like FETCH_STRING_CHAR_ADVANCE, but return a multibyte character
479 even if STRING is unibyte. */ 439 even if STRING is unibyte. */
480 440
481#define FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE(OUTPUT, STRING, CHARIDX, BYTEIDX) \ 441INLINE int
482 do \ 442fetch_string_char_as_multibyte_advance (Lisp_Object string,
483 { \ 443 ptrdiff_t *charidx, ptrdiff_t *byteidx)
484 CHARIDX++; \ 444{
485 if (STRING_MULTIBYTE (STRING)) \ 445 int output;
486 { \ 446 ptrdiff_t b = *byteidx;
487 unsigned char *chp = &SDATA (STRING)[BYTEIDX]; \ 447 unsigned char *chp = SDATA (string) + b;
488 int chlen; \ 448 if (STRING_MULTIBYTE (string))
489 \ 449 {
490 OUTPUT = STRING_CHAR_AND_LENGTH (chp, chlen); \ 450 int chlen;
491 BYTEIDX += chlen; \ 451 output = string_char_and_length (chp, &chlen);
492 } \ 452 b += chlen;
493 else \ 453 }
494 { \ 454 else
495 OUTPUT = SREF (STRING, BYTEIDX); \ 455 {
496 BYTEIDX++; \ 456 output = make_char_multibyte (*chp);
497 MAKE_CHAR_MULTIBYTE (OUTPUT); \ 457 b++;
498 } \ 458 }
499 } \ 459 (*charidx)++;
500 while (false) 460 *byteidx = b;
501 461 return output;
502 462}
503/* Like FETCH_STRING_CHAR_ADVANCE, but assumes STRING is multibyte. */ 463
504 464
505#define FETCH_STRING_CHAR_ADVANCE_NO_CHECK(OUTPUT, STRING, CHARIDX, BYTEIDX) \ 465/* Like fetch_string_char_advance, but assumes STRING is multibyte. */
506 do \ 466
507 { \ 467INLINE int
508 unsigned char *fetch_ptr = &SDATA (STRING)[BYTEIDX]; \ 468fetch_string_char_advance_no_check (Lisp_Object string,
509 int fetch_len; \ 469 ptrdiff_t *charidx, ptrdiff_t *byteidx)
510 \ 470{
511 OUTPUT = STRING_CHAR_AND_LENGTH (fetch_ptr, fetch_len); \ 471 ptrdiff_t b = *byteidx;
512 BYTEIDX += fetch_len; \ 472 unsigned char *chp = SDATA (string) + b;
513 CHARIDX++; \ 473 int chlen, output = string_char_and_length (chp, &chlen);
514 } \ 474 (*charidx)++;
515 while (false) 475 *byteidx = b + chlen;
516 476 return output;
517 477}
518/* Like FETCH_STRING_CHAR_ADVANCE, but fetch character from the current
519 buffer. */
520
521#define FETCH_CHAR_ADVANCE(OUTPUT, CHARIDX, BYTEIDX) \
522 do \
523 { \
524 CHARIDX++; \
525 if (!NILP (BVAR (current_buffer, enable_multibyte_characters))) \
526 { \
527 unsigned char *chp = BYTE_POS_ADDR (BYTEIDX); \
528 int chlen; \
529 \
530 OUTPUT = STRING_CHAR_AND_LENGTH (chp, chlen); \
531 BYTEIDX += chlen; \
532 } \
533 else \
534 { \
535 OUTPUT = *(BYTE_POS_ADDR (BYTEIDX)); \
536 BYTEIDX++; \
537 } \
538 } \
539 while (false)
540
541
542/* Like FETCH_CHAR_ADVANCE, but assumes the current buffer is multibyte. */
543
544#define FETCH_CHAR_ADVANCE_NO_CHECK(OUTPUT, CHARIDX, BYTEIDX) \
545 do \
546 { \
547 unsigned char *chp = BYTE_POS_ADDR (BYTEIDX); \
548 int chlen; \
549 \
550 OUTPUT = STRING_CHAR_AND_LENGTH (chp, chlen); \
551 BYTEIDX += chlen; \
552 CHARIDX++; \
553 } \
554 while (false)
555
556
557/* Increment the buffer byte position POS_BYTE of the current buffer to
558 the next character boundary. No range checking of POS. */
559
560#define INC_POS(pos_byte) \
561 do { \
562 unsigned char *chp = BYTE_POS_ADDR (pos_byte); \
563 pos_byte += BYTES_BY_CHAR_HEAD (*chp); \
564 } while (false)
565
566
567/* Decrement the buffer byte position POS_BYTE of the current buffer to
568 the previous character boundary. No range checking of POS. */
569
570#define DEC_POS(pos_byte) \
571 do { \
572 unsigned char *chp; \
573 \
574 pos_byte--; \
575 if (pos_byte < GPT_BYTE) \
576 chp = BEG_ADDR + pos_byte - BEG_BYTE; \
577 else \
578 chp = BEG_ADDR + GAP_SIZE + pos_byte - BEG_BYTE; \
579 while (!CHAR_HEAD_P (*chp)) \
580 { \
581 chp--; \
582 pos_byte--; \
583 } \
584 } while (false)
585
586/* Increment both CHARPOS and BYTEPOS, each in the appropriate way. */
587
588#define INC_BOTH(charpos, bytepos) \
589 do \
590 { \
591 (charpos)++; \
592 if (NILP (BVAR (current_buffer, enable_multibyte_characters))) \
593 (bytepos)++; \
594 else \
595 INC_POS ((bytepos)); \
596 } \
597 while (false)
598
599
600/* Decrement both CHARPOS and BYTEPOS, each in the appropriate way. */
601
602#define DEC_BOTH(charpos, bytepos) \
603 do \
604 { \
605 (charpos)--; \
606 if (NILP (BVAR (current_buffer, enable_multibyte_characters))) \
607 (bytepos)--; \
608 else \
609 DEC_POS ((bytepos)); \
610 } \
611 while (false)
612
613
614/* Increment the buffer byte position POS_BYTE of the current buffer to
615 the next character boundary. This macro relies on the fact that
616 *GPT_ADDR and *Z_ADDR are always accessible and the values are
617 '\0'. No range checking of POS_BYTE. */
618
619#define BUF_INC_POS(buf, pos_byte) \
620 do { \
621 unsigned char *chp = BUF_BYTE_ADDRESS (buf, pos_byte); \
622 pos_byte += BYTES_BY_CHAR_HEAD (*chp); \
623 } while (false)
624
625
626/* Decrement the buffer byte position POS_BYTE of the current buffer to
627 the previous character boundary. No range checking of POS_BYTE. */
628
629#define BUF_DEC_POS(buf, pos_byte) \
630 do { \
631 unsigned char *chp; \
632 pos_byte--; \
633 if (pos_byte < BUF_GPT_BYTE (buf)) \
634 chp = BUF_BEG_ADDR (buf) + pos_byte - BEG_BYTE; \
635 else \
636 chp = BUF_BEG_ADDR (buf) + BUF_GAP_SIZE (buf) + pos_byte - BEG_BYTE;\
637 while (!CHAR_HEAD_P (*chp)) \
638 { \
639 chp--; \
640 pos_byte--; \
641 } \
642 } while (false)
643 478
644 479
645/* If C is a variation selector, return the index of the 480/* If C is a variation selector, return the index of the
@@ -728,10 +563,6 @@ extern bool graphicp (int);
728extern bool printablep (int); 563extern bool printablep (int);
729extern bool blankp (int); 564extern bool blankp (int);
730 565
731/* Return a translation table of id number ID. */
732#define GET_TRANSLATION_TABLE(id) \
733 (XCDR (XVECTOR (Vtranslation_table_vector)->contents[(id)]))
734
735/* Look up the element in char table OBJ at index CH, and return it as 566/* Look up the element in char table OBJ at index CH, and return it as
736 an integer. If the element is not a character, return CH itself. */ 567 an integer. If the element is not a character, return CH itself. */
737 568
diff --git a/src/charset.c b/src/charset.c
index 9e55d0c7fef..8635aad3ed6 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1460,7 +1460,7 @@ string_xstring_p (Lisp_Object string)
1460 1460
1461 while (p < endp) 1461 while (p < endp)
1462 { 1462 {
1463 int c = STRING_CHAR_ADVANCE (p); 1463 int c = string_char_advance (&p);
1464 1464
1465 if (c >= 0x100) 1465 if (c >= 0x100)
1466 return 2; 1466 return 2;
@@ -1504,7 +1504,7 @@ find_charsets_in_text (const unsigned char *ptr, ptrdiff_t nchars,
1504 { 1504 {
1505 while (ptr < pend) 1505 while (ptr < pend)
1506 { 1506 {
1507 int c = STRING_CHAR_ADVANCE (ptr); 1507 int c = string_char_advance (&ptr);
1508 struct charset *charset; 1508 struct charset *charset;
1509 1509
1510 if (!NILP (table)) 1510 if (!NILP (table))
diff --git a/src/chartab.c b/src/chartab.c
index 04205ac1032..cb2ced568d9 100644
--- a/src/chartab.c
+++ b/src/chartab.c
@@ -1117,10 +1117,10 @@ uniprop_table_uncompress (Lisp_Object table, int idx)
1117 { 1117 {
1118 /* SIMPLE TABLE */ 1118 /* SIMPLE TABLE */
1119 p++; 1119 p++;
1120 idx = STRING_CHAR_ADVANCE (p); 1120 idx = string_char_advance (&p);
1121 while (p < pend && idx < chartab_chars[2]) 1121 while (p < pend && idx < chartab_chars[2])
1122 { 1122 {
1123 int v = STRING_CHAR_ADVANCE (p); 1123 int v = string_char_advance (&p);
1124 set_sub_char_table_contents 1124 set_sub_char_table_contents
1125 (sub, idx++, v > 0 ? make_fixnum (v) : Qnil); 1125 (sub, idx++, v > 0 ? make_fixnum (v) : Qnil);
1126 } 1126 }
@@ -1131,13 +1131,13 @@ uniprop_table_uncompress (Lisp_Object table, int idx)
1131 p++; 1131 p++;
1132 for (idx = 0; p < pend; ) 1132 for (idx = 0; p < pend; )
1133 { 1133 {
1134 int v = STRING_CHAR_ADVANCE (p); 1134 int v = string_char_advance (&p);
1135 int count = 1; 1135 int count = 1;
1136 int len;
1137 1136
1138 if (p < pend) 1137 if (p < pend)
1139 { 1138 {
1140 count = STRING_CHAR_AND_LENGTH (p, len); 1139 int len;
1140 count = string_char_and_length (p, &len);
1141 if (count < 128) 1141 if (count < 128)
1142 count = 1; 1142 count = 1;
1143 else 1143 else
diff --git a/src/cmds.c b/src/cmds.c
index c342cd88bd8..9f96f210b9f 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -389,7 +389,7 @@ internal_self_insert (int c, EMACS_INT n)
389 /* We will delete too many columns. Let's fill columns 389 /* We will delete too many columns. Let's fill columns
390 by spaces so that the remaining text won't move. */ 390 by spaces so that the remaining text won't move. */
391 ptrdiff_t actual = PT_BYTE; 391 ptrdiff_t actual = PT_BYTE;
392 DEC_POS (actual); 392 actual -= prev_char_len (actual);
393 if (FETCH_CHAR (actual) == '\t') 393 if (FETCH_CHAR (actual) == '\t')
394 /* Rather than add spaces, let's just keep the tab. */ 394 /* Rather than add spaces, let's just keep the tab. */
395 chars_to_delete--; 395 chars_to_delete--;
diff --git a/src/coding.c b/src/coding.c
index 0daa390bc85..716b0d99792 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -643,7 +643,7 @@ growable_destination (struct coding_system *coding)
643 else \ 643 else \
644 { \ 644 { \
645 src--; \ 645 src--; \
646 c = - string_char (src, &src, NULL); \ 646 c = - string_char_advance (&src); \
647 record_conversion_result \ 647 record_conversion_result \
648 (coding, CODING_RESULT_INVALID_SRC); \ 648 (coding, CODING_RESULT_INVALID_SRC); \
649 } \ 649 } \
@@ -728,7 +728,7 @@ growable_destination (struct coding_system *coding)
728 unsigned ch = (c); \ 728 unsigned ch = (c); \
729 if (ch >= 0x80) \ 729 if (ch >= 0x80) \
730 ch = BYTE8_TO_CHAR (ch); \ 730 ch = BYTE8_TO_CHAR (ch); \
731 CHAR_STRING_ADVANCE (ch, dst); \ 731 dst += CHAR_STRING (ch, dst); \
732 } \ 732 } \
733 else \ 733 else \
734 *dst++ = (c); \ 734 *dst++ = (c); \
@@ -747,11 +747,11 @@ growable_destination (struct coding_system *coding)
747 ch = (c1); \ 747 ch = (c1); \
748 if (ch >= 0x80) \ 748 if (ch >= 0x80) \
749 ch = BYTE8_TO_CHAR (ch); \ 749 ch = BYTE8_TO_CHAR (ch); \
750 CHAR_STRING_ADVANCE (ch, dst); \ 750 dst += CHAR_STRING (ch, dst); \
751 ch = (c2); \ 751 ch = (c2); \
752 if (ch >= 0x80) \ 752 if (ch >= 0x80) \
753 ch = BYTE8_TO_CHAR (ch); \ 753 ch = BYTE8_TO_CHAR (ch); \
754 CHAR_STRING_ADVANCE (ch, dst); \ 754 dst += CHAR_STRING (ch, dst); \
755 } \ 755 } \
756 else \ 756 else \
757 { \ 757 { \
@@ -884,18 +884,18 @@ record_conversion_result (struct coding_system *coding,
884 884
885 885
886/* Store multibyte form of the character C in P, and advance P to the 886/* Store multibyte form of the character C in P, and advance P to the
887 end of the multibyte form. This used to be like CHAR_STRING_ADVANCE 887 end of the multibyte form. This used to be like adding CHAR_STRING
888 without ever calling MAYBE_UNIFY_CHAR, but nowadays we don't call 888 without ever calling MAYBE_UNIFY_CHAR, but nowadays we don't call
889 MAYBE_UNIFY_CHAR in CHAR_STRING_ADVANCE. */ 889 MAYBE_UNIFY_CHAR in CHAR_STRING. */
890 890
891#define CHAR_STRING_ADVANCE_NO_UNIFY(c, p) CHAR_STRING_ADVANCE(c, p) 891#define CHAR_STRING_ADVANCE_NO_UNIFY(c, p) ((p) += CHAR_STRING (c, p))
892 892
893/* Return the character code of character whose multibyte form is at 893/* Return the character code of character whose multibyte form is at
894 P, and advance P to the end of the multibyte form. This used to be 894 P, and advance P to the end of the multibyte form. This used to be
895 like STRING_CHAR_ADVANCE without ever calling MAYBE_UNIFY_CHAR, but 895 like string_char_advance without ever calling MAYBE_UNIFY_CHAR, but
896 nowadays STRING_CHAR_ADVANCE doesn't call MAYBE_UNIFY_CHAR. */ 896 nowadays string_char_advance doesn't call MAYBE_UNIFY_CHAR. */
897 897
898#define STRING_CHAR_ADVANCE_NO_UNIFY(p) STRING_CHAR_ADVANCE(p) 898#define STRING_CHAR_ADVANCE_NO_UNIFY(p) string_char_advance (&(p))
899 899
900/* Set coding->source from coding->src_object. */ 900/* Set coding->source from coding->src_object. */
901 901
@@ -5131,7 +5131,7 @@ decode_coding_ccl (struct coding_system *coding)
5131 while (i < 1024 && p < src_end) 5131 while (i < 1024 && p < src_end)
5132 { 5132 {
5133 source_byteidx[i] = p - src; 5133 source_byteidx[i] = p - src;
5134 source_charbuf[i++] = STRING_CHAR_ADVANCE (p); 5134 source_charbuf[i++] = string_char_advance (&p);
5135 } 5135 }
5136 source_byteidx[i] = p - src; 5136 source_byteidx[i] = p - src;
5137 } 5137 }
@@ -5308,15 +5308,10 @@ encode_coding_raw_text (struct coding_system *coding)
5308 } 5308 }
5309 else 5309 else
5310 { 5310 {
5311 unsigned char str[MAX_MULTIBYTE_LENGTH], *p0 = str, *p1 = str; 5311 unsigned char str[MAX_MULTIBYTE_LENGTH];
5312 5312 int len = CHAR_STRING (c, str);
5313 CHAR_STRING_ADVANCE (c, p1); 5313 for (int i = 0; i < len; i++)
5314 do 5314 EMIT_ONE_BYTE (str[i]);
5315 {
5316 EMIT_ONE_BYTE (*p0);
5317 p0++;
5318 }
5319 while (p0 < p1);
5320 } 5315 }
5321 } 5316 }
5322 else 5317 else
@@ -5342,7 +5337,7 @@ encode_coding_raw_text (struct coding_system *coding)
5342 else if (CHAR_BYTE8_P (c)) 5337 else if (CHAR_BYTE8_P (c))
5343 *dst++ = CHAR_TO_BYTE8 (c); 5338 *dst++ = CHAR_TO_BYTE8 (c);
5344 else 5339 else
5345 CHAR_STRING_ADVANCE (c, dst); 5340 dst += CHAR_STRING (c, dst);
5346 } 5341 }
5347 } 5342 }
5348 else 5343 else
@@ -7457,7 +7452,7 @@ decode_coding (struct coding_system *coding)
7457 if (coding->src_multibyte 7452 if (coding->src_multibyte
7458 && CHAR_BYTE8_HEAD_P (*src) && nbytes > 0) 7453 && CHAR_BYTE8_HEAD_P (*src) && nbytes > 0)
7459 { 7454 {
7460 c = STRING_CHAR_ADVANCE (src); 7455 c = string_char_advance (&src);
7461 nbytes--; 7456 nbytes--;
7462 } 7457 }
7463 else 7458 else
@@ -7551,10 +7546,8 @@ handle_composition_annotation (ptrdiff_t pos, ptrdiff_t limit,
7551 len = SCHARS (components); 7546 len = SCHARS (components);
7552 i = i_byte = 0; 7547 i = i_byte = 0;
7553 while (i < len) 7548 while (i < len)
7554 { 7549 *buf++ = fetch_string_char_advance (components,
7555 FETCH_STRING_CHAR_ADVANCE (*buf, components, i, i_byte); 7550 &i, &i_byte);
7556 buf++;
7557 }
7558 } 7551 }
7559 else if (FIXNUMP (components)) 7552 else if (FIXNUMP (components))
7560 { 7553 {
@@ -7715,7 +7708,7 @@ consume_chars (struct coding_system *coding, Lisp_Object translation_table,
7715 7708
7716 lookup_buf[0] = c; 7709 lookup_buf[0] = c;
7717 for (i = 1; i < max_lookup && p < src_end; i++) 7710 for (i = 1; i < max_lookup && p < src_end; i++)
7718 lookup_buf[i] = STRING_CHAR_ADVANCE (p); 7711 lookup_buf[i] = string_char_advance (&p);
7719 lookup_buf_end = lookup_buf + i; 7712 lookup_buf_end = lookup_buf + i;
7720 trans = get_translation (trans, lookup_buf, lookup_buf_end, 7713 trans = get_translation (trans, lookup_buf, lookup_buf_end,
7721 &from_nchars); 7714 &from_nchars);
@@ -9075,7 +9068,7 @@ DEFUN ("find-coding-systems-region-internal",
9075 p++; 9068 p++;
9076 else 9069 else
9077 { 9070 {
9078 c = STRING_CHAR_ADVANCE (p); 9071 c = string_char_advance (&p);
9079 if (!NILP (char_table_ref (work_table, c))) 9072 if (!NILP (char_table_ref (work_table, c)))
9080 /* This character was already checked. Ignore it. */ 9073 /* This character was already checked. Ignore it. */
9081 continue; 9074 continue;
@@ -9208,7 +9201,7 @@ to the string and treated as in `substring'. */)
9208 p = GAP_END_ADDR; 9201 p = GAP_END_ADDR;
9209 } 9202 }
9210 9203
9211 c = STRING_CHAR_ADVANCE (p); 9204 c = string_char_advance (&p);
9212 if (! (ASCII_CHAR_P (c) && ascii_compatible) 9205 if (! (ASCII_CHAR_P (c) && ascii_compatible)
9213 && ! char_charset (translate_char (translation_table, c), 9206 && ! char_charset (translate_char (translation_table, c),
9214 charset_list, NULL)) 9207 charset_list, NULL))
@@ -9326,7 +9319,7 @@ is nil. */)
9326 p++; 9319 p++;
9327 else 9320 else
9328 { 9321 {
9329 c = STRING_CHAR_ADVANCE (p); 9322 c = string_char_advance (&p);
9330 9323
9331 charset_map_loaded = 0; 9324 charset_map_loaded = 0;
9332 for (tail = list; CONSP (tail); tail = XCDR (tail)) 9325 for (tail = list; CONSP (tail); tail = XCDR (tail))
@@ -9728,7 +9721,7 @@ encode_string_utf_8 (Lisp_Object string, Lisp_Object buffer,
9728 || (len == 2 ? ! CHAR_BYTE8_HEAD_P (c) 9721 || (len == 2 ? ! CHAR_BYTE8_HEAD_P (c)
9729 : (EQ (handle_over_uni, Qt) 9722 : (EQ (handle_over_uni, Qt)
9730 || (len == 4 9723 || (len == 4
9731 && string_char (p, NULL, NULL) <= MAX_UNICODE_CHAR)))) 9724 && STRING_CHAR (p) <= MAX_UNICODE_CHAR))))
9732 { 9725 {
9733 p += len; 9726 p += len;
9734 continue; 9727 continue;
@@ -10010,8 +10003,7 @@ decode_string_utf_8 (Lisp_Object string, const char *str, ptrdiff_t str_len,
10010 && (len == 3 10003 && (len == 3
10011 || (UTF_8_EXTRA_OCTET_P (p[3]) 10004 || (UTF_8_EXTRA_OCTET_P (p[3])
10012 && len == 4 10005 && len == 4
10013 && (string_char (p, NULL, NULL) 10006 && STRING_CHAR (p) <= MAX_UNICODE_CHAR)))))
10014 <= MAX_UNICODE_CHAR))))))
10015 { 10007 {
10016 p += len; 10008 p += len;
10017 continue; 10009 continue;
@@ -10148,8 +10140,7 @@ decode_string_utf_8 (Lisp_Object string, const char *str, ptrdiff_t str_len,
10148 mlen++); 10140 mlen++);
10149 if (mlen == len 10141 if (mlen == len
10150 && (len <= 3 10142 && (len <= 3
10151 || (len == 4 10143 || (len == 4 && STRING_CHAR (p) <= MAX_UNICODE_CHAR)
10152 && string_char (p, NULL, NULL) <= MAX_UNICODE_CHAR)
10153 || EQ (handle_over_uni, Qt))) 10144 || EQ (handle_over_uni, Qt)))
10154 { 10145 {
10155 p += len; 10146 p += len;
diff --git a/src/composite.c b/src/composite.c
index a00a4541f5e..518502be49f 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -170,7 +170,6 @@ get_composition_id (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t nchars,
170 ptrdiff_t hash_index; 170 ptrdiff_t hash_index;
171 enum composition_method method; 171 enum composition_method method;
172 struct composition *cmp; 172 struct composition *cmp;
173 ptrdiff_t i;
174 int ch; 173 int ch;
175 174
176 /* Maximum length of a string of glyphs. XftGlyphExtents limits 175 /* Maximum length of a string of glyphs. XftGlyphExtents limits
@@ -224,15 +223,15 @@ get_composition_id (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t nchars,
224 { 223 {
225 key = make_uninit_vector (nchars); 224 key = make_uninit_vector (nchars);
226 if (STRINGP (string)) 225 if (STRINGP (string))
227 for (i = 0; i < nchars; i++) 226 for (ptrdiff_t i = 0; i < nchars; i++)
228 { 227 {
229 FETCH_STRING_CHAR_ADVANCE (ch, string, charpos, bytepos); 228 ch = fetch_string_char_advance (string, &charpos, &bytepos);
230 ASET (key, i, make_fixnum (ch)); 229 ASET (key, i, make_fixnum (ch));
231 } 230 }
232 else 231 else
233 for (i = 0; i < nchars; i++) 232 for (ptrdiff_t i = 0; i < nchars; i++)
234 { 233 {
235 FETCH_CHAR_ADVANCE (ch, charpos, bytepos); 234 ch = fetch_char_advance (&charpos, &bytepos);
236 ASET (key, i, make_fixnum (ch)); 235 ASET (key, i, make_fixnum (ch));
237 } 236 }
238 } 237 }
@@ -273,7 +272,7 @@ get_composition_id (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t nchars,
273 /* COMPONENTS is a glyph-string. */ 272 /* COMPONENTS is a glyph-string. */
274 ptrdiff_t len = ASIZE (key); 273 ptrdiff_t len = ASIZE (key);
275 274
276 for (i = 1; i < len; i++) 275 for (ptrdiff_t i = 1; i < len; i++)
277 if (! VECTORP (AREF (key, i))) 276 if (! VECTORP (AREF (key, i)))
278 goto invalid_composition; 277 goto invalid_composition;
279 } 278 }
@@ -286,7 +285,7 @@ get_composition_id (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t nchars,
286 goto invalid_composition; 285 goto invalid_composition;
287 /* All elements should be integers (character or encoded 286 /* All elements should be integers (character or encoded
288 composition rule). */ 287 composition rule). */
289 for (i = 0; i < len; i++) 288 for (ptrdiff_t i = 0; i < len; i++)
290 { 289 {
291 if (!FIXNUMP (key_contents[i])) 290 if (!FIXNUMP (key_contents[i]))
292 goto invalid_composition; 291 goto invalid_composition;
@@ -328,7 +327,7 @@ get_composition_id (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t nchars,
328 { 327 {
329 /* Relative composition. */ 328 /* Relative composition. */
330 cmp->width = 0; 329 cmp->width = 0;
331 for (i = 0; i < glyph_len; i++) 330 for (ptrdiff_t i = 0; i < glyph_len; i++)
332 { 331 {
333 int this_width; 332 int this_width;
334 ch = XFIXNUM (key_contents[i]); 333 ch = XFIXNUM (key_contents[i]);
@@ -347,7 +346,7 @@ get_composition_id (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t nchars,
347 ch = XFIXNUM (key_contents[0]); 346 ch = XFIXNUM (key_contents[0]);
348 rightmost = ch != '\t' ? CHARACTER_WIDTH (ch) : 1; 347 rightmost = ch != '\t' ? CHARACTER_WIDTH (ch) : 1;
349 348
350 for (i = 1; i < glyph_len; i += 2) 349 for (ptrdiff_t i = 1; i < glyph_len; i += 2)
351 { 350 {
352 int rule, gref, nref; 351 int rule, gref, nref;
353 int this_width; 352 int this_width;
@@ -800,12 +799,10 @@ fill_gstring_header (ptrdiff_t from, ptrdiff_t from_byte,
800 ASET (header, 0, font_object); 799 ASET (header, 0, font_object);
801 for (ptrdiff_t i = 0; i < len; i++) 800 for (ptrdiff_t i = 0; i < len; i++)
802 { 801 {
803 int c; 802 int c
804 803 = (NILP (string)
805 if (NILP (string)) 804 ? fetch_char_advance_no_check (&from, &from_byte)
806 FETCH_CHAR_ADVANCE_NO_CHECK (c, from, from_byte); 805 : fetch_string_char_advance_no_check (string, &from, &from_byte));
807 else
808 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, from, from_byte);
809 ASET (header, i + 1, make_fixnum (c)); 806 ASET (header, i + 1, make_fixnum (c));
810 } 807 }
811 return header; 808 return header;
@@ -1012,10 +1009,9 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
1012 /* Forward search. */ 1009 /* Forward search. */
1013 while (charpos < endpos) 1010 while (charpos < endpos)
1014 { 1011 {
1015 if (STRINGP (string)) 1012 c = (STRINGP (string)
1016 FETCH_STRING_CHAR_ADVANCE (c, string, charpos, bytepos); 1013 ? fetch_string_char_advance (string, &charpos, &bytepos)
1017 else 1014 : fetch_char_advance (&charpos, &bytepos));
1018 FETCH_CHAR_ADVANCE (c, charpos, bytepos);
1019 if (c == '\n') 1015 if (c == '\n')
1020 { 1016 {
1021 cmp_it->ch = -2; 1017 cmp_it->ch = -2;
@@ -1070,7 +1066,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
1070 p = BYTE_POS_ADDR (bytepos); 1066 p = BYTE_POS_ADDR (bytepos);
1071 else 1067 else
1072 p = SDATA (string) + bytepos; 1068 p = SDATA (string) + bytepos;
1073 c = STRING_CHAR_AND_LENGTH (p, len); 1069 c = string_char_and_length (p, &len);
1074 limit = bytepos + len; 1070 limit = bytepos + len;
1075 while (char_composable_p (c)) 1071 while (char_composable_p (c))
1076 { 1072 {
@@ -1132,7 +1128,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
1132 } 1128 }
1133 else 1129 else
1134 { 1130 {
1135 DEC_BOTH (charpos, bytepos); 1131 dec_both (&charpos, &bytepos);
1136 p = BYTE_POS_ADDR (bytepos); 1132 p = BYTE_POS_ADDR (bytepos);
1137 } 1133 }
1138 c = STRING_CHAR (p); 1134 c = STRING_CHAR (p);
@@ -1145,7 +1141,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
1145 { 1141 {
1146 while (charpos - 1 > endpos && ! char_composable_p (c)) 1142 while (charpos - 1 > endpos && ! char_composable_p (c))
1147 { 1143 {
1148 DEC_BOTH (charpos, bytepos); 1144 dec_both (&charpos, &bytepos);
1149 c = FETCH_MULTIBYTE_CHAR (bytepos); 1145 c = FETCH_MULTIBYTE_CHAR (bytepos);
1150 } 1146 }
1151 } 1147 }
@@ -1290,7 +1286,7 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos,
1290 { 1286 {
1291 charpos++; 1287 charpos++;
1292 if (NILP (string)) 1288 if (NILP (string))
1293 INC_POS (bytepos); 1289 bytepos += next_char_len (bytepos);
1294 else 1290 else
1295 bytepos += BYTES_BY_CHAR_HEAD (*(SDATA (string) + bytepos)); 1291 bytepos += BYTES_BY_CHAR_HEAD (*(SDATA (string) + bytepos));
1296 } 1292 }
diff --git a/src/dispextern.h b/src/dispextern.h
index ae994d7f9bc..d6fe68cf99f 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -234,7 +234,7 @@ struct text_pos
234 { \ 234 { \
235 ++(POS).charpos; \ 235 ++(POS).charpos; \
236 if (MULTIBYTE_P) \ 236 if (MULTIBYTE_P) \
237 INC_POS ((POS).bytepos); \ 237 (POS).bytepos += next_char_len ((POS).bytepos); \
238 else \ 238 else \
239 ++(POS).bytepos; \ 239 ++(POS).bytepos; \
240 } \ 240 } \
@@ -247,7 +247,7 @@ struct text_pos
247 { \ 247 { \
248 --(POS).charpos; \ 248 --(POS).charpos; \
249 if (MULTIBYTE_P) \ 249 if (MULTIBYTE_P) \
250 DEC_POS ((POS).bytepos); \ 250 (POS).bytepos -= prev_char_len ((POS).bytepos); \
251 else \ 251 else \
252 --(POS).bytepos; \ 252 --(POS).bytepos; \
253 } \ 253 } \
diff --git a/src/editfns.c b/src/editfns.c
index 90520d0dced..d9da119845a 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -999,7 +999,7 @@ At the beginning of the buffer or accessible region, return 0. */)
999 else if (!NILP (BVAR (current_buffer, enable_multibyte_characters))) 999 else if (!NILP (BVAR (current_buffer, enable_multibyte_characters)))
1000 { 1000 {
1001 ptrdiff_t pos = PT_BYTE; 1001 ptrdiff_t pos = PT_BYTE;
1002 DEC_POS (pos); 1002 pos -= prev_char_len (pos);
1003 XSETFASTINT (temp, FETCH_CHAR (pos)); 1003 XSETFASTINT (temp, FETCH_CHAR (pos));
1004 } 1004 }
1005 else 1005 else
@@ -1112,7 +1112,7 @@ If POS is out of range, the value is nil. */)
1112 1112
1113 if (!NILP (BVAR (current_buffer, enable_multibyte_characters))) 1113 if (!NILP (BVAR (current_buffer, enable_multibyte_characters)))
1114 { 1114 {
1115 DEC_POS (pos_byte); 1115 pos_byte -= prev_char_len (pos_byte);
1116 XSETFASTINT (val, FETCH_CHAR (pos_byte)); 1116 XSETFASTINT (val, FETCH_CHAR (pos_byte));
1117 } 1117 }
1118 else 1118 else
@@ -1549,7 +1549,7 @@ from adjoining text, if those properties are sticky. */)
1549 make_uninit_string, which can cause the buffer arena to be 1549 make_uninit_string, which can cause the buffer arena to be
1550 compacted. make_string has no way of knowing that the data has 1550 compacted. make_string has no way of knowing that the data has
1551 been moved, and thus copies the wrong data into the string. This 1551 been moved, and thus copies the wrong data into the string. This
1552 doesn't effect most of the other users of make_string, so it should 1552 doesn't affect most of the other users of make_string, so it should
1553 be left as is. But we should use this function when conjuring 1553 be left as is. But we should use this function when conjuring
1554 buffer substrings. */ 1554 buffer substrings. */
1555 1555
@@ -1830,26 +1830,24 @@ determines whether case is significant or ignored. */)
1830 if (! NILP (BVAR (bp1, enable_multibyte_characters))) 1830 if (! NILP (BVAR (bp1, enable_multibyte_characters)))
1831 { 1831 {
1832 c1 = BUF_FETCH_MULTIBYTE_CHAR (bp1, i1_byte); 1832 c1 = BUF_FETCH_MULTIBYTE_CHAR (bp1, i1_byte);
1833 BUF_INC_POS (bp1, i1_byte); 1833 i1_byte += buf_next_char_len (bp1, i1_byte);
1834 i1++; 1834 i1++;
1835 } 1835 }
1836 else 1836 else
1837 { 1837 {
1838 c1 = BUF_FETCH_BYTE (bp1, i1); 1838 c1 = make_char_multibyte (BUF_FETCH_BYTE (bp1, i1));
1839 MAKE_CHAR_MULTIBYTE (c1);
1840 i1++; 1839 i1++;
1841 } 1840 }
1842 1841
1843 if (! NILP (BVAR (bp2, enable_multibyte_characters))) 1842 if (! NILP (BVAR (bp2, enable_multibyte_characters)))
1844 { 1843 {
1845 c2 = BUF_FETCH_MULTIBYTE_CHAR (bp2, i2_byte); 1844 c2 = BUF_FETCH_MULTIBYTE_CHAR (bp2, i2_byte);
1846 BUF_INC_POS (bp2, i2_byte); 1845 i2_byte += buf_next_char_len (bp2, i2_byte);
1847 i2++; 1846 i2++;
1848 } 1847 }
1849 else 1848 else
1850 { 1849 {
1851 c2 = BUF_FETCH_BYTE (bp2, i2); 1850 c2 = make_char_multibyte (BUF_FETCH_BYTE (bp2, i2));
1852 MAKE_CHAR_MULTIBYTE (c2);
1853 i2++; 1851 i2++;
1854 } 1852 }
1855 1853
@@ -2304,7 +2302,7 @@ Both characters must have the same length of multi-byte form. */)
2304 } 2302 }
2305 p = BYTE_POS_ADDR (pos_byte); 2303 p = BYTE_POS_ADDR (pos_byte);
2306 if (multibyte_p) 2304 if (multibyte_p)
2307 INC_POS (pos_byte_next); 2305 pos_byte_next += next_char_len (pos_byte_next);
2308 else 2306 else
2309 ++pos_byte_next; 2307 ++pos_byte_next;
2310 if (pos_byte_next - pos_byte == len 2308 if (pos_byte_next - pos_byte == len
@@ -2365,7 +2363,7 @@ Both characters must have the same length of multi-byte form. */)
2365 decrease it now. */ 2363 decrease it now. */
2366 pos--; 2364 pos--;
2367 else 2365 else
2368 INC_POS (pos_byte_next); 2366 pos_byte_next += next_char_len (pos_byte_next);
2369 2367
2370 if (! NILP (noundo)) 2368 if (! NILP (noundo))
2371 bset_undo_list (current_buffer, tem); 2369 bset_undo_list (current_buffer, tem);
@@ -2442,7 +2440,7 @@ check_translation (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t end,
2442 memcpy (bufalloc, buf, sizeof initial_buf); 2440 memcpy (bufalloc, buf, sizeof initial_buf);
2443 buf = bufalloc; 2441 buf = bufalloc;
2444 } 2442 }
2445 buf[buf_used++] = STRING_CHAR_AND_LENGTH (p, len1); 2443 buf[buf_used++] = string_char_and_length (p, &len1);
2446 pos_byte += len1; 2444 pos_byte += len1;
2447 } 2445 }
2448 if (XFIXNUM (AREF (elt, i)) != buf[i]) 2446 if (XFIXNUM (AREF (elt, i)) != buf[i])
@@ -2501,7 +2499,7 @@ It returns the number of characters changed. */)
2501 int len, oc; 2499 int len, oc;
2502 2500
2503 if (multibyte) 2501 if (multibyte)
2504 oc = STRING_CHAR_AND_LENGTH (p, len); 2502 oc = string_char_and_length (p, &len);
2505 else 2503 else
2506 oc = *p, len = 1; 2504 oc = *p, len = 1;
2507 if (oc < translatable_chars) 2505 if (oc < translatable_chars)
@@ -2518,7 +2516,7 @@ It returns the number of characters changed. */)
2518 if (string_multibyte) 2516 if (string_multibyte)
2519 { 2517 {
2520 str = tt + string_char_to_byte (table, oc); 2518 str = tt + string_char_to_byte (table, oc);
2521 nc = STRING_CHAR_AND_LENGTH (str, str_len); 2519 nc = string_char_and_length (str, &str_len);
2522 } 2520 }
2523 else 2521 else
2524 { 2522 {
diff --git a/src/fns.c b/src/fns.c
index e22fbaaedb9..cefdf389a54 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -226,12 +226,12 @@ Letter-case is significant, but text properties are ignored. */)
226 for (x = 1; x <= len2; x++) 226 for (x = 1; x <= len2; x++)
227 { 227 {
228 column[0] = x; 228 column[0] = x;
229 FETCH_STRING_CHAR_ADVANCE (c2, string2, i2, i2_byte); 229 c2 = fetch_string_char_advance (string2, &i2, &i2_byte);
230 i1 = i1_byte = 0; 230 i1 = i1_byte = 0;
231 for (y = 1, lastdiag = x - 1; y <= len1; y++) 231 for (y = 1, lastdiag = x - 1; y <= len1; y++)
232 { 232 {
233 olddiag = column[y]; 233 olddiag = column[y];
234 FETCH_STRING_CHAR_ADVANCE (c1, string1, i1, i1_byte); 234 c1 = fetch_string_char_advance (string1, &i1, &i1_byte);
235 column[y] = min (min (column[y] + 1, column[y-1] + 1), 235 column[y] = min (min (column[y] + 1, column[y-1] + 1),
236 lastdiag + (c1 == c2 ? 0 : 1)); 236 lastdiag + (c1 == c2 ? 0 : 1));
237 lastdiag = olddiag; 237 lastdiag = olddiag;
@@ -312,10 +312,8 @@ If string STR1 is greater, the value is a positive number N;
312 { 312 {
313 /* When we find a mismatch, we must compare the 313 /* When we find a mismatch, we must compare the
314 characters, not just the bytes. */ 314 characters, not just the bytes. */
315 int c1, c2; 315 int c1 = fetch_string_char_as_multibyte_advance (str1, &i1, &i1_byte);
316 316 int c2 = fetch_string_char_as_multibyte_advance (str2, &i2, &i2_byte);
317 FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE (c1, str1, i1, i1_byte);
318 FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE (c2, str2, i2, i2_byte);
319 317
320 if (c1 == c2) 318 if (c1 == c2)
321 continue; 319 continue;
@@ -350,11 +348,8 @@ DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0,
350 doc: /* Return non-nil if STRING1 is less than STRING2 in lexicographic order. 348 doc: /* Return non-nil if STRING1 is less than STRING2 in lexicographic order.
351Case is significant. 349Case is significant.
352Symbols are also allowed; their print names are used instead. */) 350Symbols are also allowed; their print names are used instead. */)
353 (register Lisp_Object string1, Lisp_Object string2) 351 (Lisp_Object string1, Lisp_Object string2)
354{ 352{
355 register ptrdiff_t end;
356 register ptrdiff_t i1, i1_byte, i2, i2_byte;
357
358 if (SYMBOLP (string1)) 353 if (SYMBOLP (string1))
359 string1 = SYMBOL_NAME (string1); 354 string1 = SYMBOL_NAME (string1);
360 if (SYMBOLP (string2)) 355 if (SYMBOLP (string2))
@@ -362,21 +357,15 @@ Symbols are also allowed; their print names are used instead. */)
362 CHECK_STRING (string1); 357 CHECK_STRING (string1);
363 CHECK_STRING (string2); 358 CHECK_STRING (string2);
364 359
365 i1 = i1_byte = i2 = i2_byte = 0; 360 ptrdiff_t i1 = 0, i1_byte = 0, i2 = 0, i2_byte = 0;
366 361 ptrdiff_t end = min (SCHARS (string1), SCHARS (string2));
367 end = SCHARS (string1);
368 if (end > SCHARS (string2))
369 end = SCHARS (string2);
370 362
371 while (i1 < end) 363 while (i1 < end)
372 { 364 {
373 /* When we find a mismatch, we must compare the 365 /* When we find a mismatch, we must compare the
374 characters, not just the bytes. */ 366 characters, not just the bytes. */
375 int c1, c2; 367 int c1 = fetch_string_char_advance (string1, &i1, &i1_byte);
376 368 int c2 = fetch_string_char_advance (string2, &i2, &i2_byte);
377 FETCH_STRING_CHAR_ADVANCE (c1, string1, i1, i1_byte);
378 FETCH_STRING_CHAR_ADVANCE (c2, string2, i2, i2_byte);
379
380 if (c1 != c2) 369 if (c1 != c2)
381 return c1 < c2 ? Qt : Qnil; 370 return c1 < c2 ? Qt : Qnil;
382 } 371 }
@@ -767,8 +756,8 @@ concat (ptrdiff_t nargs, Lisp_Object *args,
767 { 756 {
768 Lisp_Object thislen; 757 Lisp_Object thislen;
769 ptrdiff_t thisleni = 0; 758 ptrdiff_t thisleni = 0;
770 register ptrdiff_t thisindex = 0; 759 ptrdiff_t thisindex = 0;
771 register ptrdiff_t thisindex_byte = 0; 760 ptrdiff_t thisindex_byte = 0;
772 761
773 this = args[argnum]; 762 this = args[argnum];
774 if (!CONSP (this)) 763 if (!CONSP (this))
@@ -821,9 +810,8 @@ concat (ptrdiff_t nargs, Lisp_Object *args,
821 { 810 {
822 int c; 811 int c;
823 if (STRING_MULTIBYTE (this)) 812 if (STRING_MULTIBYTE (this))
824 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, this, 813 c = fetch_string_char_advance_no_check (this, &thisindex,
825 thisindex, 814 &thisindex_byte);
826 thisindex_byte);
827 else 815 else
828 { 816 {
829 c = SREF (this, thisindex); thisindex++; 817 c = SREF (this, thisindex); thisindex++;
@@ -1961,9 +1949,7 @@ See also the function `nreverse', which is used more often. */)
1961 p = SDATA (seq), q = SDATA (new) + bytes; 1949 p = SDATA (seq), q = SDATA (new) + bytes;
1962 while (q > SDATA (new)) 1950 while (q > SDATA (new))
1963 { 1951 {
1964 int ch, len; 1952 int len, ch = string_char_and_length (p, &len);
1965
1966 ch = STRING_CHAR_AND_LENGTH (p, len);
1967 p += len, q -= len; 1953 p += len, q -= len;
1968 CHAR_STRING (ch, q); 1954 CHAR_STRING (ch, q);
1969 } 1955 }
@@ -2641,10 +2627,8 @@ mapcar1 (EMACS_INT leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq)
2641 2627
2642 for (i = 0, i_byte = 0; i < leni;) 2628 for (i = 0, i_byte = 0; i < leni;)
2643 { 2629 {
2644 int c;
2645 ptrdiff_t i_before = i; 2630 ptrdiff_t i_before = i;
2646 2631 int c = fetch_string_char_advance (seq, &i, &i_byte);
2647 FETCH_STRING_CHAR_ADVANCE (c, seq, i, i_byte);
2648 XSETFASTINT (dummy, c); 2632 XSETFASTINT (dummy, c);
2649 dummy = call1 (fn, dummy); 2633 dummy = call1 (fn, dummy);
2650 if (vals) 2634 if (vals)
@@ -3451,7 +3435,7 @@ base64_encode_1 (const char *from, char *to, ptrdiff_t length,
3451 { 3435 {
3452 if (multibyte) 3436 if (multibyte)
3453 { 3437 {
3454 c = STRING_CHAR_AND_LENGTH ((unsigned char *) from + i, bytes); 3438 c = string_char_and_length ((unsigned char *) from + i, &bytes);
3455 if (CHAR_BYTE8_P (c)) 3439 if (CHAR_BYTE8_P (c))
3456 c = CHAR_TO_BYTE8 (c); 3440 c = CHAR_TO_BYTE8 (c);
3457 else if (c >= 256) 3441 else if (c >= 256)
@@ -3494,7 +3478,7 @@ base64_encode_1 (const char *from, char *to, ptrdiff_t length,
3494 3478
3495 if (multibyte) 3479 if (multibyte)
3496 { 3480 {
3497 c = STRING_CHAR_AND_LENGTH ((unsigned char *) from + i, bytes); 3481 c = string_char_and_length ((unsigned char *) from + i, &bytes);
3498 if (CHAR_BYTE8_P (c)) 3482 if (CHAR_BYTE8_P (c))
3499 c = CHAR_TO_BYTE8 (c); 3483 c = CHAR_TO_BYTE8 (c);
3500 else if (c >= 256) 3484 else if (c >= 256)
@@ -3519,7 +3503,7 @@ base64_encode_1 (const char *from, char *to, ptrdiff_t length,
3519 3503
3520 if (multibyte) 3504 if (multibyte)
3521 { 3505 {
3522 c = STRING_CHAR_AND_LENGTH ((unsigned char *) from + i, bytes); 3506 c = string_char_and_length ((unsigned char *) from + i, &bytes);
3523 if (CHAR_BYTE8_P (c)) 3507 if (CHAR_BYTE8_P (c))
3524 c = CHAR_TO_BYTE8 (c); 3508 c = CHAR_TO_BYTE8 (c);
3525 else if (c >= 256) 3509 else if (c >= 256)
diff --git a/src/font.c b/src/font.c
index 0c9e752e089..ab00402b40b 100644
--- a/src/font.c
+++ b/src/font.c
@@ -3856,13 +3856,10 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit,
3856 3856
3857 while (pos < *limit) 3857 while (pos < *limit)
3858 { 3858 {
3859 Lisp_Object category; 3859 c = (NILP (string)
3860 3860 ? fetch_char_advance_no_check (&pos, &pos_byte)
3861 if (NILP (string)) 3861 : fetch_string_char_advance_no_check (string, &pos, &pos_byte));
3862 FETCH_CHAR_ADVANCE_NO_CHECK (c, pos, pos_byte); 3862 Lisp_Object category = CHAR_TABLE_REF (Vunicode_category_table, c);
3863 else
3864 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, pos, pos_byte);
3865 category = CHAR_TABLE_REF (Vunicode_category_table, c);
3866 if (FIXNUMP (category) 3863 if (FIXNUMP (category)
3867 && (XFIXNUM (category) == UNICODE_CATEGORY_Cf 3864 && (XFIXNUM (category) == UNICODE_CATEGORY_Cf
3868 || CHAR_VARIATION_SELECTOR_P (c))) 3865 || CHAR_VARIATION_SELECTOR_P (c)))
@@ -4891,7 +4888,7 @@ the corresponding element is nil. */)
4891 Lisp_Object object) 4888 Lisp_Object object)
4892{ 4889{
4893 struct font *font = CHECK_FONT_GET_OBJECT (font_object); 4890 struct font *font = CHECK_FONT_GET_OBJECT (font_object);
4894 ptrdiff_t i, len; 4891 ptrdiff_t len;
4895 Lisp_Object *chars, vec; 4892 Lisp_Object *chars, vec;
4896 USE_SAFE_ALLOCA; 4893 USE_SAFE_ALLOCA;
4897 4894
@@ -4906,10 +4903,9 @@ the corresponding element is nil. */)
4906 SAFE_ALLOCA_LISP (chars, len); 4903 SAFE_ALLOCA_LISP (chars, len);
4907 charpos = XFIXNAT (from); 4904 charpos = XFIXNAT (from);
4908 bytepos = CHAR_TO_BYTE (charpos); 4905 bytepos = CHAR_TO_BYTE (charpos);
4909 for (i = 0; charpos < XFIXNAT (to); i++) 4906 for (ptrdiff_t i = 0; charpos < XFIXNAT (to); i++)
4910 { 4907 {
4911 int c; 4908 int c = fetch_char_advance (&charpos, &bytepos);
4912 FETCH_CHAR_ADVANCE (c, charpos, bytepos);
4913 chars[i] = make_fixnum (c); 4909 chars[i] = make_fixnum (c);
4914 } 4910 }
4915 } 4911 }
@@ -4929,18 +4925,18 @@ the corresponding element is nil. */)
4929 int c; 4925 int c;
4930 4926
4931 /* Skip IFROM characters from the beginning. */ 4927 /* Skip IFROM characters from the beginning. */
4932 for (i = 0; i < ifrom; i++) 4928 for (ptrdiff_t i = 0; i < ifrom; i++)
4933 c = STRING_CHAR_ADVANCE (p); 4929 p += BYTES_BY_CHAR_HEAD (*p);
4934 4930
4935 /* Now fetch an interesting characters. */ 4931 /* Now fetch an interesting characters. */
4936 for (i = 0; i < len; i++) 4932 for (ptrdiff_t i = 0; i < len; i++)
4937 { 4933 {
4938 c = STRING_CHAR_ADVANCE (p); 4934 c = string_char_advance (&p);
4939 chars[i] = make_fixnum (c); 4935 chars[i] = make_fixnum (c);
4940 } 4936 }
4941 } 4937 }
4942 else 4938 else
4943 for (i = 0; i < len; i++) 4939 for (ptrdiff_t i = 0; i < len; i++)
4944 chars[i] = make_fixnum (p[ifrom + i]); 4940 chars[i] = make_fixnum (p[ifrom + i]);
4945 } 4941 }
4946 else if (VECTORP (object)) 4942 else if (VECTORP (object))
@@ -4951,7 +4947,7 @@ the corresponding element is nil. */)
4951 if (ifrom == ito) 4947 if (ifrom == ito)
4952 return Qnil; 4948 return Qnil;
4953 len = ito - ifrom; 4949 len = ito - ifrom;
4954 for (i = 0; i < len; i++) 4950 for (ptrdiff_t i = 0; i < len; i++)
4955 { 4951 {
4956 Lisp_Object elt = AREF (object, ifrom + i); 4952 Lisp_Object elt = AREF (object, ifrom + i);
4957 CHECK_CHARACTER (elt); 4953 CHECK_CHARACTER (elt);
@@ -4962,7 +4958,7 @@ the corresponding element is nil. */)
4962 wrong_type_argument (Qarrayp, object); 4958 wrong_type_argument (Qarrayp, object);
4963 4959
4964 vec = make_uninit_vector (len); 4960 vec = make_uninit_vector (len);
4965 for (i = 0; i < len; i++) 4961 for (ptrdiff_t i = 0; i < len; i++)
4966 { 4962 {
4967 Lisp_Object g; 4963 Lisp_Object g;
4968 int c = XFIXNAT (chars[i]); 4964 int c = XFIXNAT (chars[i]);
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index a0e18e13cfa..7832d4f5ce0 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -328,14 +328,13 @@ ftcrfont_encode_char (struct font *font, int c)
328 struct font_info *ftcrfont_info = (struct font_info *) font; 328 struct font_info *ftcrfont_info = (struct font_info *) font;
329 unsigned code = FONT_INVALID_CODE; 329 unsigned code = FONT_INVALID_CODE;
330 unsigned char utf8[MAX_MULTIBYTE_LENGTH]; 330 unsigned char utf8[MAX_MULTIBYTE_LENGTH];
331 unsigned char *p = utf8; 331 int utf8len = CHAR_STRING (c, utf8);
332 cairo_glyph_t stack_glyph; 332 cairo_glyph_t stack_glyph;
333 cairo_glyph_t *glyphs = &stack_glyph; 333 cairo_glyph_t *glyphs = &stack_glyph;
334 int num_glyphs = 1; 334 int num_glyphs = 1;
335 335
336 CHAR_STRING_ADVANCE (c, p);
337 if (cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font, 0, 0, 336 if (cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font, 0, 0,
338 (char *) utf8, p - utf8, 337 (char *) utf8, utf8len,
339 &glyphs, &num_glyphs, 338 &glyphs, &num_glyphs,
340 NULL, NULL, NULL) 339 NULL, NULL, NULL)
341 == CAIRO_STATUS_SUCCESS) 340 == CAIRO_STATUS_SUCCESS)
diff --git a/src/indent.c b/src/indent.c
index 06f11a251e6..c0b4c13b2c5 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -285,9 +285,7 @@ skip_invisible (ptrdiff_t pos, ptrdiff_t *next_boundary_p, ptrdiff_t to, Lisp_Ob
285 285
286#define MULTIBYTE_BYTES_WIDTH(p, dp, bytes, width) \ 286#define MULTIBYTE_BYTES_WIDTH(p, dp, bytes, width) \
287 do { \ 287 do { \
288 int ch; \ 288 int ch = string_char_and_length (p, &(bytes)); \
289 \
290 ch = STRING_CHAR_AND_LENGTH (p, bytes); \
291 if (BYTES_BY_CHAR_HEAD (*p) != bytes) \ 289 if (BYTES_BY_CHAR_HEAD (*p) != bytes) \
292 width = bytes * 4; \ 290 width = bytes * 4; \
293 else \ 291 else \
@@ -942,7 +940,7 @@ position_indentation (ptrdiff_t pos_byte)
942 if (CHAR_HAS_CATEGORY (c, ' ')) 940 if (CHAR_HAS_CATEGORY (c, ' '))
943 { 941 {
944 column++; 942 column++;
945 INC_POS (pos_byte); 943 pos_byte += next_char_len (pos_byte);
946 p = BYTE_POS_ADDR (pos_byte); 944 p = BYTE_POS_ADDR (pos_byte);
947 } 945 }
948 else 946 else
@@ -961,7 +959,7 @@ indented_beyond_p (ptrdiff_t pos, ptrdiff_t pos_byte, EMACS_INT column)
961{ 959{
962 while (pos > BEGV && FETCH_BYTE (pos_byte) == '\n') 960 while (pos > BEGV && FETCH_BYTE (pos_byte) == '\n')
963 { 961 {
964 DEC_BOTH (pos, pos_byte); 962 dec_both (&pos, &pos_byte);
965 pos = find_newline (pos, pos_byte, BEGV, BEGV_BYTE, 963 pos = find_newline (pos, pos_byte, BEGV, BEGV_BYTE,
966 -1, NULL, &pos_byte, 0); 964 -1, NULL, &pos_byte, 0);
967 } 965 }
@@ -1010,7 +1008,7 @@ The return value is the current column. */)
1010 int c; 1008 int c;
1011 ptrdiff_t pos_byte = PT_BYTE; 1009 ptrdiff_t pos_byte = PT_BYTE;
1012 1010
1013 DEC_POS (pos_byte); 1011 pos_byte -= prev_char_len (pos_byte);
1014 c = FETCH_CHAR (pos_byte); 1012 c = FETCH_CHAR (pos_byte);
1015 if (c == '\t' && prev_col < goal) 1013 if (c == '\t' && prev_col < goal)
1016 { 1014 {
@@ -1605,7 +1603,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos,
1605 { 1603 {
1606 pos = find_before_next_newline (pos, to, 1, &pos_byte); 1604 pos = find_before_next_newline (pos, to, 1, &pos_byte);
1607 if (pos < to) 1605 if (pos < to)
1608 INC_BOTH (pos, pos_byte); 1606 inc_both (&pos, &pos_byte);
1609 rarely_quit (++quit_count); 1607 rarely_quit (++quit_count);
1610 } 1608 }
1611 while (pos < to 1609 while (pos < to
@@ -1618,7 +1616,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos,
1618 if (hpos >= width) 1616 if (hpos >= width)
1619 hpos = width; 1617 hpos = width;
1620 } 1618 }
1621 DEC_BOTH (pos, pos_byte); 1619 dec_both (&pos, &pos_byte);
1622 /* We have skipped the invis text, but not the 1620 /* We have skipped the invis text, but not the
1623 newline after. */ 1621 newline after. */
1624 } 1622 }
@@ -1820,8 +1818,8 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */)
1820static struct position val_vmotion; 1818static struct position val_vmotion;
1821 1819
1822struct position * 1820struct position *
1823vmotion (register ptrdiff_t from, register ptrdiff_t from_byte, 1821vmotion (ptrdiff_t from, ptrdiff_t from_byte,
1824 register EMACS_INT vtarget, struct window *w) 1822 EMACS_INT vtarget, struct window *w)
1825{ 1823{
1826 ptrdiff_t hscroll = w->hscroll; 1824 ptrdiff_t hscroll = w->hscroll;
1827 struct position pos; 1825 struct position pos;
@@ -1862,7 +1860,7 @@ vmotion (register ptrdiff_t from, register ptrdiff_t from_byte,
1862 Lisp_Object propval; 1860 Lisp_Object propval;
1863 1861
1864 prevline = from; 1862 prevline = from;
1865 DEC_BOTH (prevline, bytepos); 1863 dec_both (&prevline, &bytepos);
1866 prevline = find_newline_no_quit (prevline, bytepos, -1, &bytepos); 1864 prevline = find_newline_no_quit (prevline, bytepos, -1, &bytepos);
1867 1865
1868 while (prevline > BEGV 1866 while (prevline > BEGV
@@ -1875,7 +1873,7 @@ vmotion (register ptrdiff_t from, register ptrdiff_t from_byte,
1875 text_prop_object), 1873 text_prop_object),
1876 TEXT_PROP_MEANS_INVISIBLE (propval)))) 1874 TEXT_PROP_MEANS_INVISIBLE (propval))))
1877 { 1875 {
1878 DEC_BOTH (prevline, bytepos); 1876 dec_both (&prevline, &bytepos);
1879 prevline = find_newline_no_quit (prevline, bytepos, -1, &bytepos); 1877 prevline = find_newline_no_quit (prevline, bytepos, -1, &bytepos);
1880 } 1878 }
1881 pos = *compute_motion (prevline, bytepos, 0, lmargin, 0, from, 1879 pos = *compute_motion (prevline, bytepos, 0, lmargin, 0, from,
@@ -1925,7 +1923,7 @@ vmotion (register ptrdiff_t from, register ptrdiff_t from_byte,
1925 text_prop_object), 1923 text_prop_object),
1926 TEXT_PROP_MEANS_INVISIBLE (propval)))) 1924 TEXT_PROP_MEANS_INVISIBLE (propval))))
1927 { 1925 {
1928 DEC_BOTH (prevline, bytepos); 1926 dec_both (&prevline, &bytepos);
1929 prevline = find_newline_no_quit (prevline, bytepos, -1, &bytepos); 1927 prevline = find_newline_no_quit (prevline, bytepos, -1, &bytepos);
1930 } 1928 }
1931 pos = *compute_motion (prevline, bytepos, 0, lmargin, 0, from, 1929 pos = *compute_motion (prevline, bytepos, 0, lmargin, 0, from,
diff --git a/src/insdel.c b/src/insdel.c
index dfa1cc311ca..c37b0710783 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -382,10 +382,10 @@ count_bytes (ptrdiff_t pos, ptrdiff_t bytepos, ptrdiff_t endpos)
382 382
383 if (pos <= endpos) 383 if (pos <= endpos)
384 for ( ; pos < endpos; pos++) 384 for ( ; pos < endpos; pos++)
385 INC_POS (bytepos); 385 bytepos += next_char_len (bytepos);
386 else 386 else
387 for ( ; pos > endpos; pos--) 387 for ( ; pos > endpos; pos--)
388 DEC_POS (bytepos); 388 bytepos -= prev_char_len (bytepos);
389 389
390 return bytepos; 390 return bytepos;
391} 391}
@@ -626,8 +626,7 @@ copy_text (const unsigned char *from_addr, unsigned char *to_addr,
626 626
627 while (bytes_left > 0) 627 while (bytes_left > 0)
628 { 628 {
629 int thislen, c; 629 int thislen, c = string_char_and_length (from_addr, &thislen);
630 c = STRING_CHAR_AND_LENGTH (from_addr, thislen);
631 if (! ASCII_CHAR_P (c)) 630 if (! ASCII_CHAR_P (c))
632 c &= 0xFF; 631 c &= 0xFF;
633 *to_addr++ = c; 632 *to_addr++ = c;
diff --git a/src/keyboard.c b/src/keyboard.c
index b4e62c3bb49..c94d794b013 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -2279,7 +2279,7 @@ read_decoded_event_from_main_queue (struct timespec *end_time,
2279 eassert (coding->carryover_bytes == 0); 2279 eassert (coding->carryover_bytes == 0);
2280 n = 0; 2280 n = 0;
2281 while (n < coding->produced_char) 2281 while (n < coding->produced_char)
2282 events[n++] = make_fixnum (STRING_CHAR_ADVANCE (p)); 2282 events[n++] = make_fixnum (string_char_advance (&p));
2283 } 2283 }
2284 } 2284 }
2285 } 2285 }
@@ -10466,9 +10466,8 @@ Internal use only. */)
10466 this_command_key_count = 0; 10466 this_command_key_count = 0;
10467 this_single_command_key_start = 0; 10467 this_single_command_key_start = 0;
10468 10468
10469 int charidx = 0, byteidx = 0; 10469 ptrdiff_t charidx = 0, byteidx = 0;
10470 int key0; 10470 int key0 = fetch_string_char_advance (keys, &charidx, &byteidx);
10471 FETCH_STRING_CHAR_ADVANCE (key0, keys, charidx, byteidx);
10472 if (CHAR_BYTE8_P (key0)) 10471 if (CHAR_BYTE8_P (key0))
10473 key0 = CHAR_TO_BYTE8 (key0); 10472 key0 = CHAR_TO_BYTE8 (key0);
10474 10473
@@ -10480,8 +10479,7 @@ Internal use only. */)
10480 add_command_key (make_fixnum (key0)); 10479 add_command_key (make_fixnum (key0));
10481 for (ptrdiff_t i = 1; i < SCHARS (keys); i++) 10480 for (ptrdiff_t i = 1; i < SCHARS (keys); i++)
10482 { 10481 {
10483 int key_i; 10482 int key_i = fetch_string_char_advance (keys, &charidx, &byteidx);
10484 FETCH_STRING_CHAR_ADVANCE (key_i, keys, charidx, byteidx);
10485 if (CHAR_BYTE8_P (key_i)) 10483 if (CHAR_BYTE8_P (key_i))
10486 key_i = CHAR_TO_BYTE8 (key_i); 10484 key_i = CHAR_TO_BYTE8 (key_i);
10487 add_command_key (make_fixnum (key_i)); 10485 add_command_key (make_fixnum (key_i));
diff --git a/src/keymap.c b/src/keymap.c
index cfba98c72f2..8a6881a54e6 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -1949,8 +1949,7 @@ then the value includes only maps for prefixes that start with PREFIX. */)
1949 for (ptrdiff_t i = 0; i < SCHARS (prefix); ) 1949 for (ptrdiff_t i = 0; i < SCHARS (prefix); )
1950 { 1950 {
1951 ptrdiff_t i_before = i; 1951 ptrdiff_t i_before = i;
1952 int c; 1952 int c = fetch_string_char_advance (prefix, &i, &i_byte);
1953 FETCH_STRING_CHAR_ADVANCE (c, prefix, i, i_byte);
1954 if (SINGLE_BYTE_CHAR_P (c) && (c & 0200)) 1953 if (SINGLE_BYTE_CHAR_P (c) && (c & 0200))
1955 c ^= 0200 | meta_modifier; 1954 c ^= 0200 | meta_modifier;
1956 ASET (copy, i_before, make_fixnum (c)); 1955 ASET (copy, i_before, make_fixnum (c));
@@ -2065,8 +2064,7 @@ For an approximate inverse of this, see `kbd'. */)
2065 { 2064 {
2066 if (STRINGP (list)) 2065 if (STRINGP (list))
2067 { 2066 {
2068 int c; 2067 int c = fetch_string_char_advance (list, &i, &i_byte);
2069 FETCH_STRING_CHAR_ADVANCE (c, list, i, i_byte);
2070 if (SINGLE_BYTE_CHAR_P (c) && (c & 0200)) 2068 if (SINGLE_BYTE_CHAR_P (c) && (c & 0200))
2071 c ^= 0200 | meta_modifier; 2069 c ^= 0200 | meta_modifier;
2072 XSETFASTINT (key, c); 2070 XSETFASTINT (key, c);
diff --git a/src/lread.c b/src/lread.c
index 8ec9e325049..c6607a8935f 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -225,8 +225,9 @@ readchar (Lisp_Object readcharfun, bool *multibyte)
225 { 225 {
226 /* Fetch the character code from the buffer. */ 226 /* Fetch the character code from the buffer. */
227 unsigned char *p = BUF_BYTE_ADDRESS (inbuffer, pt_byte); 227 unsigned char *p = BUF_BYTE_ADDRESS (inbuffer, pt_byte);
228 BUF_INC_POS (inbuffer, pt_byte); 228 int clen;
229 c = STRING_CHAR (p); 229 c = string_char_and_length (p, &clen);
230 pt_byte += clen;
230 if (multibyte) 231 if (multibyte)
231 *multibyte = 1; 232 *multibyte = 1;
232 } 233 }
@@ -254,8 +255,9 @@ readchar (Lisp_Object readcharfun, bool *multibyte)
254 { 255 {
255 /* Fetch the character code from the buffer. */ 256 /* Fetch the character code from the buffer. */
256 unsigned char *p = BUF_BYTE_ADDRESS (inbuffer, bytepos); 257 unsigned char *p = BUF_BYTE_ADDRESS (inbuffer, bytepos);
257 BUF_INC_POS (inbuffer, bytepos); 258 int clen;
258 c = STRING_CHAR (p); 259 c = string_char_and_length (p, &clen);
260 bytepos += clen;
259 if (multibyte) 261 if (multibyte)
260 *multibyte = 1; 262 *multibyte = 1;
261 } 263 }
@@ -294,9 +296,10 @@ readchar (Lisp_Object readcharfun, bool *multibyte)
294 { 296 {
295 if (multibyte) 297 if (multibyte)
296 *multibyte = 1; 298 *multibyte = 1;
297 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, readcharfun, 299 c = (fetch_string_char_advance_no_check
298 read_from_string_index, 300 (readcharfun,
299 read_from_string_index_byte); 301 &read_from_string_index,
302 &read_from_string_index_byte));
300 } 303 }
301 else 304 else
302 { 305 {
@@ -427,7 +430,7 @@ unreadchar (Lisp_Object readcharfun, int c)
427 ptrdiff_t bytepos = BUF_PT_BYTE (b); 430 ptrdiff_t bytepos = BUF_PT_BYTE (b);
428 431
429 if (! NILP (BVAR (b, enable_multibyte_characters))) 432 if (! NILP (BVAR (b, enable_multibyte_characters)))
430 BUF_DEC_POS (b, bytepos); 433 bytepos -= buf_prev_char_len (b, bytepos);
431 else 434 else
432 bytepos--; 435 bytepos--;
433 436
@@ -440,7 +443,7 @@ unreadchar (Lisp_Object readcharfun, int c)
440 443
441 XMARKER (readcharfun)->charpos--; 444 XMARKER (readcharfun)->charpos--;
442 if (! NILP (BVAR (b, enable_multibyte_characters))) 445 if (! NILP (BVAR (b, enable_multibyte_characters)))
443 BUF_DEC_POS (b, bytepos); 446 bytepos -= buf_prev_char_len (b, bytepos);
444 else 447 else
445 bytepos--; 448 bytepos--;
446 449
@@ -526,13 +529,11 @@ readbyte_from_string (int c, Lisp_Object readcharfun)
526 = string_char_to_byte (string, read_from_string_index); 529 = string_char_to_byte (string, read_from_string_index);
527 } 530 }
528 531
529 if (read_from_string_index >= read_from_string_limit) 532 return (read_from_string_index < read_from_string_limit
530 c = -1; 533 ? fetch_string_char_advance (string,
531 else 534 &read_from_string_index,
532 FETCH_STRING_CHAR_ADVANCE (c, string, 535 &read_from_string_index_byte)
533 read_from_string_index, 536 : -1);
534 read_from_string_index_byte);
535 return c;
536} 537}
537 538
538 539
diff --git a/src/marker.c b/src/marker.c
index 684b7509c51..64f210db88b 100644
--- a/src/marker.c
+++ b/src/marker.c
@@ -221,7 +221,7 @@ buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos)
221 while (best_below != charpos) 221 while (best_below != charpos)
222 { 222 {
223 best_below++; 223 best_below++;
224 BUF_INC_POS (b, best_below_byte); 224 best_below_byte += buf_next_char_len (b, best_below_byte);
225 } 225 }
226 226
227 /* If this position is quite far from the nearest known position, 227 /* If this position is quite far from the nearest known position,
@@ -246,7 +246,7 @@ buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos)
246 while (best_above != charpos) 246 while (best_above != charpos)
247 { 247 {
248 best_above--; 248 best_above--;
249 BUF_DEC_POS (b, best_above_byte); 249 best_above_byte -= buf_prev_char_len (b, best_above_byte);
250 } 250 }
251 251
252 /* If this position is quite far from the nearest known position, 252 /* If this position is quite far from the nearest known position,
@@ -372,7 +372,7 @@ buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos)
372 while (best_below_byte < bytepos) 372 while (best_below_byte < bytepos)
373 { 373 {
374 best_below++; 374 best_below++;
375 BUF_INC_POS (b, best_below_byte); 375 best_below_byte += buf_next_char_len (b, best_below_byte);
376 } 376 }
377 377
378 /* If this position is quite far from the nearest known position, 378 /* If this position is quite far from the nearest known position,
@@ -399,7 +399,7 @@ buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos)
399 while (best_above_byte > bytepos) 399 while (best_above_byte > bytepos)
400 { 400 {
401 best_above--; 401 best_above--;
402 BUF_DEC_POS (b, best_above_byte); 402 best_above_byte -= buf_prev_char_len (b, best_above_byte);
403 } 403 }
404 404
405 /* If this position is quite far from the nearest known position, 405 /* If this position is quite far from the nearest known position,
@@ -804,7 +804,7 @@ verify_bytepos (ptrdiff_t charpos)
804 while (below != charpos) 804 while (below != charpos)
805 { 805 {
806 below++; 806 below++;
807 BUF_INC_POS (current_buffer, below_byte); 807 below_byte += buf_next_char_len (current_buffer, below_byte);
808 } 808 }
809 809
810 return below_byte; 810 return below_byte;
diff --git a/src/menu.c b/src/menu.c
index 6b8b5dd1210..e4fda572cd8 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -1036,9 +1036,7 @@ menu_item_width (const unsigned char *str)
1036 1036
1037 for (len = 0, p = str; *p; ) 1037 for (len = 0, p = str; *p; )
1038 { 1038 {
1039 int ch_len; 1039 int ch_len, ch = string_char_and_length (p, &ch_len);
1040 int ch = STRING_CHAR_AND_LENGTH (p, ch_len);
1041
1042 len += CHARACTER_WIDTH (ch); 1040 len += CHARACTER_WIDTH (ch);
1043 p += ch_len; 1041 p += ch_len;
1044 } 1042 }
diff --git a/src/msdos.c b/src/msdos.c
index a09b3ba7924..b5f06c99c3d 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -2905,7 +2905,7 @@ IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
2905 p++; 2905 p++;
2906 for (j = 0, q = menu->text[i]; *q; j++) 2906 for (j = 0, q = menu->text[i]; *q; j++)
2907 { 2907 {
2908 unsigned c = STRING_CHAR_ADVANCE (q); 2908 unsigned c = string_char_advance (&q);
2909 2909
2910 if (c > 26) 2910 if (c > 26)
2911 { 2911 {
diff --git a/src/nsfont.m b/src/nsfont.m
index e41a698a2ff..691becda6da 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -1090,7 +1090,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1090 twidth += cwidth; 1090 twidth += cwidth;
1091#ifdef NS_IMPL_GNUSTEP 1091#ifdef NS_IMPL_GNUSTEP
1092 *adv++ = cwidth; 1092 *adv++ = cwidth;
1093 CHAR_STRING_ADVANCE (*t, c); /* This converts the char to UTF-8. */ 1093 c += CHAR_STRING (*t, c); /* This converts the char to UTF-8. */
1094#else 1094#else
1095 (*adv++).width = cwidth; 1095 (*adv++).width = cwidth;
1096#endif 1096#endif
diff --git a/src/print.c b/src/print.c
index 634169dbdbd..bd1769144e0 100644
--- a/src/print.c
+++ b/src/print.c
@@ -368,8 +368,8 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte,
368 int len; 368 int len;
369 for (ptrdiff_t i = 0; i < size_byte; i += len) 369 for (ptrdiff_t i = 0; i < size_byte; i += len)
370 { 370 {
371 int ch = STRING_CHAR_AND_LENGTH ((const unsigned char *) ptr + i, 371 int ch = string_char_and_length ((const unsigned char *) ptr + i,
372 len); 372 &len);
373 printchar_to_stream (ch, stdout); 373 printchar_to_stream (ch, stdout);
374 } 374 }
375 } 375 }
@@ -400,8 +400,8 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte,
400 int len; 400 int len;
401 for (i = 0; i < size_byte; i += len) 401 for (i = 0; i < size_byte; i += len)
402 { 402 {
403 int ch = STRING_CHAR_AND_LENGTH ((const unsigned char *) ptr + i, 403 int ch = string_char_and_length ((const unsigned char *) ptr + i,
404 len); 404 &len);
405 insert_char (ch); 405 insert_char (ch);
406 } 406 }
407 } 407 }
@@ -426,9 +426,8 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte,
426 /* Here, we must convert each multi-byte form to the 426 /* Here, we must convert each multi-byte form to the
427 corresponding character code before handing it to 427 corresponding character code before handing it to
428 PRINTCHAR. */ 428 PRINTCHAR. */
429 int len; 429 int len, ch = (string_char_and_length
430 int ch = STRING_CHAR_AND_LENGTH ((const unsigned char *) ptr + i, 430 ((const unsigned char *) ptr + i, &len));
431 len);
432 printchar (ch, printcharfun); 431 printchar (ch, printcharfun);
433 i += len; 432 i += len;
434 } 433 }
@@ -510,8 +509,7 @@ print_string (Lisp_Object string, Lisp_Object printcharfun)
510 { 509 {
511 /* Here, we must convert each multi-byte form to the 510 /* Here, we must convert each multi-byte form to the
512 corresponding character code before handing it to PRINTCHAR. */ 511 corresponding character code before handing it to PRINTCHAR. */
513 int len; 512 int len, ch = string_char_and_length (SDATA (string) + i, &len);
514 int ch = STRING_CHAR_AND_LENGTH (SDATA (string) + i, len);
515 printchar (ch, printcharfun); 513 printchar (ch, printcharfun);
516 i += len; 514 i += len;
517 } 515 }
@@ -1307,15 +1305,13 @@ print_check_string_charset_prop (INTERVAL interval, Lisp_Object string)
1307 } 1305 }
1308 if (! (print_check_string_result & PRINT_STRING_UNSAFE_CHARSET_FOUND)) 1306 if (! (print_check_string_result & PRINT_STRING_UNSAFE_CHARSET_FOUND))
1309 { 1307 {
1310 int i, c;
1311 ptrdiff_t charpos = interval->position; 1308 ptrdiff_t charpos = interval->position;
1312 ptrdiff_t bytepos = string_char_to_byte (string, charpos); 1309 ptrdiff_t bytepos = string_char_to_byte (string, charpos);
1313 Lisp_Object charset; 1310 Lisp_Object charset = XCAR (XCDR (val));
1314 1311
1315 charset = XCAR (XCDR (val)); 1312 for (ptrdiff_t i = 0; i < LENGTH (interval); i++)
1316 for (i = 0; i < LENGTH (interval); i++)
1317 { 1313 {
1318 FETCH_STRING_CHAR_ADVANCE (c, string, charpos, bytepos); 1314 int c = fetch_string_char_advance (string, &charpos, &bytepos);
1319 if (! ASCII_CHAR_P (c) 1315 if (! ASCII_CHAR_P (c)
1320 && ! EQ (CHARSET_NAME (CHAR_CHARSET (c)), charset)) 1316 && ! EQ (CHARSET_NAME (CHAR_CHARSET (c)), charset))
1321 { 1317 {
@@ -1943,9 +1939,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
1943 { 1939 {
1944 /* Here, we must convert each multi-byte form to the 1940 /* Here, we must convert each multi-byte form to the
1945 corresponding character code before handing it to printchar. */ 1941 corresponding character code before handing it to printchar. */
1946 int c; 1942 int c = fetch_string_char_advance (obj, &i, &i_byte);
1947
1948 FETCH_STRING_CHAR_ADVANCE (c, obj, i, i_byte);
1949 1943
1950 maybe_quit (); 1944 maybe_quit ();
1951 1945
@@ -2036,8 +2030,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
2036 { 2030 {
2037 /* Here, we must convert each multi-byte form to the 2031 /* Here, we must convert each multi-byte form to the
2038 corresponding character code before handing it to PRINTCHAR. */ 2032 corresponding character code before handing it to PRINTCHAR. */
2039 int c; 2033 int c = fetch_string_char_advance (name, &i, &i_byte);
2040 FETCH_STRING_CHAR_ADVANCE (c, name, i, i_byte);
2041 maybe_quit (); 2034 maybe_quit ();
2042 2035
2043 if (escapeflag) 2036 if (escapeflag)
diff --git a/src/regex-emacs.c b/src/regex-emacs.c
index 0ae004e4636..9fd23943402 100644
--- a/src/regex-emacs.c
+++ b/src/regex-emacs.c
@@ -58,7 +58,7 @@
58#define RE_STRING_CHAR(p, multibyte) \ 58#define RE_STRING_CHAR(p, multibyte) \
59 (multibyte ? STRING_CHAR (p) : *(p)) 59 (multibyte ? STRING_CHAR (p) : *(p))
60#define RE_STRING_CHAR_AND_LENGTH(p, len, multibyte) \ 60#define RE_STRING_CHAR_AND_LENGTH(p, len, multibyte) \
61 (multibyte ? STRING_CHAR_AND_LENGTH (p, len) : ((len) = 1, *(p))) 61 (multibyte ? string_char_and_length (p, &(len)) : ((len) = 1, *(p)))
62 62
63#define RE_CHAR_TO_MULTIBYTE(c) UNIBYTE_TO_CHAR (c) 63#define RE_CHAR_TO_MULTIBYTE(c) UNIBYTE_TO_CHAR (c)
64 64
@@ -89,7 +89,7 @@
89#define GET_CHAR_AFTER(c, p, len) \ 89#define GET_CHAR_AFTER(c, p, len) \
90 do { \ 90 do { \
91 if (target_multibyte) \ 91 if (target_multibyte) \
92 (c) = STRING_CHAR_AND_LENGTH (p, len); \ 92 (c) = string_char_and_length (p, &(len)); \
93 else \ 93 else \
94 { \ 94 { \
95 (c) = *p; \ 95 (c) = *p; \
@@ -3167,10 +3167,6 @@ re_search (struct re_pattern_buffer *bufp, const char *string, ptrdiff_t size,
3167 regs, size); 3167 regs, size);
3168} 3168}
3169 3169
3170/* Head address of virtual concatenation of string. */
3171#define HEAD_ADDR_VSTRING(P) \
3172 (((P) >= size1 ? string2 : string1))
3173
3174/* Address of POS in the concatenation of virtual string. */ 3170/* Address of POS in the concatenation of virtual string. */
3175#define POS_ADDR_VSTRING(POS) \ 3171#define POS_ADDR_VSTRING(POS) \
3176 (((POS) >= size1 ? string2 - size1 : string1) + (POS)) 3172 (((POS) >= size1 ? string2 - size1 : string1) + (POS))
@@ -3300,7 +3296,7 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, ptrdiff_t size1,
3300 { 3296 {
3301 int buf_charlen; 3297 int buf_charlen;
3302 3298
3303 buf_ch = STRING_CHAR_AND_LENGTH (d, buf_charlen); 3299 buf_ch = string_char_and_length (d, &buf_charlen);
3304 buf_ch = RE_TRANSLATE (translate, buf_ch); 3300 buf_ch = RE_TRANSLATE (translate, buf_ch);
3305 if (fastmap[CHAR_LEADING_CODE (buf_ch)]) 3301 if (fastmap[CHAR_LEADING_CODE (buf_ch)])
3306 break; 3302 break;
@@ -3330,7 +3326,7 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, ptrdiff_t size1,
3330 { 3326 {
3331 int buf_charlen; 3327 int buf_charlen;
3332 3328
3333 buf_ch = STRING_CHAR_AND_LENGTH (d, buf_charlen); 3329 buf_ch = string_char_and_length (d, &buf_charlen);
3334 if (fastmap[CHAR_LEADING_CODE (buf_ch)]) 3330 if (fastmap[CHAR_LEADING_CODE (buf_ch)])
3335 break; 3331 break;
3336 range -= buf_charlen; 3332 range -= buf_charlen;
@@ -3413,16 +3409,12 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, ptrdiff_t size1,
3413 if (multibyte) 3409 if (multibyte)
3414 { 3410 {
3415 re_char *p = POS_ADDR_VSTRING (startpos) + 1; 3411 re_char *p = POS_ADDR_VSTRING (startpos) + 1;
3416 re_char *p0 = p; 3412 int len = raw_prev_char_len (p);
3417 re_char *phead = HEAD_ADDR_VSTRING (startpos);
3418 3413
3419 /* Find the head of multibyte form. */ 3414 range += len - 1;
3420 PREV_CHAR_BOUNDARY (p, phead);
3421 range += p0 - 1 - p;
3422 if (range > 0) 3415 if (range > 0)
3423 break; 3416 break;
3424 3417 startpos -= len - 1;
3425 startpos -= p0 - 1 - p;
3426 } 3418 }
3427 } 3419 }
3428 } 3420 }
@@ -4218,13 +4210,13 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4218 4210
4219 PREFETCH (); 4211 PREFETCH ();
4220 if (multibyte) 4212 if (multibyte)
4221 pat_ch = STRING_CHAR_AND_LENGTH (p, pat_charlen); 4213 pat_ch = string_char_and_length (p, &pat_charlen);
4222 else 4214 else
4223 { 4215 {
4224 pat_ch = RE_CHAR_TO_MULTIBYTE (*p); 4216 pat_ch = RE_CHAR_TO_MULTIBYTE (*p);
4225 pat_charlen = 1; 4217 pat_charlen = 1;
4226 } 4218 }
4227 buf_ch = STRING_CHAR_AND_LENGTH (d, buf_charlen); 4219 buf_ch = string_char_and_length (d, &buf_charlen);
4228 4220
4229 if (TRANSLATE (buf_ch) != pat_ch) 4221 if (TRANSLATE (buf_ch) != pat_ch)
4230 { 4222 {
@@ -4246,7 +4238,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4246 PREFETCH (); 4238 PREFETCH ();
4247 if (multibyte) 4239 if (multibyte)
4248 { 4240 {
4249 pat_ch = STRING_CHAR_AND_LENGTH (p, pat_charlen); 4241 pat_ch = string_char_and_length (p, &pat_charlen);
4250 pat_ch = RE_CHAR_TO_UNIBYTE (pat_ch); 4242 pat_ch = RE_CHAR_TO_UNIBYTE (pat_ch);
4251 } 4243 }
4252 else 4244 else
diff --git a/src/search.c b/src/search.c
index 08b57c5faf3..567270a84cb 100644
--- a/src/search.c
+++ b/src/search.c
@@ -994,7 +994,7 @@ find_before_next_newline (ptrdiff_t from, ptrdiff_t to,
994 if (counted == cnt) 994 if (counted == cnt)
995 { 995 {
996 if (bytepos) 996 if (bytepos)
997 DEC_BOTH (pos, *bytepos); 997 dec_both (&pos, &*bytepos);
998 else 998 else
999 pos--; 999 pos--;
1000 } 1000 }
@@ -1353,8 +1353,8 @@ search_buffer_non_re (Lisp_Object string, ptrdiff_t pos,
1353 while (--len >= 0) 1353 while (--len >= 0)
1354 { 1354 {
1355 unsigned char str_base[MAX_MULTIBYTE_LENGTH], *str; 1355 unsigned char str_base[MAX_MULTIBYTE_LENGTH], *str;
1356 int c, translated, inverse; 1356 int translated, inverse;
1357 int in_charlen, charlen; 1357 int charlen;
1358 1358
1359 /* If we got here and the RE flag is set, it's because we're 1359 /* If we got here and the RE flag is set, it's because we're
1360 dealing with a regexp known to be trivial, so the backslash 1360 dealing with a regexp known to be trivial, so the backslash
@@ -1367,7 +1367,7 @@ search_buffer_non_re (Lisp_Object string, ptrdiff_t pos,
1367 base_pat++; 1367 base_pat++;
1368 } 1368 }
1369 1369
1370 c = STRING_CHAR_AND_LENGTH (base_pat, in_charlen); 1370 int in_charlen, c = string_char_and_length (base_pat, &in_charlen);
1371 1371
1372 if (NILP (trt)) 1372 if (NILP (trt))
1373 { 1373 {
@@ -1550,12 +1550,10 @@ simple_search (EMACS_INT n, unsigned char *pat,
1550 1550
1551 while (this_len > 0) 1551 while (this_len > 0)
1552 { 1552 {
1553 int charlen, buf_charlen; 1553 int charlen, pat_ch = string_char_and_length (p, &charlen);
1554 int pat_ch, buf_ch; 1554 int buf_charlen, buf_ch
1555 1555 = string_char_and_length (BYTE_POS_ADDR (this_pos_byte),
1556 pat_ch = STRING_CHAR_AND_LENGTH (p, charlen); 1556 &buf_charlen);
1557 buf_ch = STRING_CHAR_AND_LENGTH (BYTE_POS_ADDR (this_pos_byte),
1558 buf_charlen);
1559 TRANSLATE (buf_ch, trt, buf_ch); 1557 TRANSLATE (buf_ch, trt, buf_ch);
1560 1558
1561 if (buf_ch != pat_ch) 1559 if (buf_ch != pat_ch)
@@ -1576,7 +1574,7 @@ simple_search (EMACS_INT n, unsigned char *pat,
1576 break; 1574 break;
1577 } 1575 }
1578 1576
1579 INC_BOTH (pos, pos_byte); 1577 inc_both (&pos, &pos_byte);
1580 } 1578 }
1581 1579
1582 n--; 1580 n--;
@@ -1638,8 +1636,8 @@ simple_search (EMACS_INT n, unsigned char *pat,
1638 { 1636 {
1639 int pat_ch, buf_ch; 1637 int pat_ch, buf_ch;
1640 1638
1641 DEC_BOTH (this_pos, this_pos_byte); 1639 dec_both (&this_pos, &this_pos_byte);
1642 PREV_CHAR_BOUNDARY (p, pat); 1640 p -= raw_prev_char_len (p);
1643 pat_ch = STRING_CHAR (p); 1641 pat_ch = STRING_CHAR (p);
1644 buf_ch = STRING_CHAR (BYTE_POS_ADDR (this_pos_byte)); 1642 buf_ch = STRING_CHAR (BYTE_POS_ADDR (this_pos_byte));
1645 TRANSLATE (buf_ch, trt, buf_ch); 1643 TRANSLATE (buf_ch, trt, buf_ch);
@@ -1658,7 +1656,7 @@ simple_search (EMACS_INT n, unsigned char *pat,
1658 break; 1656 break;
1659 } 1657 }
1660 1658
1661 DEC_BOTH (pos, pos_byte); 1659 dec_both (&pos, &pos_byte);
1662 } 1660 }
1663 1661
1664 n++; 1662 n++;
@@ -2437,10 +2435,11 @@ since only regular expressions have distinguished subexpressions. */)
2437 if (NILP (string)) 2435 if (NILP (string))
2438 { 2436 {
2439 c = FETCH_CHAR_AS_MULTIBYTE (pos_byte); 2437 c = FETCH_CHAR_AS_MULTIBYTE (pos_byte);
2440 INC_BOTH (pos, pos_byte); 2438 inc_both (&pos, &pos_byte);
2441 } 2439 }
2442 else 2440 else
2443 FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE (c, string, pos, pos_byte); 2441 c = fetch_string_char_as_multibyte_advance (string,
2442 &pos, &pos_byte);
2444 2443
2445 if (lowercasep (c)) 2444 if (lowercasep (c))
2446 { 2445 {
@@ -2513,11 +2512,11 @@ since only regular expressions have distinguished subexpressions. */)
2513 ptrdiff_t subend = 0; 2512 ptrdiff_t subend = 0;
2514 bool delbackslash = 0; 2513 bool delbackslash = 0;
2515 2514
2516 FETCH_STRING_CHAR_ADVANCE (c, newtext, pos, pos_byte); 2515 c = fetch_string_char_advance (newtext, &pos, &pos_byte);
2517 2516
2518 if (c == '\\') 2517 if (c == '\\')
2519 { 2518 {
2520 FETCH_STRING_CHAR_ADVANCE (c, newtext, pos, pos_byte); 2519 c = fetch_string_char_advance (newtext, &pos, &pos_byte);
2521 2520
2522 if (c == '&') 2521 if (c == '&')
2523 { 2522 {
@@ -2625,7 +2624,8 @@ since only regular expressions have distinguished subexpressions. */)
2625 2624
2626 if (str_multibyte) 2625 if (str_multibyte)
2627 { 2626 {
2628 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, newtext, pos, pos_byte); 2627 c = fetch_string_char_advance_no_check (newtext,
2628 &pos, &pos_byte);
2629 if (!buf_multibyte) 2629 if (!buf_multibyte)
2630 c = CHAR_TO_BYTE8 (c); 2630 c = CHAR_TO_BYTE8 (c);
2631 } 2631 }
@@ -2634,7 +2634,7 @@ since only regular expressions have distinguished subexpressions. */)
2634 /* Note that we don't have to increment POS. */ 2634 /* Note that we don't have to increment POS. */
2635 c = SREF (newtext, pos_byte++); 2635 c = SREF (newtext, pos_byte++);
2636 if (buf_multibyte) 2636 if (buf_multibyte)
2637 MAKE_CHAR_MULTIBYTE (c); 2637 c = make_char_multibyte (c);
2638 } 2638 }
2639 2639
2640 /* Either set ADD_STUFF and ADD_LEN to the text to put in SUBSTED, 2640 /* Either set ADD_STUFF and ADD_LEN to the text to put in SUBSTED,
@@ -2647,8 +2647,8 @@ since only regular expressions have distinguished subexpressions. */)
2647 2647
2648 if (str_multibyte) 2648 if (str_multibyte)
2649 { 2649 {
2650 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, newtext, 2650 c = fetch_string_char_advance_no_check (newtext,
2651 pos, pos_byte); 2651 &pos, &pos_byte);
2652 if (!buf_multibyte && !ASCII_CHAR_P (c)) 2652 if (!buf_multibyte && !ASCII_CHAR_P (c))
2653 c = CHAR_TO_BYTE8 (c); 2653 c = CHAR_TO_BYTE8 (c);
2654 } 2654 }
@@ -2656,7 +2656,7 @@ since only regular expressions have distinguished subexpressions. */)
2656 { 2656 {
2657 c = SREF (newtext, pos_byte++); 2657 c = SREF (newtext, pos_byte++);
2658 if (buf_multibyte) 2658 if (buf_multibyte)
2659 MAKE_CHAR_MULTIBYTE (c); 2659 c = make_char_multibyte (c);
2660 } 2660 }
2661 2661
2662 if (c == '&') 2662 if (c == '&')
diff --git a/src/syntax.c b/src/syntax.c
index ff125b137cf..bcf4dc07997 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -535,7 +535,7 @@ char_quoted (ptrdiff_t charpos, ptrdiff_t bytepos)
535 while (charpos > beg) 535 while (charpos > beg)
536 { 536 {
537 int c; 537 int c;
538 DEC_BOTH (charpos, bytepos); 538 dec_both (&charpos, &bytepos);
539 539
540 UPDATE_SYNTAX_TABLE_BACKWARD (charpos); 540 UPDATE_SYNTAX_TABLE_BACKWARD (charpos);
541 c = FETCH_CHAR_AS_MULTIBYTE (bytepos); 541 c = FETCH_CHAR_AS_MULTIBYTE (bytepos);
@@ -556,11 +556,9 @@ char_quoted (ptrdiff_t charpos, ptrdiff_t bytepos)
556static ptrdiff_t 556static ptrdiff_t
557dec_bytepos (ptrdiff_t bytepos) 557dec_bytepos (ptrdiff_t bytepos)
558{ 558{
559 if (NILP (BVAR (current_buffer, enable_multibyte_characters))) 559 return (bytepos
560 return bytepos - 1; 560 - (!NILP (BVAR (current_buffer, enable_multibyte_characters))
561 561 ? prev_char_len (bytepos) : 1));
562 DEC_POS (bytepos);
563 return bytepos;
564} 562}
565 563
566/* Return a defun-start position before POS and not too far before. 564/* Return a defun-start position before POS and not too far before.
@@ -667,7 +665,7 @@ prev_char_comend_first (ptrdiff_t pos, ptrdiff_t pos_byte)
667 int c; 665 int c;
668 bool val; 666 bool val;
669 667
670 DEC_BOTH (pos, pos_byte); 668 dec_both (&pos, &pos_byte);
671 UPDATE_SYNTAX_TABLE_BACKWARD (pos); 669 UPDATE_SYNTAX_TABLE_BACKWARD (pos);
672 c = FETCH_CHAR (pos_byte); 670 c = FETCH_CHAR (pos_byte);
673 val = SYNTAX_COMEND_FIRST (c); 671 val = SYNTAX_COMEND_FIRST (c);
@@ -738,7 +736,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
738 bool com2start, com2end, comstart; 736 bool com2start, com2end, comstart;
739 737
740 /* Move back and examine a character. */ 738 /* Move back and examine a character. */
741 DEC_BOTH (from, from_byte); 739 dec_both (&from, &from_byte);
742 UPDATE_SYNTAX_TABLE_BACKWARD (from); 740 UPDATE_SYNTAX_TABLE_BACKWARD (from);
743 741
744 prev_syntax = syntax; 742 prev_syntax = syntax;
@@ -773,7 +771,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
773 { 771 {
774 ptrdiff_t next = from, next_byte = from_byte; 772 ptrdiff_t next = from, next_byte = from_byte;
775 int next_c, next_syntax; 773 int next_c, next_syntax;
776 DEC_BOTH (next, next_byte); 774 dec_both (&next, &next_byte);
777 UPDATE_SYNTAX_TABLE_BACKWARD (next); 775 UPDATE_SYNTAX_TABLE_BACKWARD (next);
778 next_c = FETCH_CHAR_AS_MULTIBYTE (next_byte); 776 next_c = FETCH_CHAR_AS_MULTIBYTE (next_byte);
779 next_syntax = SYNTAX_WITH_FLAGS (next_c); 777 next_syntax = SYNTAX_WITH_FLAGS (next_c);
@@ -1150,8 +1148,7 @@ the value of a `syntax-table' text property. */)
1150 1148
1151 if (*p) 1149 if (*p)
1152 { 1150 {
1153 int len; 1151 int len, character = string_char_and_length (p, &len);
1154 int character = STRING_CHAR_AND_LENGTH (p, len);
1155 XSETINT (match, character); 1152 XSETINT (match, character);
1156 if (XFIXNAT (match) == ' ') 1153 if (XFIXNAT (match) == ' ')
1157 match = Qnil; 1154 match = Qnil;
@@ -1455,7 +1452,7 @@ scan_words (ptrdiff_t from, EMACS_INT count)
1455 UPDATE_SYNTAX_TABLE_FORWARD (from); 1452 UPDATE_SYNTAX_TABLE_FORWARD (from);
1456 ch0 = FETCH_CHAR_AS_MULTIBYTE (from_byte); 1453 ch0 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
1457 code = SYNTAX (ch0); 1454 code = SYNTAX (ch0);
1458 INC_BOTH (from, from_byte); 1455 inc_both (&from, &from_byte);
1459 if (words_include_escapes 1456 if (words_include_escapes
1460 && (code == Sescape || code == Scharquote)) 1457 && (code == Sescape || code == Scharquote))
1461 break; 1458 break;
@@ -1488,7 +1485,7 @@ scan_words (ptrdiff_t from, EMACS_INT count)
1488 || (code != Sescape && code != Scharquote))) 1485 || (code != Sescape && code != Scharquote)))
1489 || word_boundary_p (ch0, ch1)) 1486 || word_boundary_p (ch0, ch1))
1490 break; 1487 break;
1491 INC_BOTH (from, from_byte); 1488 inc_both (&from, &from_byte);
1492 ch0 = ch1; 1489 ch0 = ch1;
1493 rarely_quit (from); 1490 rarely_quit (from);
1494 } 1491 }
@@ -1501,7 +1498,7 @@ scan_words (ptrdiff_t from, EMACS_INT count)
1501 { 1498 {
1502 if (from == beg) 1499 if (from == beg)
1503 return 0; 1500 return 0;
1504 DEC_BOTH (from, from_byte); 1501 dec_both (&from, &from_byte);
1505 UPDATE_SYNTAX_TABLE_BACKWARD (from); 1502 UPDATE_SYNTAX_TABLE_BACKWARD (from);
1506 ch1 = FETCH_CHAR_AS_MULTIBYTE (from_byte); 1503 ch1 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
1507 code = SYNTAX (ch1); 1504 code = SYNTAX (ch1);
@@ -1530,7 +1527,7 @@ scan_words (ptrdiff_t from, EMACS_INT count)
1530 { 1527 {
1531 if (from == beg) 1528 if (from == beg)
1532 break; 1529 break;
1533 DEC_BOTH (from, from_byte); 1530 dec_both (&from, &from_byte);
1534 UPDATE_SYNTAX_TABLE_BACKWARD (from); 1531 UPDATE_SYNTAX_TABLE_BACKWARD (from);
1535 ch0 = FETCH_CHAR_AS_MULTIBYTE (from_byte); 1532 ch0 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
1536 code = SYNTAX (ch0); 1533 code = SYNTAX (ch0);
@@ -1539,7 +1536,7 @@ scan_words (ptrdiff_t from, EMACS_INT count)
1539 || (code != Sescape && code != Scharquote))) 1536 || (code != Sescape && code != Scharquote)))
1540 || word_boundary_p (ch0, ch1)) 1537 || word_boundary_p (ch0, ch1))
1541 { 1538 {
1542 INC_BOTH (from, from_byte); 1539 inc_both (&from, &from_byte);
1543 break; 1540 break;
1544 } 1541 }
1545 ch1 = ch0; 1542 ch1 = ch0;
@@ -1818,7 +1815,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
1818 1815
1819 leading_code = str[i_byte]; 1816 leading_code = str[i_byte];
1820 } 1817 }
1821 c = STRING_CHAR_AND_LENGTH (str + i_byte, len); 1818 c = string_char_and_length (str + i_byte, &len);
1822 i_byte += len; 1819 i_byte += len;
1823 1820
1824 1821
@@ -1834,14 +1831,14 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
1834 1831
1835 /* Get the end of the range. */ 1832 /* Get the end of the range. */
1836 leading_code2 = str[i_byte]; 1833 leading_code2 = str[i_byte];
1837 c2 = STRING_CHAR_AND_LENGTH (str + i_byte, len); 1834 c2 = string_char_and_length (str + i_byte, &len);
1838 i_byte += len; 1835 i_byte += len;
1839 1836
1840 if (c2 == '\\' 1837 if (c2 == '\\'
1841 && i_byte < size_byte) 1838 && i_byte < size_byte)
1842 { 1839 {
1843 leading_code2 = str[i_byte]; 1840 leading_code2 = str[i_byte];
1844 c2 = STRING_CHAR_AND_LENGTH (str + i_byte, len); 1841 c2 = string_char_and_length (str + i_byte, &len);
1845 i_byte += len; 1842 i_byte += len;
1846 } 1843 }
1847 1844
@@ -1953,7 +1950,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
1953 p = GAP_END_ADDR; 1950 p = GAP_END_ADDR;
1954 stop = endp; 1951 stop = endp;
1955 } 1952 }
1956 c = STRING_CHAR_AND_LENGTH (p, nbytes); 1953 c = string_char_and_length (p, &nbytes);
1957 if (! NILP (iso_classes) && in_classes (c, iso_classes)) 1954 if (! NILP (iso_classes) && in_classes (c, iso_classes))
1958 { 1955 {
1959 if (negate) 1956 if (negate)
@@ -2175,7 +2172,7 @@ skip_syntaxes (bool forwardp, Lisp_Object string, Lisp_Object lim)
2175 stop = endp; 2172 stop = endp;
2176 } 2173 }
2177 if (multibyte) 2174 if (multibyte)
2178 c = STRING_CHAR_AND_LENGTH (p, nbytes); 2175 c = string_char_and_length (p, &nbytes);
2179 else 2176 else
2180 c = *p, nbytes = 1; 2177 c = *p, nbytes = 1;
2181 if (! fastmap[SYNTAX (c)]) 2178 if (! fastmap[SYNTAX (c)])
@@ -2357,7 +2354,7 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
2357 /* We have encountered a nested comment of the same style 2354 /* We have encountered a nested comment of the same style
2358 as the comment sequence which began this comment section. */ 2355 as the comment sequence which began this comment section. */
2359 nesting++; 2356 nesting++;
2360 INC_BOTH (from, from_byte); 2357 inc_both (&from, &from_byte);
2361 UPDATE_SYNTAX_TABLE_FORWARD (from); 2358 UPDATE_SYNTAX_TABLE_FORWARD (from);
2362 2359
2363 forw_incomment: 2360 forw_incomment:
@@ -2378,7 +2375,7 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
2378 break; 2375 break;
2379 else 2376 else
2380 { 2377 {
2381 INC_BOTH (from, from_byte); 2378 inc_both (&from, &from_byte);
2382 UPDATE_SYNTAX_TABLE_FORWARD (from); 2379 UPDATE_SYNTAX_TABLE_FORWARD (from);
2383 } 2380 }
2384 } 2381 }
@@ -2395,7 +2392,7 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
2395 as the comment sequence which began this comment section. */ 2392 as the comment sequence which began this comment section. */
2396 { 2393 {
2397 syntax = Smax; /* So that "#|#" isn't also a comment ender. */ 2394 syntax = Smax; /* So that "#|#" isn't also a comment ender. */
2398 INC_BOTH (from, from_byte); 2395 inc_both (&from, &from_byte);
2399 UPDATE_SYNTAX_TABLE_FORWARD (from); 2396 UPDATE_SYNTAX_TABLE_FORWARD (from);
2400 nesting++; 2397 nesting++;
2401 } 2398 }
@@ -2456,7 +2453,7 @@ between them, return t; otherwise return nil. */)
2456 comstart_first = SYNTAX_FLAGS_COMSTART_FIRST (syntax); 2453 comstart_first = SYNTAX_FLAGS_COMSTART_FIRST (syntax);
2457 comnested = SYNTAX_FLAGS_COMMENT_NESTED (syntax); 2454 comnested = SYNTAX_FLAGS_COMMENT_NESTED (syntax);
2458 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0); 2455 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0);
2459 INC_BOTH (from, from_byte); 2456 inc_both (&from, &from_byte);
2460 UPDATE_SYNTAX_TABLE_FORWARD (from); 2457 UPDATE_SYNTAX_TABLE_FORWARD (from);
2461 if (from < stop && comstart_first 2458 if (from < stop && comstart_first
2462 && (c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte), 2459 && (c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte),
@@ -2471,7 +2468,7 @@ between them, return t; otherwise return nil. */)
2471 code = Scomment; 2468 code = Scomment;
2472 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (other_syntax, syntax); 2469 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (other_syntax, syntax);
2473 comnested |= SYNTAX_FLAGS_COMMENT_NESTED (other_syntax); 2470 comnested |= SYNTAX_FLAGS_COMMENT_NESTED (other_syntax);
2474 INC_BOTH (from, from_byte); 2471 inc_both (&from, &from_byte);
2475 UPDATE_SYNTAX_TABLE_FORWARD (from); 2472 UPDATE_SYNTAX_TABLE_FORWARD (from);
2476 } 2473 }
2477 rarely_quit (++quit_count); 2474 rarely_quit (++quit_count);
@@ -2482,7 +2479,7 @@ between them, return t; otherwise return nil. */)
2482 comstyle = ST_COMMENT_STYLE; 2479 comstyle = ST_COMMENT_STYLE;
2483 else if (code != Scomment) 2480 else if (code != Scomment)
2484 { 2481 {
2485 DEC_BOTH (from, from_byte); 2482 dec_both (&from, &from_byte);
2486 SET_PT_BOTH (from, from_byte); 2483 SET_PT_BOTH (from, from_byte);
2487 return Qnil; 2484 return Qnil;
2488 } 2485 }
@@ -2495,7 +2492,7 @@ between them, return t; otherwise return nil. */)
2495 SET_PT_BOTH (from, from_byte); 2492 SET_PT_BOTH (from, from_byte);
2496 return Qnil; 2493 return Qnil;
2497 } 2494 }
2498 INC_BOTH (from, from_byte); 2495 inc_both (&from, &from_byte);
2499 UPDATE_SYNTAX_TABLE_FORWARD (from); 2496 UPDATE_SYNTAX_TABLE_FORWARD (from);
2500 /* We have skipped one comment. */ 2497 /* We have skipped one comment. */
2501 count1--; 2498 count1--;
@@ -2511,7 +2508,7 @@ between them, return t; otherwise return nil. */)
2511 return Qnil; 2508 return Qnil;
2512 } 2509 }
2513 2510
2514 DEC_BOTH (from, from_byte); 2511 dec_both (&from, &from_byte);
2515 /* char_quoted does UPDATE_SYNTAX_TABLE_BACKWARD (from). */ 2512 /* char_quoted does UPDATE_SYNTAX_TABLE_BACKWARD (from). */
2516 bool quoted = char_quoted (from, from_byte); 2513 bool quoted = char_quoted (from, from_byte);
2517 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 2514 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
@@ -2529,7 +2526,7 @@ between them, return t; otherwise return nil. */)
2529 /* We must record the comment style encountered so that 2526 /* We must record the comment style encountered so that
2530 later, we can match only the proper comment begin 2527 later, we can match only the proper comment begin
2531 sequence of the same style. */ 2528 sequence of the same style. */
2532 DEC_BOTH (from, from_byte); 2529 dec_both (&from, &from_byte);
2533 code = Sendcomment; 2530 code = Sendcomment;
2534 /* Calling char_quoted, above, set up global syntax position 2531 /* Calling char_quoted, above, set up global syntax position
2535 at the new value of FROM. */ 2532 at the new value of FROM. */
@@ -2547,7 +2544,7 @@ between them, return t; otherwise return nil. */)
2547 2544
2548 while (1) 2545 while (1)
2549 { 2546 {
2550 DEC_BOTH (from, from_byte); 2547 dec_both (&from, &from_byte);
2551 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2548 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2552 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 2549 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2553 if (SYNTAX (c) == Scomment_fence 2550 if (SYNTAX (c) == Scomment_fence
@@ -2588,7 +2585,7 @@ between them, return t; otherwise return nil. */)
2588 not-quite-endcomment. */ 2585 not-quite-endcomment. */
2589 if (SYNTAX (c) != code) 2586 if (SYNTAX (c) != code)
2590 /* It was a two-char Sendcomment. */ 2587 /* It was a two-char Sendcomment. */
2591 INC_BOTH (from, from_byte); 2588 inc_both (&from, &from_byte);
2592 goto leave; 2589 goto leave;
2593 } 2590 }
2594 } 2591 }
@@ -2602,7 +2599,7 @@ between them, return t; otherwise return nil. */)
2602 else if (code != Swhitespace || quoted) 2599 else if (code != Swhitespace || quoted)
2603 { 2600 {
2604 leave: 2601 leave:
2605 INC_BOTH (from, from_byte); 2602 inc_both (&from, &from_byte);
2606 SET_PT_BOTH (from, from_byte); 2603 SET_PT_BOTH (from, from_byte);
2607 return Qnil; 2604 return Qnil;
2608 } 2605 }
@@ -2676,7 +2673,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2676 prefix = SYNTAX_FLAGS_PREFIX (syntax); 2673 prefix = SYNTAX_FLAGS_PREFIX (syntax);
2677 if (depth == min_depth) 2674 if (depth == min_depth)
2678 last_good = from; 2675 last_good = from;
2679 INC_BOTH (from, from_byte); 2676 inc_both (&from, &from_byte);
2680 UPDATE_SYNTAX_TABLE_FORWARD (from); 2677 UPDATE_SYNTAX_TABLE_FORWARD (from);
2681 if (from < stop && comstart_first 2678 if (from < stop && comstart_first
2682 && (c = FETCH_CHAR_AS_MULTIBYTE (from_byte), 2679 && (c = FETCH_CHAR_AS_MULTIBYTE (from_byte),
@@ -2692,7 +2689,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2692 code = Scomment; 2689 code = Scomment;
2693 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (other_syntax, syntax); 2690 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (other_syntax, syntax);
2694 comnested |= SYNTAX_FLAGS_COMMENT_NESTED (other_syntax); 2691 comnested |= SYNTAX_FLAGS_COMMENT_NESTED (other_syntax);
2695 INC_BOTH (from, from_byte); 2692 inc_both (&from, &from_byte);
2696 UPDATE_SYNTAX_TABLE_FORWARD (from); 2693 UPDATE_SYNTAX_TABLE_FORWARD (from);
2697 } 2694 }
2698 2695
@@ -2705,7 +2702,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2705 case Scharquote: 2702 case Scharquote:
2706 if (from == stop) 2703 if (from == stop)
2707 goto lose; 2704 goto lose;
2708 INC_BOTH (from, from_byte); 2705 inc_both (&from, &from_byte);
2709 /* Treat following character as a word constituent. */ 2706 /* Treat following character as a word constituent. */
2710 FALLTHROUGH; 2707 FALLTHROUGH;
2711 case Sword: 2708 case Sword:
@@ -2721,7 +2718,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2721 { 2718 {
2722 case Scharquote: 2719 case Scharquote:
2723 case Sescape: 2720 case Sescape:
2724 INC_BOTH (from, from_byte); 2721 inc_both (&from, &from_byte);
2725 if (from == stop) 2722 if (from == stop)
2726 goto lose; 2723 goto lose;
2727 break; 2724 break;
@@ -2732,7 +2729,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2732 default: 2729 default:
2733 goto done; 2730 goto done;
2734 } 2731 }
2735 INC_BOTH (from, from_byte); 2732 inc_both (&from, &from_byte);
2736 rarely_quit (++quit_count); 2733 rarely_quit (++quit_count);
2737 } 2734 }
2738 goto done; 2735 goto done;
@@ -2754,7 +2751,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2754 goto done; 2751 goto done;
2755 goto lose; 2752 goto lose;
2756 } 2753 }
2757 INC_BOTH (from, from_byte); 2754 inc_both (&from, &from_byte);
2758 UPDATE_SYNTAX_TABLE_FORWARD (from); 2755 UPDATE_SYNTAX_TABLE_FORWARD (from);
2759 break; 2756 break;
2760 2757
@@ -2763,7 +2760,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2763 break; 2760 break;
2764 if (from != stop && c == FETCH_CHAR_AS_MULTIBYTE (from_byte)) 2761 if (from != stop && c == FETCH_CHAR_AS_MULTIBYTE (from_byte))
2765 { 2762 {
2766 INC_BOTH (from, from_byte); 2763 inc_both (&from, &from_byte);
2767 } 2764 }
2768 if (mathexit) 2765 if (mathexit)
2769 { 2766 {
@@ -2803,11 +2800,11 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2803 break; 2800 break;
2804 2801
2805 if (c_code == Scharquote || c_code == Sescape) 2802 if (c_code == Scharquote || c_code == Sescape)
2806 INC_BOTH (from, from_byte); 2803 inc_both (&from, &from_byte);
2807 INC_BOTH (from, from_byte); 2804 inc_both (&from, &from_byte);
2808 rarely_quit (++quit_count); 2805 rarely_quit (++quit_count);
2809 } 2806 }
2810 INC_BOTH (from, from_byte); 2807 inc_both (&from, &from_byte);
2811 if (!depth && sexpflag) goto done; 2808 if (!depth && sexpflag) goto done;
2812 break; 2809 break;
2813 default: 2810 default:
@@ -2832,7 +2829,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2832 while (from > stop) 2829 while (from > stop)
2833 { 2830 {
2834 rarely_quit (++quit_count); 2831 rarely_quit (++quit_count);
2835 DEC_BOTH (from, from_byte); 2832 dec_both (&from, &from_byte);
2836 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2833 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2837 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 2834 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2838 int syntax = SYNTAX_WITH_FLAGS (c); 2835 int syntax = SYNTAX_WITH_FLAGS (c);
@@ -2851,7 +2848,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2851 later, we can match only the proper comment begin 2848 later, we can match only the proper comment begin
2852 sequence of the same style. */ 2849 sequence of the same style. */
2853 int c2, other_syntax; 2850 int c2, other_syntax;
2854 DEC_BOTH (from, from_byte); 2851 dec_both (&from, &from_byte);
2855 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2852 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2856 code = Sendcomment; 2853 code = Sendcomment;
2857 c2 = FETCH_CHAR_AS_MULTIBYTE (from_byte); 2854 c2 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
@@ -2865,7 +2862,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2865 if we decremented FROM in the if-statement above. */ 2862 if we decremented FROM in the if-statement above. */
2866 if (code != Sendcomment && char_quoted (from, from_byte)) 2863 if (code != Sendcomment && char_quoted (from, from_byte))
2867 { 2864 {
2868 DEC_BOTH (from, from_byte); 2865 dec_both (&from, &from_byte);
2869 code = Sword; 2866 code = Sword;
2870 } 2867 }
2871 else if (SYNTAX_FLAGS_PREFIX (syntax)) 2868 else if (SYNTAX_FLAGS_PREFIX (syntax))
@@ -2882,11 +2879,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2882 after passing it. */ 2879 after passing it. */
2883 while (from > stop) 2880 while (from > stop)
2884 { 2881 {
2885 temp_pos = from_byte; 2882 temp_pos = dec_bytepos (from_byte);
2886 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
2887 DEC_POS (temp_pos);
2888 else
2889 temp_pos--;
2890 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1); 2883 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2891 c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos); 2884 c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
2892 /* Don't allow comment-end to be quoted. */ 2885 /* Don't allow comment-end to be quoted. */
@@ -2895,7 +2888,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2895 quoted = char_quoted (from - 1, temp_pos); 2888 quoted = char_quoted (from - 1, temp_pos);
2896 if (quoted) 2889 if (quoted)
2897 { 2890 {
2898 DEC_BOTH (from, from_byte); 2891 dec_both (&from, &from_byte);
2899 temp_pos = dec_bytepos (temp_pos); 2892 temp_pos = dec_bytepos (temp_pos);
2900 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1); 2893 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2901 } 2894 }
@@ -2906,7 +2899,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2906 case Sword: case Ssymbol: case Squote: break; 2899 case Sword: case Ssymbol: case Squote: break;
2907 default: goto done2; 2900 default: goto done2;
2908 } 2901 }
2909 DEC_BOTH (from, from_byte); 2902 dec_both (&from, &from_byte);
2910 rarely_quit (++quit_count); 2903 rarely_quit (++quit_count);
2911 } 2904 }
2912 goto done2; 2905 goto done2;
@@ -2919,7 +2912,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2919 temp_pos = dec_bytepos (from_byte); 2912 temp_pos = dec_bytepos (from_byte);
2920 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1); 2913 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2921 if (from != stop && c == FETCH_CHAR_AS_MULTIBYTE (temp_pos)) 2914 if (from != stop && c == FETCH_CHAR_AS_MULTIBYTE (temp_pos))
2922 DEC_BOTH (from, from_byte); 2915 dec_both (&from, &from_byte);
2923 } 2916 }
2924 if (mathexit) 2917 if (mathexit)
2925 { 2918 {
@@ -2962,7 +2955,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2962 { 2955 {
2963 if (from == stop) 2956 if (from == stop)
2964 goto lose; 2957 goto lose;
2965 DEC_BOTH (from, from_byte); 2958 dec_both (&from, &from_byte);
2966 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2959 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2967 if (!char_quoted (from, from_byte)) 2960 if (!char_quoted (from, from_byte))
2968 { 2961 {
@@ -2981,7 +2974,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2981 { 2974 {
2982 if (from == stop) 2975 if (from == stop)
2983 goto lose; 2976 goto lose;
2984 DEC_BOTH (from, from_byte); 2977 dec_both (&from, &from_byte);
2985 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2978 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2986 if (!char_quoted (from, from_byte)) 2979 if (!char_quoted (from, from_byte))
2987 { 2980 {
@@ -3091,7 +3084,7 @@ the prefix syntax flag (p). */)
3091 3084
3092 SETUP_SYNTAX_TABLE (pos, -1); 3085 SETUP_SYNTAX_TABLE (pos, -1);
3093 3086
3094 DEC_BOTH (pos, pos_byte); 3087 dec_both (&pos, &pos_byte);
3095 3088
3096 while (!char_quoted (pos, pos_byte) 3089 while (!char_quoted (pos, pos_byte)
3097 /* Previous statement updates syntax table. */ 3090 /* Previous statement updates syntax table. */
@@ -3103,7 +3096,7 @@ the prefix syntax flag (p). */)
3103 3096
3104 if (pos <= beg) 3097 if (pos <= beg)
3105 break; 3098 break;
3106 DEC_BOTH (pos, pos_byte); 3099 dec_both (&pos, &pos_byte);
3107 rarely_quit (pos); 3100 rarely_quit (pos);
3108 } 3101 }
3109 3102
@@ -3180,7 +3173,7 @@ scan_sexps_forward (struct lisp_parse_state *state,
3180 prev_from = from; 3173 prev_from = from;
3181 prev_from_byte = from_byte; 3174 prev_from_byte = from_byte;
3182 if (from != BEGV) 3175 if (from != BEGV)
3183 DEC_BOTH (prev_from, prev_from_byte); 3176 dec_both (&prev_from, &prev_from_byte);
3184 3177
3185 /* Use this macro instead of `from++'. */ 3178 /* Use this macro instead of `from++'. */
3186#define INC_FROM \ 3179#define INC_FROM \
@@ -3189,7 +3182,7 @@ do { prev_from = from; \
3189 temp = FETCH_CHAR_AS_MULTIBYTE (prev_from_byte); \ 3182 temp = FETCH_CHAR_AS_MULTIBYTE (prev_from_byte); \
3190 prev_prev_from_syntax = prev_from_syntax; \ 3183 prev_prev_from_syntax = prev_from_syntax; \
3191 prev_from_syntax = SYNTAX_WITH_FLAGS (temp); \ 3184 prev_from_syntax = SYNTAX_WITH_FLAGS (temp); \
3192 INC_BOTH (from, from_byte); \ 3185 inc_both (&from, &from_byte); \
3193 if (from < end) \ 3186 if (from < end) \
3194 UPDATE_SYNTAX_TABLE_FORWARD (from); \ 3187 UPDATE_SYNTAX_TABLE_FORWARD (from); \
3195 } while (0) 3188 } while (0)
diff --git a/src/sysdep.c b/src/sysdep.c
index 149d80f19ec..86e7c20cd01 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -4133,14 +4133,20 @@ str_collate (Lisp_Object s1, Lisp_Object s2,
4133 len = SCHARS (s1); i = i_byte = 0; 4133 len = SCHARS (s1); i = i_byte = 0;
4134 SAFE_NALLOCA (p1, 1, len + 1); 4134 SAFE_NALLOCA (p1, 1, len + 1);
4135 while (i < len) 4135 while (i < len)
4136 FETCH_STRING_CHAR_ADVANCE (*(p1+i-1), s1, i, i_byte); 4136 {
4137 *(p1+len) = 0; 4137 wchar_t *p = &p1[i];
4138 *p = fetch_string_char_advance (s1, &i, &i_byte);
4139 }
4140 p1[len] = 0;
4138 4141
4139 len = SCHARS (s2); i = i_byte = 0; 4142 len = SCHARS (s2); i = i_byte = 0;
4140 SAFE_NALLOCA (p2, 1, len + 1); 4143 SAFE_NALLOCA (p2, 1, len + 1);
4141 while (i < len) 4144 while (i < len)
4142 FETCH_STRING_CHAR_ADVANCE (*(p2+i-1), s2, i, i_byte); 4145 {
4143 *(p2+len) = 0; 4146 wchar_t *p = &p2[i];
4147 *p = fetch_string_char_advance (s2, &i, &i_byte);
4148 }
4149 p2[len] = 0;
4144 4150
4145 if (STRINGP (locale)) 4151 if (STRINGP (locale))
4146 { 4152 {
diff --git a/src/xdisp.c b/src/xdisp.c
index cce434e6665..86ae8e73365 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1901,16 +1901,14 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1901 1901
1902 1902
1903/* Return the next character from STR. Return in *LEN the length of 1903/* Return the next character from STR. Return in *LEN the length of
1904 the character. This is like STRING_CHAR_AND_LENGTH but never 1904 the character. This is like string_char_and_length but never
1905 returns an invalid character. If we find one, we return a `?', but 1905 returns an invalid character. If we find one, we return a `?', but
1906 with the length of the invalid character. */ 1906 with the length of the invalid character. */
1907 1907
1908static int 1908static int
1909string_char_and_length (const unsigned char *str, int *len) 1909check_char_and_length (const unsigned char *str, int *len)
1910{ 1910{
1911 int c; 1911 int c = string_char_and_length (str, len);
1912
1913 c = STRING_CHAR_AND_LENGTH (str, *len);
1914 if (!CHAR_VALID_P (c)) 1912 if (!CHAR_VALID_P (c))
1915 /* We may not change the length here because other places in Emacs 1913 /* We may not change the length here because other places in Emacs
1916 don't use this function, i.e. they silently accept invalid 1914 don't use this function, i.e. they silently accept invalid
@@ -1933,11 +1931,10 @@ string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t ncha
1933 if (STRING_MULTIBYTE (string)) 1931 if (STRING_MULTIBYTE (string))
1934 { 1932 {
1935 const unsigned char *p = SDATA (string) + BYTEPOS (pos); 1933 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1936 int len;
1937 1934
1938 while (nchars--) 1935 while (nchars--)
1939 { 1936 {
1940 string_char_and_length (p, &len); 1937 int len = BYTES_BY_CHAR_HEAD (*p);
1941 p += len; 1938 p += len;
1942 CHARPOS (pos) += 1; 1939 CHARPOS (pos) += 1;
1943 BYTEPOS (pos) += len; 1940 BYTEPOS (pos) += len;
@@ -1978,12 +1975,10 @@ c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1978 1975
1979 if (multibyte_p) 1976 if (multibyte_p)
1980 { 1977 {
1981 int len;
1982
1983 SET_TEXT_POS (pos, 0, 0); 1978 SET_TEXT_POS (pos, 0, 0);
1984 while (charpos--) 1979 while (charpos--)
1985 { 1980 {
1986 string_char_and_length ((const unsigned char *) s, &len); 1981 int len = BYTES_BY_CHAR_HEAD (*s);
1987 s += len; 1982 s += len;
1988 CHARPOS (pos) += 1; 1983 CHARPOS (pos) += 1;
1989 BYTEPOS (pos) += len; 1984 BYTEPOS (pos) += len;
@@ -2007,12 +2002,11 @@ number_of_chars (const char *s, bool multibyte_p)
2007 if (multibyte_p) 2002 if (multibyte_p)
2008 { 2003 {
2009 ptrdiff_t rest = strlen (s); 2004 ptrdiff_t rest = strlen (s);
2010 int len;
2011 const unsigned char *p = (const unsigned char *) s; 2005 const unsigned char *p = (const unsigned char *) s;
2012 2006
2013 for (nchars = 0; rest > 0; ++nchars) 2007 for (nchars = 0; rest > 0; ++nchars)
2014 { 2008 {
2015 string_char_and_length (p, &len); 2009 int len = BYTES_BY_CHAR_HEAD (*p);
2016 rest -= len, p += len; 2010 rest -= len, p += len;
2017 } 2011 }
2018 } 2012 }
@@ -3819,8 +3813,7 @@ compute_stop_pos (struct it *it)
3819 ptrdiff_t bpos = CHAR_TO_BYTE (pos); 3813 ptrdiff_t bpos = CHAR_TO_BYTE (pos);
3820 while (pos < endpos) 3814 while (pos < endpos)
3821 { 3815 {
3822 int ch; 3816 int ch = fetch_char_advance_no_check (&pos, &bpos);
3823 FETCH_CHAR_ADVANCE_NO_CHECK (ch, pos, bpos);
3824 if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\f') 3817 if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\f')
3825 { 3818 {
3826 found = true; 3819 found = true;
@@ -4479,10 +4472,8 @@ face_before_or_after_it_pos (struct it *it, bool before_p)
4479 { 4472 {
4480 struct text_pos pos1 = string_pos (charpos, it->string); 4473 struct text_pos pos1 = string_pos (charpos, it->string);
4481 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1); 4474 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4482 int c, len;
4483 struct face *face = FACE_FROM_ID (it->f, face_id); 4475 struct face *face = FACE_FROM_ID (it->f, face_id);
4484 4476 int len, c = check_char_and_length (p, &len);
4485 c = string_char_and_length (p, &len);
4486 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string); 4477 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4487 } 4478 }
4488 } 4479 }
@@ -6577,7 +6568,7 @@ back_to_previous_line_start (struct it *it)
6577{ 6568{
6578 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it); 6569 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6579 6570
6580 DEC_BOTH (cp, bp); 6571 dec_both (&cp, &bp);
6581 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it)); 6572 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6582} 6573}
6583 6574
@@ -8391,7 +8382,7 @@ next_element_from_string (struct it *it)
8391 { 8382 {
8392 const unsigned char *s = (SDATA (it->string) 8383 const unsigned char *s = (SDATA (it->string)
8393 + IT_STRING_BYTEPOS (*it)); 8384 + IT_STRING_BYTEPOS (*it));
8394 it->c = string_char_and_length (s, &it->len); 8385 it->c = check_char_and_length (s, &it->len);
8395 } 8386 }
8396 else 8387 else
8397 { 8388 {
@@ -8429,7 +8420,7 @@ next_element_from_string (struct it *it)
8429 { 8420 {
8430 const unsigned char *s = (SDATA (it->string) 8421 const unsigned char *s = (SDATA (it->string)
8431 + IT_STRING_BYTEPOS (*it)); 8422 + IT_STRING_BYTEPOS (*it));
8432 it->c = string_char_and_length (s, &it->len); 8423 it->c = check_char_and_length (s, &it->len);
8433 } 8424 }
8434 else 8425 else
8435 { 8426 {
@@ -8487,7 +8478,7 @@ next_element_from_c_string (struct it *it)
8487 BYTEPOS (it->position) = CHARPOS (it->position) = -1; 8478 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
8488 } 8479 }
8489 else if (it->multibyte_p) 8480 else if (it->multibyte_p)
8490 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len); 8481 it->c = check_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
8491 else 8482 else
8492 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1; 8483 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
8493 8484
@@ -8784,7 +8775,7 @@ next_element_from_buffer (struct it *it)
8784 /* Get the next character, maybe multibyte. */ 8775 /* Get the next character, maybe multibyte. */
8785 p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); 8776 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8786 if (it->multibyte_p && !ASCII_CHAR_P (*p)) 8777 if (it->multibyte_p && !ASCII_CHAR_P (*p))
8787 it->c = STRING_CHAR_AND_LENGTH (p, it->len); 8778 it->c = string_char_and_length (p, &it->len);
8788 else 8779 else
8789 it->c = *p, it->len = 1; 8780 it->c = *p, it->len = 1;
8790 8781
@@ -10073,7 +10064,7 @@ move_it_vertically_backward (struct it *it, int dy)
10073 { 10064 {
10074 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it); 10065 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
10075 10066
10076 DEC_BOTH (cp, bp); 10067 dec_both (&cp, &bp);
10077 cp = find_newline_no_quit (cp, bp, -1, NULL); 10068 cp = find_newline_no_quit (cp, bp, -1, NULL);
10078 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS); 10069 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
10079 } 10070 }
@@ -10667,32 +10658,26 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
10667 if (multibyte 10658 if (multibyte
10668 && NILP (BVAR (current_buffer, enable_multibyte_characters))) 10659 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10669 { 10660 {
10670 ptrdiff_t i;
10671 int c, char_bytes;
10672 char work[1];
10673
10674 /* Convert a multibyte string to single-byte 10661 /* Convert a multibyte string to single-byte
10675 for the *Message* buffer. */ 10662 for the *Message* buffer. */
10676 for (i = 0; i < nbytes; i += char_bytes) 10663 for (ptrdiff_t i = 0; i < nbytes; )
10677 { 10664 {
10678 c = string_char_and_length (msg + i, &char_bytes); 10665 int char_bytes, c = check_char_and_length (msg + i, &char_bytes);
10679 work[0] = CHAR_TO_BYTE8 (c); 10666 char work = CHAR_TO_BYTE8 (c);
10680 insert_1_both (work, 1, 1, true, false, false); 10667 insert_1_both (&work, 1, 1, true, false, false);
10668 i += char_bytes;
10681 } 10669 }
10682 } 10670 }
10683 else if (! multibyte 10671 else if (! multibyte
10684 && ! NILP (BVAR (current_buffer, enable_multibyte_characters))) 10672 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
10685 { 10673 {
10686 ptrdiff_t i;
10687 int c, char_bytes;
10688 unsigned char str[MAX_MULTIBYTE_LENGTH];
10689 /* Convert a single-byte string to multibyte 10674 /* Convert a single-byte string to multibyte
10690 for the *Message* buffer. */ 10675 for the *Message* buffer. */
10691 for (i = 0; i < nbytes; i++) 10676 for (ptrdiff_t i = 0; i < nbytes; i++)
10692 { 10677 {
10693 c = msg[i]; 10678 int c = make_char_multibyte (msg[i]);
10694 MAKE_CHAR_MULTIBYTE (c); 10679 unsigned char str[MAX_MULTIBYTE_LENGTH];
10695 char_bytes = CHAR_STRING (c, str); 10680 int char_bytes = CHAR_STRING (c, str);
10696 insert_1_both ((char *) str, 1, char_bytes, true, false, false); 10681 insert_1_both ((char *) str, 1, char_bytes, true, false, false);
10697 } 10682 }
10698 } 10683 }
@@ -21151,7 +21136,7 @@ get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
21151 21136
21152 /* Get the next character. */ 21137 /* Get the next character. */
21153 if (multibyte_p) 21138 if (multibyte_p)
21154 it.c = it.char_to_display = string_char_and_length (p, &it.len); 21139 it.c = it.char_to_display = check_char_and_length (p, &it.len);
21155 else 21140 else
21156 { 21141 {
21157 it.c = it.char_to_display = *p, it.len = 1; 21142 it.c = it.char_to_display = *p, it.len = 1;
@@ -22504,7 +22489,7 @@ find_row_edges (struct it *it, struct glyph_row *row,
22504 required when scanning back, because max_pos will already 22489 required when scanning back, because max_pos will already
22505 have a much larger value. */ 22490 have a much larger value. */
22506 if (CHARPOS (row->end.pos) > max_pos) 22491 if (CHARPOS (row->end.pos) > max_pos)
22507 INC_BOTH (max_pos, max_bpos); 22492 inc_both (&max_pos, &max_bpos);
22508 SET_TEXT_POS (row->maxpos, max_pos, max_bpos); 22493 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
22509 } 22494 }
22510 else if (CHARPOS (it->eol_pos) > 0) 22495 else if (CHARPOS (it->eol_pos) > 0)
@@ -22522,7 +22507,7 @@ find_row_edges (struct it *it, struct glyph_row *row,
22522 SET_TEXT_POS (row->maxpos, max_pos, max_bpos); 22507 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
22523 else 22508 else
22524 { 22509 {
22525 INC_BOTH (max_pos, max_bpos); 22510 inc_both (&max_pos, &max_bpos);
22526 SET_TEXT_POS (row->maxpos, max_pos, max_bpos); 22511 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
22527 } 22512 }
22528 } 22513 }
@@ -23932,7 +23917,7 @@ See also `bidi-paragraph-direction'. */)
23932 to make sure we are within that paragraph. To that end, find 23917 to make sure we are within that paragraph. To that end, find
23933 the previous non-empty line. */ 23918 the previous non-empty line. */
23934 if (pos >= ZV && pos > BEGV) 23919 if (pos >= ZV && pos > BEGV)
23935 DEC_BOTH (pos, bytepos); 23920 dec_both (&pos, &bytepos);
23936 AUTO_STRING (trailing_white_space, "[\f\t ]*\n"); 23921 AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
23937 if (fast_looking_at (trailing_white_space, 23922 if (fast_looking_at (trailing_white_space,
23938 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0) 23923 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
@@ -29279,7 +29264,7 @@ produce_stretch_glyph (struct it *it)
29279 29264
29280 it2 = *it; 29265 it2 = *it;
29281 if (it->multibyte_p) 29266 if (it->multibyte_p)
29282 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len); 29267 it2.c = it2.char_to_display = string_char_and_length (p, &it2.len);
29283 else 29268 else
29284 { 29269 {
29285 it2.c = it2.char_to_display = *p, it2.len = 1; 29270 it2.c = it2.char_to_display = *p, it2.len = 1;
diff --git a/src/xfont.c b/src/xfont.c
index f6131dcec5a..1563b43bf97 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -166,7 +166,7 @@ xfont_encode_coding_xlfd (char *xlfd)
166 166
167 while (*p0) 167 while (*p0)
168 { 168 {
169 int c = STRING_CHAR_ADVANCE (p0); 169 int c = string_char_advance (&p0);
170 170
171 if (c >= 0x100) 171 if (c >= 0x100)
172 return -1; 172 return -1;
diff --git a/src/xterm.c b/src/xterm.c
index ae5dad92897..afe9c3da5b8 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8706,7 +8706,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
8706 if (nchars == nbytes) 8706 if (nchars == nbytes)
8707 ch = copy_bufptr[i], len = 1; 8707 ch = copy_bufptr[i], len = 1;
8708 else 8708 else
8709 ch = STRING_CHAR_AND_LENGTH (copy_bufptr + i, len); 8709 ch = string_char_and_length (copy_bufptr + i, &len);
8710 inev.ie.kind = (SINGLE_BYTE_CHAR_P (ch) 8710 inev.ie.kind = (SINGLE_BYTE_CHAR_P (ch)
8711 ? ASCII_KEYSTROKE_EVENT 8711 ? ASCII_KEYSTROKE_EVENT
8712 : MULTIBYTE_CHAR_KEYSTROKE_EVENT); 8712 : MULTIBYTE_CHAR_KEYSTROKE_EVENT);