aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVibhav Pant2017-02-11 19:54:37 +0530
committerVibhav Pant2017-02-11 19:54:37 +0530
commitc1a9b5db0e2985e7c46fb3b1e50e9d17785f7fa3 (patch)
treea33cb8c57d628541baee88bef5b0907327056e88 /src
parenta75d080b17a6b6c6296ff4e24d8129d77bb3bb6b (diff)
parentac83b2dfe4504babfbafc5efb37dbde4bed34fed (diff)
downloademacs-c1a9b5db0e2985e7c46fb3b1e50e9d17785f7fa3.tar.gz
emacs-c1a9b5db0e2985e7c46fb3b1e50e9d17785f7fa3.zip
Merge branch 'master' into feature/byte-switch
Diffstat (limited to 'src')
-rw-r--r--src/composite.c89
-rw-r--r--src/data.c6
-rw-r--r--src/dispextern.h2
-rw-r--r--src/fns.c262
-rw-r--r--src/image.c16
-rw-r--r--src/keyboard.c25
-rw-r--r--src/lisp.h75
-rw-r--r--src/xdisp.c52
-rw-r--r--src/xfaces.c2
-rw-r--r--src/xwidget.c12
10 files changed, 272 insertions, 269 deletions
diff --git a/src/composite.c b/src/composite.c
index f23bb17c57a..b673c53ac83 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -1012,7 +1012,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
1012 val = CHAR_TABLE_REF (Vcomposition_function_table, c); 1012 val = CHAR_TABLE_REF (Vcomposition_function_table, c);
1013 if (! NILP (val)) 1013 if (! NILP (val))
1014 { 1014 {
1015 for (int ridx = 0; CONSP (val); val = XCDR (val), ridx++) 1015 for (EMACS_INT ridx = 0; CONSP (val); val = XCDR (val), ridx++)
1016 { 1016 {
1017 Lisp_Object elt = XCAR (val); 1017 Lisp_Object elt = XCAR (val);
1018 if (VECTORP (elt) && ASIZE (elt) == 3 1018 if (VECTORP (elt) && ASIZE (elt) == 3
@@ -1063,54 +1063,48 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
1063 while (char_composable_p (c)) 1063 while (char_composable_p (c))
1064 { 1064 {
1065 val = CHAR_TABLE_REF (Vcomposition_function_table, c); 1065 val = CHAR_TABLE_REF (Vcomposition_function_table, c);
1066 if (! NILP (val)) 1066 for (EMACS_INT ridx = 0; CONSP (val); val = XCDR (val), ridx++)
1067 { 1067 {
1068 Lisp_Object elt; 1068 Lisp_Object elt = XCAR (val);
1069 int ridx, blen; 1069 if (VECTORP (elt) && ASIZE (elt) == 3
1070 1070 && NATNUMP (AREF (elt, 1))
1071 for (ridx = 0; CONSP (val); val = XCDR (val), ridx++) 1071 && charpos - XFASTINT (AREF (elt, 1)) > endpos)
1072 { 1072 {
1073 elt = XCAR (val); 1073 ptrdiff_t back = XFASTINT (AREF (elt, 1));
1074 if (VECTORP (elt) && ASIZE (elt) == 3 1074 ptrdiff_t cpos = charpos - back, bpos;
1075 && NATNUMP (AREF (elt, 1))
1076 && charpos - XFASTINT (AREF (elt, 1)) > endpos)
1077 {
1078 ptrdiff_t back = XFASTINT (AREF (elt, 1));
1079 ptrdiff_t cpos = charpos - back, bpos;
1080 1075
1081 if (back == 0) 1076 if (back == 0)
1082 bpos = bytepos; 1077 bpos = bytepos;
1083 else 1078 else
1084 bpos = (NILP (string) ? CHAR_TO_BYTE (cpos) 1079 bpos = (NILP (string) ? CHAR_TO_BYTE (cpos)
1085 : string_char_to_byte (string, cpos)); 1080 : string_char_to_byte (string, cpos));
1086 if (STRINGP (AREF (elt, 0))) 1081 ptrdiff_t blen
1087 blen = fast_looking_at (AREF (elt, 0), cpos, bpos, 1082 = (STRINGP (AREF (elt, 0))
1088 start + 1, limit, string); 1083 ? fast_looking_at (AREF (elt, 0), cpos, bpos,
1089 else 1084 start + 1, limit, string)
1090 blen = 1; 1085 : 1);
1091 if (blen > 0) 1086 if (blen > 0)
1087 {
1088 /* Make CPOS point to the last character of
1089 match. Note that BLEN is byte-length. */
1090 if (blen > 1)
1091 {
1092 bpos += blen;
1093 if (NILP (string))
1094 cpos = BYTE_TO_CHAR (bpos) - 1;
1095 else
1096 cpos = string_byte_to_char (string, bpos) - 1;
1097 }
1098 back = cpos - (charpos - back);
1099 if (cmp_it->stop_pos < cpos
1100 || (cmp_it->stop_pos == cpos
1101 && cmp_it->lookback < back))
1092 { 1102 {
1093 /* Make CPOS point to the last character of 1103 cmp_it->rule_idx = ridx;
1094 match. Note that BLEN is byte-length. */ 1104 cmp_it->stop_pos = cpos;
1095 if (blen > 1) 1105 cmp_it->ch = c;
1096 { 1106 cmp_it->lookback = back;
1097 bpos += blen; 1107 cmp_it->nchars = back + 1;
1098 if (NILP (string))
1099 cpos = BYTE_TO_CHAR (bpos) - 1;
1100 else
1101 cpos = string_byte_to_char (string, bpos) - 1;
1102 }
1103 back = cpos - (charpos - back);
1104 if (cmp_it->stop_pos < cpos
1105 || (cmp_it->stop_pos == cpos
1106 && cmp_it->lookback < back))
1107 {
1108 cmp_it->rule_idx = ridx;
1109 cmp_it->stop_pos = cpos;
1110 cmp_it->ch = c;
1111 cmp_it->lookback = back;
1112 cmp_it->nchars = back + 1;
1113 }
1114 } 1108 }
1115 } 1109 }
1116 } 1110 }
@@ -1203,10 +1197,10 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos,
1203 { 1197 {
1204 Lisp_Object lgstring = Qnil; 1198 Lisp_Object lgstring = Qnil;
1205 Lisp_Object val, elt; 1199 Lisp_Object val, elt;
1206 ptrdiff_t i;
1207 1200
1208 val = CHAR_TABLE_REF (Vcomposition_function_table, cmp_it->ch); 1201 val = CHAR_TABLE_REF (Vcomposition_function_table, cmp_it->ch);
1209 for (i = 0; i < cmp_it->rule_idx; i++, val = XCDR (val)); 1202 for (EMACS_INT i = 0; i < cmp_it->rule_idx; i++, val = XCDR (val))
1203 continue;
1210 if (charpos < endpos) 1204 if (charpos < endpos)
1211 { 1205 {
1212 for (; CONSP (val); val = XCDR (val)) 1206 for (; CONSP (val); val = XCDR (val))
@@ -1255,6 +1249,7 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos,
1255 if (NILP (LGSTRING_ID (lgstring))) 1249 if (NILP (LGSTRING_ID (lgstring)))
1256 lgstring = composition_gstring_put_cache (lgstring, -1); 1250 lgstring = composition_gstring_put_cache (lgstring, -1);
1257 cmp_it->id = XINT (LGSTRING_ID (lgstring)); 1251 cmp_it->id = XINT (LGSTRING_ID (lgstring));
1252 int i;
1258 for (i = 0; i < LGSTRING_GLYPH_LEN (lgstring); i++) 1253 for (i = 0; i < LGSTRING_GLYPH_LEN (lgstring); i++)
1259 if (NILP (LGSTRING_GLYPH (lgstring, i))) 1254 if (NILP (LGSTRING_GLYPH (lgstring, i)))
1260 break; 1255 break;
diff --git a/src/data.c b/src/data.c
index 8e07bf01b44..12dc2df0bac 100644
--- a/src/data.c
+++ b/src/data.c
@@ -170,6 +170,12 @@ args_out_of_range_3 (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
170 xsignal3 (Qargs_out_of_range, a1, a2, a3); 170 xsignal3 (Qargs_out_of_range, a1, a2, a3);
171} 171}
172 172
173void
174circular_list (Lisp_Object list)
175{
176 xsignal1 (Qcircular_list, list);
177}
178
173 179
174/* Data type predicates. */ 180/* Data type predicates. */
175 181
diff --git a/src/dispextern.h b/src/dispextern.h
index eb71a82311c..e030618a9b7 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2215,7 +2215,7 @@ struct composition_it
2215 the automatic composition. Provided that ELT is an element of 2215 the automatic composition. Provided that ELT is an element of
2216 Vcomposition_function_table for CH, (nth ELT RULE_IDX) is the 2216 Vcomposition_function_table for CH, (nth ELT RULE_IDX) is the
2217 rule for the composition. */ 2217 rule for the composition. */
2218 int rule_idx; 2218 EMACS_INT rule_idx;
2219 /* If this is an automatic composition, how many characters to look 2219 /* If this is an automatic composition, how many characters to look
2220 back from the position where a character triggering the 2220 back from the position where a character triggering the
2221 composition exists. */ 2221 composition exists. */
diff --git a/src/fns.c b/src/fns.c
index ac7c1f265a4..ffe3218ca7d 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -108,23 +108,12 @@ To get the number of bytes, use `string-bytes'. */)
108 XSETFASTINT (val, ASIZE (sequence) & PSEUDOVECTOR_SIZE_MASK); 108 XSETFASTINT (val, ASIZE (sequence) & PSEUDOVECTOR_SIZE_MASK);
109 else if (CONSP (sequence)) 109 else if (CONSP (sequence))
110 { 110 {
111 EMACS_INT i = 0; 111 intptr_t i = 0;
112 112 FOR_EACH_TAIL (sequence)
113 do 113 i++;
114 {
115 ++i;
116 if ((i & (QUIT_COUNT_HEURISTIC - 1)) == 0)
117 {
118 if (MOST_POSITIVE_FIXNUM < i)
119 error ("List too long");
120 maybe_quit ();
121 }
122 sequence = XCDR (sequence);
123 }
124 while (CONSP (sequence));
125
126 CHECK_LIST_END (sequence, sequence); 114 CHECK_LIST_END (sequence, sequence);
127 115 if (MOST_POSITIVE_FIXNUM < i)
116 error ("List too long");
128 val = make_number (i); 117 val = make_number (i);
129 } 118 }
130 else if (NILP (sequence)) 119 else if (NILP (sequence))
@@ -142,38 +131,10 @@ it returns 0. If LIST is circular, it returns a finite value
142which is at least the number of distinct elements. */) 131which is at least the number of distinct elements. */)
143 (Lisp_Object list) 132 (Lisp_Object list)
144{ 133{
145 Lisp_Object tail, halftail; 134 intptr_t len = 0;
146 double hilen = 0; 135 FOR_EACH_TAIL_SAFE (list)
147 uintmax_t lolen = 1; 136 len++;
148 137 return make_fixnum_or_float (len);
149 if (! CONSP (list))
150 return make_number (0);
151
152 /* halftail is used to detect circular lists. */
153 for (tail = halftail = list; ; )
154 {
155 tail = XCDR (tail);
156 if (! CONSP (tail))
157 break;
158 if (EQ (tail, halftail))
159 break;
160 lolen++;
161 if ((lolen & 1) == 0)
162 {
163 halftail = XCDR (halftail);
164 if ((lolen & (QUIT_COUNT_HEURISTIC - 1)) == 0)
165 {
166 maybe_quit ();
167 if (lolen == 0)
168 hilen += UINTMAX_MAX + 1.0;
169 }
170 }
171 }
172
173 /* If the length does not fit into a fixnum, return a float.
174 On all known practical machines this returns an upper bound on
175 the true length. */
176 return hilen ? make_float (hilen + lolen) : make_fixnum_or_float (lolen);
177} 138}
178 139
179DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0, 140DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0,
@@ -1383,14 +1344,10 @@ DEFUN ("member", Fmember, Smember, 2, 2, 0,
1383The value is actually the tail of LIST whose car is ELT. */) 1344The value is actually the tail of LIST whose car is ELT. */)
1384 (Lisp_Object elt, Lisp_Object list) 1345 (Lisp_Object elt, Lisp_Object list)
1385{ 1346{
1386 unsigned short int quit_count = 0; 1347 Lisp_Object tail = list;
1387 Lisp_Object tail; 1348 FOR_EACH_TAIL (tail)
1388 for (tail = list; CONSP (tail); tail = XCDR (tail)) 1349 if (! NILP (Fequal (elt, XCAR (tail))))
1389 { 1350 return tail;
1390 if (! NILP (Fequal (elt, XCAR (tail))))
1391 return tail;
1392 rarely_quit (++quit_count);
1393 }
1394 CHECK_LIST_END (tail, list); 1351 CHECK_LIST_END (tail, list);
1395 return Qnil; 1352 return Qnil;
1396} 1353}
@@ -1400,14 +1357,10 @@ DEFUN ("memq", Fmemq, Smemq, 2, 2, 0,
1400The value is actually the tail of LIST whose car is ELT. */) 1357The value is actually the tail of LIST whose car is ELT. */)
1401 (Lisp_Object elt, Lisp_Object list) 1358 (Lisp_Object elt, Lisp_Object list)
1402{ 1359{
1403 unsigned short int quit_count = 0; 1360 Lisp_Object tail = list;
1404 Lisp_Object tail; 1361 FOR_EACH_TAIL (tail)
1405 for (tail = list; CONSP (tail); tail = XCDR (tail)) 1362 if (EQ (XCAR (tail), elt))
1406 { 1363 return tail;
1407 if (EQ (XCAR (tail), elt))
1408 return tail;
1409 rarely_quit (++quit_count);
1410 }
1411 CHECK_LIST_END (tail, list); 1364 CHECK_LIST_END (tail, list);
1412 return Qnil; 1365 return Qnil;
1413} 1366}
@@ -1420,14 +1373,12 @@ The value is actually the tail of LIST whose car is ELT. */)
1420 if (!FLOATP (elt)) 1373 if (!FLOATP (elt))
1421 return Fmemq (elt, list); 1374 return Fmemq (elt, list);
1422 1375
1423 unsigned short int quit_count = 0; 1376 Lisp_Object tail = list;
1424 Lisp_Object tail; 1377 FOR_EACH_TAIL (tail)
1425 for (tail = list; CONSP (tail); tail = XCDR (tail))
1426 { 1378 {
1427 Lisp_Object tem = XCAR (tail); 1379 Lisp_Object tem = XCAR (tail);
1428 if (FLOATP (tem) && internal_equal (elt, tem, 0, 0, Qnil)) 1380 if (FLOATP (tem) && internal_equal (elt, tem, 0, 0, Qnil))
1429 return tail; 1381 return tail;
1430 rarely_quit (++quit_count);
1431 } 1382 }
1432 CHECK_LIST_END (tail, list); 1383 CHECK_LIST_END (tail, list);
1433 return Qnil; 1384 return Qnil;
@@ -1439,14 +1390,10 @@ The value is actually the first element of LIST whose car is KEY.
1439Elements of LIST that are not conses are ignored. */) 1390Elements of LIST that are not conses are ignored. */)
1440 (Lisp_Object key, Lisp_Object list) 1391 (Lisp_Object key, Lisp_Object list)
1441{ 1392{
1442 unsigned short int quit_count = 0; 1393 Lisp_Object tail = list;
1443 Lisp_Object tail; 1394 FOR_EACH_TAIL (tail)
1444 for (tail = list; CONSP (tail); tail = XCDR (tail)) 1395 if (CONSP (XCAR (tail)) && EQ (XCAR (XCAR (tail)), key))
1445 { 1396 return XCAR (tail);
1446 if (CONSP (XCAR (tail)) && EQ (XCAR (XCAR (tail)), key))
1447 return XCAR (tail);
1448 rarely_quit (++quit_count);
1449 }
1450 CHECK_LIST_END (tail, list); 1397 CHECK_LIST_END (tail, list);
1451 return Qnil; 1398 return Qnil;
1452} 1399}
@@ -1468,15 +1415,13 @@ DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0,
1468The value is actually the first element of LIST whose car equals KEY. */) 1415The value is actually the first element of LIST whose car equals KEY. */)
1469 (Lisp_Object key, Lisp_Object list) 1416 (Lisp_Object key, Lisp_Object list)
1470{ 1417{
1471 unsigned short int quit_count = 0; 1418 Lisp_Object tail = list;
1472 Lisp_Object tail; 1419 FOR_EACH_TAIL (tail)
1473 for (tail = list; CONSP (tail); tail = XCDR (tail))
1474 { 1420 {
1475 Lisp_Object car = XCAR (tail); 1421 Lisp_Object car = XCAR (tail);
1476 if (CONSP (car) 1422 if (CONSP (car)
1477 && (EQ (XCAR (car), key) || !NILP (Fequal (XCAR (car), key)))) 1423 && (EQ (XCAR (car), key) || !NILP (Fequal (XCAR (car), key))))
1478 return car; 1424 return car;
1479 rarely_quit (++quit_count);
1480 } 1425 }
1481 CHECK_LIST_END (tail, list); 1426 CHECK_LIST_END (tail, list);
1482 return Qnil; 1427 return Qnil;
@@ -1503,14 +1448,10 @@ DEFUN ("rassq", Frassq, Srassq, 2, 2, 0,
1503The value is actually the first element of LIST whose cdr is KEY. */) 1448The value is actually the first element of LIST whose cdr is KEY. */)
1504 (Lisp_Object key, Lisp_Object list) 1449 (Lisp_Object key, Lisp_Object list)
1505{ 1450{
1506 unsigned short int quit_count = 0; 1451 Lisp_Object tail = list;
1507 Lisp_Object tail; 1452 FOR_EACH_TAIL (tail)
1508 for (tail = list; CONSP (tail); tail = XCDR (tail)) 1453 if (CONSP (XCAR (tail)) && EQ (XCDR (XCAR (tail)), key))
1509 { 1454 return XCAR (tail);
1510 if (CONSP (XCAR (tail)) && EQ (XCDR (XCAR (tail)), key))
1511 return XCAR (tail);
1512 rarely_quit (++quit_count);
1513 }
1514 CHECK_LIST_END (tail, list); 1455 CHECK_LIST_END (tail, list);
1515 return Qnil; 1456 return Qnil;
1516} 1457}
@@ -1520,15 +1461,13 @@ DEFUN ("rassoc", Frassoc, Srassoc, 2, 2, 0,
1520The value is actually the first element of LIST whose cdr equals KEY. */) 1461The value is actually the first element of LIST whose cdr equals KEY. */)
1521 (Lisp_Object key, Lisp_Object list) 1462 (Lisp_Object key, Lisp_Object list)
1522{ 1463{
1523 unsigned short int quit_count = 0; 1464 Lisp_Object tail = list;
1524 Lisp_Object tail; 1465 FOR_EACH_TAIL (tail)
1525 for (tail = list; CONSP (tail); tail = XCDR (tail))
1526 { 1466 {
1527 Lisp_Object car = XCAR (tail); 1467 Lisp_Object car = XCAR (tail);
1528 if (CONSP (car) 1468 if (CONSP (car)
1529 && (EQ (XCDR (car), key) || !NILP (Fequal (XCDR (car), key)))) 1469 && (EQ (XCDR (car), key) || !NILP (Fequal (XCDR (car), key))))
1530 return car; 1470 return car;
1531 rarely_quit (++quit_count);
1532 } 1471 }
1533 CHECK_LIST_END (tail, list); 1472 CHECK_LIST_END (tail, list);
1534 return Qnil; 1473 return Qnil;
@@ -1544,12 +1483,11 @@ list.
1544Write `(setq foo (delq element foo))' to be sure of correctly changing 1483Write `(setq foo (delq element foo))' to be sure of correctly changing
1545the value of a list `foo'. See also `remq', which does not modify the 1484the value of a list `foo'. See also `remq', which does not modify the
1546argument. */) 1485argument. */)
1547 (register Lisp_Object elt, Lisp_Object list) 1486 (Lisp_Object elt, Lisp_Object list)
1548{ 1487{
1549 Lisp_Object tail, tortoise, prev = Qnil; 1488 Lisp_Object prev = Qnil, tail = list;
1550 bool skip;
1551 1489
1552 FOR_EACH_TAIL (tail, list, tortoise, skip) 1490 FOR_EACH_TAIL (tail)
1553 { 1491 {
1554 Lisp_Object tem = XCAR (tail); 1492 Lisp_Object tem = XCAR (tail);
1555 if (EQ (elt, tem)) 1493 if (EQ (elt, tem))
@@ -1670,10 +1608,9 @@ changing the value of a sequence `foo'. */)
1670 } 1608 }
1671 else 1609 else
1672 { 1610 {
1673 unsigned short int quit_count = 0; 1611 Lisp_Object prev = Qnil, tail = seq;
1674 Lisp_Object tail, prev;
1675 1612
1676 for (tail = seq, prev = Qnil; CONSP (tail); tail = XCDR (tail)) 1613 FOR_EACH_TAIL (tail)
1677 { 1614 {
1678 if (!NILP (Fequal (elt, XCAR (tail)))) 1615 if (!NILP (Fequal (elt, XCAR (tail))))
1679 { 1616 {
@@ -1684,7 +1621,6 @@ changing the value of a sequence `foo'. */)
1684 } 1621 }
1685 else 1622 else
1686 prev = tail; 1623 prev = tail;
1687 rarely_quit (++quit_count);
1688 } 1624 }
1689 CHECK_LIST_END (tail, seq); 1625 CHECK_LIST_END (tail, seq);
1690 } 1626 }
@@ -1704,15 +1640,17 @@ This function may destructively modify SEQ to produce the value. */)
1704 return Freverse (seq); 1640 return Freverse (seq);
1705 else if (CONSP (seq)) 1641 else if (CONSP (seq))
1706 { 1642 {
1707 unsigned short int quit_count = 0;
1708 Lisp_Object prev, tail, next; 1643 Lisp_Object prev, tail, next;
1709 1644
1710 for (prev = Qnil, tail = seq; CONSP (tail); tail = next) 1645 for (prev = Qnil, tail = seq; CONSP (tail); tail = next)
1711 { 1646 {
1712 next = XCDR (tail); 1647 next = XCDR (tail);
1648 /* If SEQ contains a cycle, attempting to reverse it
1649 in-place will inevitably come back to SEQ. */
1650 if (EQ (next, seq))
1651 circular_list (seq);
1713 Fsetcdr (tail, prev); 1652 Fsetcdr (tail, prev);
1714 prev = tail; 1653 prev = tail;
1715 rarely_quit (++quit_count);
1716 } 1654 }
1717 CHECK_LIST_END (tail, seq); 1655 CHECK_LIST_END (tail, seq);
1718 seq = prev; 1656 seq = prev;
@@ -1755,12 +1693,9 @@ See also the function `nreverse', which is used more often. */)
1755 return Qnil; 1693 return Qnil;
1756 else if (CONSP (seq)) 1694 else if (CONSP (seq))
1757 { 1695 {
1758 unsigned short int quit_count = 0; 1696 new = Qnil;
1759 for (new = Qnil; CONSP (seq); seq = XCDR (seq)) 1697 FOR_EACH_TAIL (seq)
1760 { 1698 new = Fcons (XCAR (seq), new);
1761 new = Fcons (XCAR (seq), new);
1762 rarely_quit (++quit_count);
1763 }
1764 CHECK_LIST_END (seq, seq); 1699 CHECK_LIST_END (seq, seq);
1765 } 1700 }
1766 else if (VECTORP (seq)) 1701 else if (VECTORP (seq))
@@ -2013,18 +1948,15 @@ corresponding to the given PROP, or nil if PROP is not one of the
2013properties on the list. This function never signals an error. */) 1948properties on the list. This function never signals an error. */)
2014 (Lisp_Object plist, Lisp_Object prop) 1949 (Lisp_Object plist, Lisp_Object prop)
2015{ 1950{
2016 Lisp_Object tail, halftail; 1951 Lisp_Object tail = plist;
2017 1952 FOR_EACH_TAIL_SAFE (tail)
2018 /* halftail is used to detect circular lists. */
2019 tail = halftail = plist;
2020 while (CONSP (tail) && CONSP (XCDR (tail)))
2021 { 1953 {
1954 if (! CONSP (XCDR (tail)))
1955 break;
2022 if (EQ (prop, XCAR (tail))) 1956 if (EQ (prop, XCAR (tail)))
2023 return XCAR (XCDR (tail)); 1957 return XCAR (XCDR (tail));
2024 1958 tail = XCDR (tail);
2025 tail = XCDR (XCDR (tail)); 1959 if (EQ (tail, li.tortoise))
2026 halftail = XCDR (halftail);
2027 if (EQ (tail, halftail))
2028 break; 1960 break;
2029 } 1961 }
2030 1962
@@ -2050,11 +1982,12 @@ use `(setq x (plist-put x prop val))' to be sure to use the new value.
2050The PLIST is modified by side effects. */) 1982The PLIST is modified by side effects. */)
2051 (Lisp_Object plist, Lisp_Object prop, Lisp_Object val) 1983 (Lisp_Object plist, Lisp_Object prop, Lisp_Object val)
2052{ 1984{
2053 unsigned short int quit_count = 0; 1985 Lisp_Object prev = Qnil, tail = plist;
2054 Lisp_Object prev = Qnil; 1986 FOR_EACH_TAIL (tail)
2055 for (Lisp_Object tail = plist; CONSP (tail) && CONSP (XCDR (tail));
2056 tail = XCDR (XCDR (tail)))
2057 { 1987 {
1988 if (! CONSP (XCDR (tail)))
1989 break;
1990
2058 if (EQ (prop, XCAR (tail))) 1991 if (EQ (prop, XCAR (tail)))
2059 { 1992 {
2060 Fsetcar (XCDR (tail), val); 1993 Fsetcar (XCDR (tail), val);
@@ -2062,8 +1995,11 @@ The PLIST is modified by side effects. */)
2062 } 1995 }
2063 1996
2064 prev = tail; 1997 prev = tail;
2065 rarely_quit (++quit_count); 1998 tail = XCDR (tail);
1999 if (EQ (tail, li.tortoise))
2000 circular_list (plist);
2066 } 2001 }
2002 CHECK_LIST_END (tail, plist);
2067 Lisp_Object newcell 2003 Lisp_Object newcell
2068 = Fcons (prop, Fcons (val, NILP (prev) ? plist : XCDR (XCDR (prev)))); 2004 = Fcons (prop, Fcons (val, NILP (prev) ? plist : XCDR (XCDR (prev))));
2069 if (NILP (prev)) 2005 if (NILP (prev))
@@ -2091,19 +2027,19 @@ corresponding to the given PROP, or nil if PROP is not
2091one of the properties on the list. */) 2027one of the properties on the list. */)
2092 (Lisp_Object plist, Lisp_Object prop) 2028 (Lisp_Object plist, Lisp_Object prop)
2093{ 2029{
2094 unsigned short int quit_count = 0; 2030 Lisp_Object tail = plist;
2095 Lisp_Object tail; 2031 FOR_EACH_TAIL (tail)
2096
2097 for (tail = plist;
2098 CONSP (tail) && CONSP (XCDR (tail));
2099 tail = XCDR (XCDR (tail)))
2100 { 2032 {
2033 if (! CONSP (XCDR (tail)))
2034 break;
2101 if (! NILP (Fequal (prop, XCAR (tail)))) 2035 if (! NILP (Fequal (prop, XCAR (tail))))
2102 return XCAR (XCDR (tail)); 2036 return XCAR (XCDR (tail));
2103 rarely_quit (++quit_count); 2037 tail = XCDR (tail);
2038 if (EQ (tail, li.tortoise))
2039 circular_list (plist);
2104 } 2040 }
2105 2041
2106 CHECK_LIST_END (tail, prop); 2042 CHECK_LIST_END (tail, plist);
2107 2043
2108 return Qnil; 2044 return Qnil;
2109} 2045}
@@ -2118,11 +2054,12 @@ use `(setq x (lax-plist-put x prop val))' to be sure to use the new value.
2118The PLIST is modified by side effects. */) 2054The PLIST is modified by side effects. */)
2119 (Lisp_Object plist, Lisp_Object prop, Lisp_Object val) 2055 (Lisp_Object plist, Lisp_Object prop, Lisp_Object val)
2120{ 2056{
2121 unsigned short int quit_count = 0; 2057 Lisp_Object prev = Qnil, tail = plist;
2122 Lisp_Object prev = Qnil; 2058 FOR_EACH_TAIL (tail)
2123 for (Lisp_Object tail = plist; CONSP (tail) && CONSP (XCDR (tail));
2124 tail = XCDR (XCDR (tail)))
2125 { 2059 {
2060 if (! CONSP (XCDR (tail)))
2061 break;
2062
2126 if (! NILP (Fequal (prop, XCAR (tail)))) 2063 if (! NILP (Fequal (prop, XCAR (tail))))
2127 { 2064 {
2128 Fsetcar (XCDR (tail), val); 2065 Fsetcar (XCDR (tail), val);
@@ -2130,8 +2067,11 @@ The PLIST is modified by side effects. */)
2130 } 2067 }
2131 2068
2132 prev = tail; 2069 prev = tail;
2133 rarely_quit (++quit_count); 2070 tail = XCDR (tail);
2071 if (EQ (tail, li.tortoise))
2072 circular_list (plist);
2134 } 2073 }
2074 CHECK_LIST_END (tail, plist);
2135 Lisp_Object newcell = list2 (prop, val); 2075 Lisp_Object newcell = list2 (prop, val);
2136 if (NILP (prev)) 2076 if (NILP (prev))
2137 return newcell; 2077 return newcell;
@@ -2180,6 +2120,7 @@ static bool
2180internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props, 2120internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props,
2181 Lisp_Object ht) 2121 Lisp_Object ht)
2182{ 2122{
2123 tail_recurse:
2183 if (depth > 10) 2124 if (depth > 10)
2184 { 2125 {
2185 if (depth > 200) 2126 if (depth > 200)
@@ -2208,9 +2149,6 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props,
2208 } 2149 }
2209 } 2150 }
2210 2151
2211 unsigned short int quit_count = 0;
2212 tail_recurse:
2213 rarely_quit (++quit_count);
2214 if (EQ (o1, o2)) 2152 if (EQ (o1, o2))
2215 return 1; 2153 return 1;
2216 if (XTYPE (o1) != XTYPE (o2)) 2154 if (XTYPE (o1) != XTYPE (o2))
@@ -2230,12 +2168,20 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props,
2230 } 2168 }
2231 2169
2232 case Lisp_Cons: 2170 case Lisp_Cons:
2233 if (!internal_equal (XCAR (o1), XCAR (o2), depth + 1, props, ht)) 2171 {
2234 return 0; 2172 FOR_EACH_TAIL (o1)
2235 o1 = XCDR (o1); 2173 {
2236 o2 = XCDR (o2); 2174 if (! CONSP (o2))
2237 /* FIXME: This inf-loops in a circular list! */ 2175 return false;
2238 goto tail_recurse; 2176 if (! internal_equal (XCAR (o1), XCAR (o2), depth + 1, props, ht))
2177 return false;
2178 o2 = XCDR (o2);
2179 if (EQ (XCDR (o1), o2))
2180 return true;
2181 }
2182 depth++;
2183 goto tail_recurse;
2184 }
2239 2185
2240 case Lisp_Misc: 2186 case Lisp_Misc:
2241 if (XMISCTYPE (o1) != XMISCTYPE (o2)) 2187 if (XMISCTYPE (o1) != XMISCTYPE (o2))
@@ -2249,6 +2195,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props,
2249 return 0; 2195 return 0;
2250 o1 = XOVERLAY (o1)->plist; 2196 o1 = XOVERLAY (o1)->plist;
2251 o2 = XOVERLAY (o2)->plist; 2197 o2 = XOVERLAY (o2)->plist;
2198 depth++;
2252 goto tail_recurse; 2199 goto tail_recurse;
2253 } 2200 }
2254 if (MARKERP (o1)) 2201 if (MARKERP (o1))
@@ -2399,7 +2346,6 @@ Only the last argument is not altered, and need not be a list.
2399usage: (nconc &rest LISTS) */) 2346usage: (nconc &rest LISTS) */)
2400 (ptrdiff_t nargs, Lisp_Object *args) 2347 (ptrdiff_t nargs, Lisp_Object *args)
2401{ 2348{
2402 unsigned short int quit_count = 0;
2403 Lisp_Object val = Qnil; 2349 Lisp_Object val = Qnil;
2404 2350
2405 for (ptrdiff_t argnum = 0; argnum < nargs; argnum++) 2351 for (ptrdiff_t argnum = 0; argnum < nargs; argnum++)
@@ -2415,13 +2361,8 @@ usage: (nconc &rest LISTS) */)
2415 CHECK_CONS (tem); 2361 CHECK_CONS (tem);
2416 2362
2417 Lisp_Object tail; 2363 Lisp_Object tail;
2418 do 2364 FOR_EACH_TAIL (tem)
2419 { 2365 tail = tem;
2420 tail = tem;
2421 tem = XCDR (tail);
2422 rarely_quit (++quit_count);
2423 }
2424 while (CONSP (tem));
2425 2366
2426 tem = args[argnum + 1]; 2367 tem = args[argnum + 1];
2427 Fsetcdr (tail, tem); 2368 Fsetcdr (tail, tem);
@@ -2843,14 +2784,19 @@ property and a property with the value nil.
2843The value is actually the tail of PLIST whose car is PROP. */) 2784The value is actually the tail of PLIST whose car is PROP. */)
2844 (Lisp_Object plist, Lisp_Object prop) 2785 (Lisp_Object plist, Lisp_Object prop)
2845{ 2786{
2846 unsigned short int quit_count = 0; 2787 Lisp_Object tail = plist;
2847 while (CONSP (plist) && !EQ (XCAR (plist), prop)) 2788 FOR_EACH_TAIL (tail)
2848 { 2789 {
2849 plist = XCDR (plist); 2790 if (EQ (XCAR (tail), prop))
2850 plist = CDR (plist); 2791 return tail;
2851 rarely_quit (++quit_count); 2792 tail = XCDR (tail);
2793 if (! CONSP (tail))
2794 break;
2795 if (EQ (tail, li.tortoise))
2796 circular_list (tail);
2852 } 2797 }
2853 return plist; 2798 CHECK_LIST_END (tail, plist);
2799 return Qnil;
2854} 2800}
2855 2801
2856DEFUN ("widget-put", Fwidget_put, Swidget_put, 3, 3, 0, 2802DEFUN ("widget-put", Fwidget_put, Swidget_put, 3, 3, 0,
diff --git a/src/image.c b/src/image.c
index ad0143be48b..1e8ebfd40d5 100644
--- a/src/image.c
+++ b/src/image.c
@@ -3110,8 +3110,8 @@ xbm_load (struct frame *f, struct image *img)
3110 int nbytes, i; 3110 int nbytes, i;
3111 /* Windows mono bitmaps are reversed compared with X. */ 3111 /* Windows mono bitmaps are reversed compared with X. */
3112 invertedBits = bits; 3112 invertedBits = bits;
3113 nbytes = (img->width + CHAR_BIT - 1) / CHAR_BIT; 3113 nbytes = (img->width + CHAR_BIT - 1) / CHAR_BIT * img->height;
3114 SAFE_NALLOCA (bits, nbytes, img->height); 3114 SAFE_NALLOCA (bits, 1, nbytes);
3115 for (i = 0; i < nbytes; i++) 3115 for (i = 0; i < nbytes; i++)
3116 bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]); 3116 bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]);
3117 } 3117 }
@@ -5465,7 +5465,17 @@ pbm_load (struct frame *f, struct image *img)
5465 c <<= 1; 5465 c <<= 1;
5466 } 5466 }
5467 else 5467 else
5468 g = pbm_scan_number (&p, end); 5468 {
5469 int c = 0;
5470 /* Skip white-space and comments. */
5471 while ((c = pbm_next_char (&p, end)) != -1 && c_isspace (c))
5472 ;
5473
5474 if (c == '0' || c == '1')
5475 g = c - '0';
5476 else
5477 g = 0;
5478 }
5469 5479
5470#ifdef USE_CAIRO 5480#ifdef USE_CAIRO
5471 *dataptr++ = g ? fga32 : bga32; 5481 *dataptr++ = g ? fga32 : bga32;
diff --git a/src/keyboard.c b/src/keyboard.c
index a86e7c5f8e4..ed8e71fd0a7 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -10001,6 +10001,30 @@ See also `this-command-keys-vector'. */)
10001 XVECTOR (this_command_keys)->contents); 10001 XVECTOR (this_command_keys)->contents);
10002} 10002}
10003 10003
10004DEFUN ("set--this-command-keys", Fset__this_command_keys,
10005 Sset__this_command_keys, 1, 1, 0,
10006 doc: /* Set the vector to be returned by `this-command-keys'.
10007The argument KEYS must be a string.
10008Internal use only. */)
10009 (Lisp_Object keys)
10010{
10011 CHECK_STRING (keys);
10012
10013 this_command_key_count = 0;
10014 this_single_command_key_start = 0;
10015 int key0 = SREF (keys, 0);
10016
10017 /* Kludge alert: this makes M-x be in the form expected by
10018 novice.el. Any better ideas? */
10019 if (key0 == 248)
10020 add_command_key (make_number ('x' | meta_modifier));
10021 else
10022 add_command_key (make_number (key0));
10023 for (ptrdiff_t i = 1; i < SCHARS (keys); i++)
10024 add_command_key (make_number (SREF (keys, i)));
10025 return Qnil;
10026}
10027
10004DEFUN ("this-command-keys-vector", Fthis_command_keys_vector, Sthis_command_keys_vector, 0, 0, 0, 10028DEFUN ("this-command-keys-vector", Fthis_command_keys_vector, Sthis_command_keys_vector, 0, 0, 0,
10005 doc: /* Return the key sequence that invoked this command, as a vector. 10029 doc: /* Return the key sequence that invoked this command, as a vector.
10006However, if the command has called `read-key-sequence', it returns 10030However, if the command has called `read-key-sequence', it returns
@@ -11211,6 +11235,7 @@ syms_of_keyboard (void)
11211 defsubr (&Sthis_command_keys_vector); 11235 defsubr (&Sthis_command_keys_vector);
11212 defsubr (&Sthis_single_command_keys); 11236 defsubr (&Sthis_single_command_keys);
11213 defsubr (&Sthis_single_command_raw_keys); 11237 defsubr (&Sthis_single_command_raw_keys);
11238 defsubr (&Sset__this_command_keys);
11214 defsubr (&Sclear_this_command_keys); 11239 defsubr (&Sclear_this_command_keys);
11215 defsubr (&Ssuspend_emacs); 11240 defsubr (&Ssuspend_emacs);
11216 defsubr (&Sabort_recursive_edit); 11241 defsubr (&Sabort_recursive_edit);
diff --git a/src/lisp.h b/src/lisp.h
index a9011b4a8be..f1e2685702d 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3129,20 +3129,14 @@ extern void maybe_quit (void);
3129 3129
3130#define QUITP (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) 3130#define QUITP (!NILP (Vquit_flag) && NILP (Vinhibit_quit))
3131 3131
3132/* Heuristic on how many iterations of a tight loop can be safely done
3133 before it's time to do a quit. This must be a power of 2. It
3134 is nice but not necessary for it to equal USHRT_MAX + 1. */
3135
3136enum { QUIT_COUNT_HEURISTIC = 1 << 16 };
3137
3138/* Process a quit rarely, based on a counter COUNT, for efficiency. 3132/* Process a quit rarely, based on a counter COUNT, for efficiency.
3139 "Rarely" means once per QUIT_COUNT_HEURISTIC or per USHRT_MAX + 1 3133 "Rarely" means once per USHRT_MAX + 1 times; this is somewhat
3140 times, whichever is smaller (somewhat arbitrary, but often faster). */ 3134 arbitrary, but efficient. */
3141 3135
3142INLINE void 3136INLINE void
3143rarely_quit (unsigned short int count) 3137rarely_quit (unsigned short int count)
3144{ 3138{
3145 if (! (count & (QUIT_COUNT_HEURISTIC - 1))) 3139 if (! count)
3146 maybe_quit (); 3140 maybe_quit ();
3147} 3141}
3148 3142
@@ -3317,6 +3311,7 @@ extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *);
3317extern _Noreturn void args_out_of_range (Lisp_Object, Lisp_Object); 3311extern _Noreturn void args_out_of_range (Lisp_Object, Lisp_Object);
3318extern _Noreturn void args_out_of_range_3 (Lisp_Object, Lisp_Object, 3312extern _Noreturn void args_out_of_range_3 (Lisp_Object, Lisp_Object,
3319 Lisp_Object); 3313 Lisp_Object);
3314extern _Noreturn void circular_list (Lisp_Object);
3320extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *); 3315extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *);
3321enum Set_Internal_Bind { 3316enum Set_Internal_Bind {
3322 SET_INTERNAL_SET, 3317 SET_INTERNAL_SET,
@@ -4585,20 +4580,54 @@ enum
4585 Lisp_String)) \ 4580 Lisp_String)) \
4586 : make_unibyte_string (str, len)) 4581 : make_unibyte_string (str, len))
4587 4582
4588/* Loop over all tails of a list, checking for cycles. 4583/* Loop over conses of the list TAIL, signaling if a cycle is found,
4589 FIXME: Make tortoise and n internal declarations. 4584 and possibly quitting after each loop iteration. In the loop body,
4590 FIXME: Unroll the loop body so we don't need `n'. */ 4585 set TAIL to the current cons. If the loop exits normally,
4591#define FOR_EACH_TAIL(hare, list, tortoise, n) \ 4586 set TAIL to the terminating non-cons, typically nil. The loop body
4592 for ((tortoise) = (hare) = (list), (n) = true; \ 4587 should not modify the list’s top level structure other than by
4593 CONSP (hare); \ 4588 perhaps deleting the current cons. */
4594 (hare = XCDR (hare), (n) = !(n), \ 4589
4595 ((n) \ 4590#define FOR_EACH_TAIL(tail) \
4596 ? (EQ (hare, tortoise) \ 4591 FOR_EACH_TAIL_INTERNAL (tail, circular_list (tail), true)
4597 ? xsignal1 (Qcircular_list, list) \ 4592
4598 : (void) 0) \ 4593/* Like FOR_EACH_TAIL (LIST), except do not signal or quit.
4599 /* Move tortoise before the next iteration, in case */ \ 4594 If the loop exits due to a cycle, TAIL’s value is undefined. */
4600 /* the next iteration does an Fsetcdr. */ \ 4595
4601 : (void) ((tortoise) = XCDR (tortoise))))) 4596#define FOR_EACH_TAIL_SAFE(tail) \
4597 FOR_EACH_TAIL_INTERNAL (tail, (void) ((tail) = Qnil), false)
4598
4599/* Iterator intended for use only within FOR_EACH_TAIL_INTERNAL. */
4600struct for_each_tail_internal
4601{
4602 Lisp_Object tortoise;
4603 intptr_t max, n;
4604 unsigned short int q;
4605};
4606
4607/* Like FOR_EACH_TAIL (LIST), except evaluate CYCLE if a cycle is
4608 found, and check for quit if CHECK_QUIT. This is an internal macro
4609 intended for use only by the above macros.
4610
4611 Use Brent’s teleporting tortoise-hare algorithm. See:
4612 Brent RP. BIT. 1980;20(2):176-84. doi:10.1007/BF01933190
4613 http://maths-people.anu.edu.au/~brent/pd/rpb051i.pdf
4614
4615 This macro uses maybe_quit because of an excess of caution. The
4616 call to maybe_quit should not be needed in practice, as a very long
4617 list, whether circular or not, will cause Emacs to be so slow in
4618 other noninterruptible areas (e.g., garbage collection) that there
4619 is little point to calling maybe_quit here. */
4620
4621#define FOR_EACH_TAIL_INTERNAL(tail, cycle, check_quit) \
4622 for (struct for_each_tail_internal li = { tail, 2, 0, 2 }; \
4623 CONSP (tail); \
4624 ((tail) = XCDR (tail), \
4625 ((--li.q != 0 \
4626 || ((check_quit) ? maybe_quit () : (void) 0, 0 < --li.n) \
4627 || (li.q = li.n = li.max <<= 1, li.n >>= USHRT_WIDTH, \
4628 li.tortoise = (tail), false)) \
4629 && EQ (tail, li.tortoise)) \
4630 ? (cycle) : (void) 0))
4602 4631
4603/* Do a `for' loop over alist values. */ 4632/* Do a `for' loop over alist values. */
4604 4633
diff --git a/src/xdisp.c b/src/xdisp.c
index 0e329dfe6e9..e59934d2d5a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -18972,7 +18972,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
18972 glyph->pixel_width, 18972 glyph->pixel_width,
18973 glyph->u.ch, 18973 glyph->u.ch,
18974 (glyph->u.ch < 0x80 && glyph->u.ch >= ' ' 18974 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
18975 ? glyph->u.ch 18975 ? (int) glyph->u.ch
18976 : '.'), 18976 : '.'),
18977 glyph->face_id, 18977 glyph->face_id,
18978 glyph->left_box_line_p, 18978 glyph->left_box_line_p,
@@ -18993,7 +18993,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
18993 ? '0' 18993 ? '0'
18994 : '-'))), 18994 : '-'))),
18995 glyph->pixel_width, 18995 glyph->pixel_width,
18996 0, 18996 0u,
18997 ' ', 18997 ' ',
18998 glyph->face_id, 18998 glyph->face_id,
18999 glyph->left_box_line_p, 18999 glyph->left_box_line_p,
@@ -19014,7 +19014,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
19014 ? '0' 19014 ? '0'
19015 : '-'))), 19015 : '-'))),
19016 glyph->pixel_width, 19016 glyph->pixel_width,
19017 glyph->u.img_id, 19017 (unsigned int) glyph->u.img_id,
19018 '.', 19018 '.',
19019 glyph->face_id, 19019 glyph->face_id,
19020 glyph->left_box_line_p, 19020 glyph->left_box_line_p,
@@ -19035,7 +19035,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
19035 ? '0' 19035 ? '0'
19036 : '-'))), 19036 : '-'))),
19037 glyph->pixel_width, 19037 glyph->pixel_width,
19038 glyph->u.cmp.id); 19038 (unsigned int) glyph->u.cmp.id);
19039 if (glyph->u.cmp.automatic) 19039 if (glyph->u.cmp.automatic)
19040 fprintf (stderr, 19040 fprintf (stderr,
19041 "[%d-%d]", 19041 "[%d-%d]",
@@ -20995,7 +20995,10 @@ display_line (struct it *it)
20995 up to the right margin of the window. */ 20995 up to the right margin of the window. */
20996 extend_face_to_end_of_line (it); 20996 extend_face_to_end_of_line (it);
20997 } 20997 }
20998 else if (it->c == '\t' && FRAME_WINDOW_P (it->f)) 20998 else if ((it->what == IT_CHARACTER
20999 || it->what == IT_STRETCH
21000 || it->what == IT_COMPOSITION)
21001 && it->c == '\t' && FRAME_WINDOW_P (it->f))
20999 { 21002 {
21000 /* A TAB that extends past the right edge of the 21003 /* A TAB that extends past the right edge of the
21001 window. This produces a single glyph on 21004 window. This produces a single glyph on
@@ -23033,30 +23036,19 @@ display_mode_element (struct it *it, int depth, int field_width, int precision,
23033 goto tail_recurse; 23036 goto tail_recurse;
23034 } 23037 }
23035 else if (STRINGP (car) || CONSP (car)) 23038 else if (STRINGP (car) || CONSP (car))
23036 { 23039 FOR_EACH_TAIL_SAFE (elt)
23037 Lisp_Object halftail = elt; 23040 {
23038 int len = 0; 23041 if (0 < precision && precision <= n)
23039 23042 break;
23040 while (CONSP (elt) 23043 n += display_mode_element (it, depth,
23041 && (precision <= 0 || n < precision)) 23044 /* Pad after only the last
23042 { 23045 list element. */
23043 n += display_mode_element (it, depth, 23046 (! CONSP (XCDR (elt))
23044 /* Do padding only after the last 23047 ? field_width - n
23045 element in the list. */ 23048 : 0),
23046 (! CONSP (XCDR (elt)) 23049 precision - n, XCAR (elt),
23047 ? field_width - n 23050 props, risky);
23048 : 0), 23051 }
23049 precision - n, XCAR (elt),
23050 props, risky);
23051 elt = XCDR (elt);
23052 len++;
23053 if ((len & 1) == 0)
23054 halftail = XCDR (halftail);
23055 /* Check for cycle. */
23056 if (EQ (halftail, elt))
23057 break;
23058 }
23059 }
23060 } 23052 }
23061 break; 23053 break;
23062 23054
@@ -24624,7 +24616,7 @@ dump_glyph_string (struct glyph_string *s)
24624 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n", 24616 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
24625 s->x, s->y, s->width, s->height); 24617 s->x, s->y, s->width, s->height);
24626 fprintf (stderr, " ybase = %d\n", s->ybase); 24618 fprintf (stderr, " ybase = %d\n", s->ybase);
24627 fprintf (stderr, " hl = %d\n", s->hl); 24619 fprintf (stderr, " hl = %u\n", s->hl);
24628 fprintf (stderr, " left overhang = %d, right = %d\n", 24620 fprintf (stderr, " left overhang = %d, right = %d\n",
24629 s->left_overhang, s->right_overhang); 24621 s->left_overhang, s->right_overhang);
24630 fprintf (stderr, " nchars = %d\n", s->nchars); 24622 fprintf (stderr, " nchars = %d\n", s->nchars);
diff --git a/src/xfaces.c b/src/xfaces.c
index 830106d64c0..b5dbb53ca20 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -6251,7 +6251,7 @@ dump_realized_face (struct face *face)
6251 fprintf (stderr, "underline: %d (%s)\n", 6251 fprintf (stderr, "underline: %d (%s)\n",
6252 face->underline_p, 6252 face->underline_p,
6253 SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))); 6253 SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX])));
6254 fprintf (stderr, "hash: %d\n", face->hash); 6254 fprintf (stderr, "hash: %u\n", face->hash);
6255} 6255}
6256 6256
6257 6257
diff --git a/src/xwidget.c b/src/xwidget.c
index 4ba1617d8df..5c276b1371c 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -301,13 +301,13 @@ webkit_js_to_lisp (JSContextRef context, JSValueRef value)
301 { 301 {
302 JSStringRef pname = JSStringCreateWithUTF8CString("length"); 302 JSStringRef pname = JSStringCreateWithUTF8CString("length");
303 JSValueRef len = JSObjectGetProperty (context, (JSObjectRef) value, pname, NULL); 303 JSValueRef len = JSObjectGetProperty (context, (JSObjectRef) value, pname, NULL);
304 int n = JSValueToNumber (context, len, NULL); 304 EMACS_INT n = JSValueToNumber (context, len, NULL);
305 JSStringRelease(pname); 305 JSStringRelease(pname);
306 306
307 Lisp_Object obj; 307 Lisp_Object obj;
308 struct Lisp_Vector *p = allocate_vector (n); 308 struct Lisp_Vector *p = allocate_vector (n);
309 309
310 for (int i = 0; i < n; ++i) 310 for (ptrdiff_t i = 0; i < n; ++i)
311 { 311 {
312 p->contents[i] = 312 p->contents[i] =
313 webkit_js_to_lisp (context, 313 webkit_js_to_lisp (context,
@@ -323,13 +323,13 @@ webkit_js_to_lisp (JSContextRef context, JSValueRef value)
323 JSPropertyNameArrayRef properties = 323 JSPropertyNameArrayRef properties =
324 JSObjectCopyPropertyNames (context, (JSObjectRef) value); 324 JSObjectCopyPropertyNames (context, (JSObjectRef) value);
325 325
326 int n = JSPropertyNameArrayGetCount (properties); 326 ptrdiff_t n = JSPropertyNameArrayGetCount (properties);
327 Lisp_Object obj; 327 Lisp_Object obj;
328 328
329 /* TODO: can we use a regular list here? */ 329 /* TODO: can we use a regular list here? */
330 struct Lisp_Vector *p = allocate_vector (n); 330 struct Lisp_Vector *p = allocate_vector (n);
331 331
332 for (int i = 0; i < n; ++i) 332 for (ptrdiff_t i = 0; i < n; ++i)
333 { 333 {
334 JSStringRef name = JSPropertyNameArrayGetNameAtIndex (properties, i); 334 JSStringRef name = JSPropertyNameArrayGetNameAtIndex (properties, i);
335 JSValueRef property = JSObjectGetProperty (context, 335 JSValueRef property = JSObjectGetProperty (context,
@@ -733,8 +733,8 @@ DEFUN ("xwidget-resize", Fxwidget_resize, Sxwidget_resize, 3, 3, 0,
733 (Lisp_Object xwidget, Lisp_Object new_width, Lisp_Object new_height) 733 (Lisp_Object xwidget, Lisp_Object new_width, Lisp_Object new_height)
734{ 734{
735 CHECK_XWIDGET (xwidget); 735 CHECK_XWIDGET (xwidget);
736 CHECK_NATNUM (new_width); 736 CHECK_RANGED_INTEGER (new_width, 0, INT_MAX);
737 CHECK_NATNUM (new_height); 737 CHECK_RANGED_INTEGER (new_height, 0, INT_MAX);
738 struct xwidget *xw = XXWIDGET (xwidget); 738 struct xwidget *xw = XXWIDGET (xwidget);
739 int w = XFASTINT (new_width); 739 int w = XFASTINT (new_width);
740 int h = XFASTINT (new_height); 740 int h = XFASTINT (new_height);