diff options
| author | Vibhav Pant | 2017-02-11 19:54:37 +0530 |
|---|---|---|
| committer | Vibhav Pant | 2017-02-11 19:54:37 +0530 |
| commit | c1a9b5db0e2985e7c46fb3b1e50e9d17785f7fa3 (patch) | |
| tree | a33cb8c57d628541baee88bef5b0907327056e88 /src | |
| parent | a75d080b17a6b6c6296ff4e24d8129d77bb3bb6b (diff) | |
| parent | ac83b2dfe4504babfbafc5efb37dbde4bed34fed (diff) | |
| download | emacs-c1a9b5db0e2985e7c46fb3b1e50e9d17785f7fa3.tar.gz emacs-c1a9b5db0e2985e7c46fb3b1e50e9d17785f7fa3.zip | |
Merge branch 'master' into feature/byte-switch
Diffstat (limited to 'src')
| -rw-r--r-- | src/composite.c | 89 | ||||
| -rw-r--r-- | src/data.c | 6 | ||||
| -rw-r--r-- | src/dispextern.h | 2 | ||||
| -rw-r--r-- | src/fns.c | 262 | ||||
| -rw-r--r-- | src/image.c | 16 | ||||
| -rw-r--r-- | src/keyboard.c | 25 | ||||
| -rw-r--r-- | src/lisp.h | 75 | ||||
| -rw-r--r-- | src/xdisp.c | 52 | ||||
| -rw-r--r-- | src/xfaces.c | 2 | ||||
| -rw-r--r-- | src/xwidget.c | 12 |
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 | ||
| 173 | void | ||
| 174 | circular_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. */ |
| @@ -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 | |||
| 142 | which is at least the number of distinct elements. */) | 131 | which 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 | ||
| 179 | DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0, | 140 | DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0, |
| @@ -1383,14 +1344,10 @@ DEFUN ("member", Fmember, Smember, 2, 2, 0, | |||
| 1383 | The value is actually the tail of LIST whose car is ELT. */) | 1344 | The 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, | |||
| 1400 | The value is actually the tail of LIST whose car is ELT. */) | 1357 | The 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. | |||
| 1439 | Elements of LIST that are not conses are ignored. */) | 1390 | Elements 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, | |||
| 1468 | The value is actually the first element of LIST whose car equals KEY. */) | 1415 | The 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, | |||
| 1503 | The value is actually the first element of LIST whose cdr is KEY. */) | 1448 | The 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, | |||
| 1520 | The value is actually the first element of LIST whose cdr equals KEY. */) | 1461 | The 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. | |||
| 1544 | Write `(setq foo (delq element foo))' to be sure of correctly changing | 1483 | Write `(setq foo (delq element foo))' to be sure of correctly changing |
| 1545 | the value of a list `foo'. See also `remq', which does not modify the | 1484 | the value of a list `foo'. See also `remq', which does not modify the |
| 1546 | argument. */) | 1485 | argument. */) |
| 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 | |||
| 2013 | properties on the list. This function never signals an error. */) | 1948 | properties 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. | |||
| 2050 | The PLIST is modified by side effects. */) | 1982 | The 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 | |||
| 2091 | one of the properties on the list. */) | 2027 | one 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. | |||
| 2118 | The PLIST is modified by side effects. */) | 2054 | The 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 | |||
| 2180 | internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props, | 2120 | internal_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. | |||
| 2399 | usage: (nconc &rest LISTS) */) | 2346 | usage: (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. | |||
| 2843 | The value is actually the tail of PLIST whose car is PROP. */) | 2784 | The 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 | ||
| 2856 | DEFUN ("widget-put", Fwidget_put, Swidget_put, 3, 3, 0, | 2802 | DEFUN ("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 | ||
| 10004 | DEFUN ("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'. | ||
| 10007 | The argument KEYS must be a string. | ||
| 10008 | Internal 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 | |||
| 10004 | DEFUN ("this-command-keys-vector", Fthis_command_keys_vector, Sthis_command_keys_vector, 0, 0, 0, | 10028 | DEFUN ("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. |
| 10006 | However, if the command has called `read-key-sequence', it returns | 10030 | However, 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 | |||
| 3136 | enum { 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 | ||
| 3142 | INLINE void | 3136 | INLINE void |
| 3143 | rarely_quit (unsigned short int count) | 3137 | rarely_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 *); | |||
| 3317 | extern _Noreturn void args_out_of_range (Lisp_Object, Lisp_Object); | 3311 | extern _Noreturn void args_out_of_range (Lisp_Object, Lisp_Object); |
| 3318 | extern _Noreturn void args_out_of_range_3 (Lisp_Object, Lisp_Object, | 3312 | extern _Noreturn void args_out_of_range_3 (Lisp_Object, Lisp_Object, |
| 3319 | Lisp_Object); | 3313 | Lisp_Object); |
| 3314 | extern _Noreturn void circular_list (Lisp_Object); | ||
| 3320 | extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *); | 3315 | extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *); |
| 3321 | enum Set_Internal_Bind { | 3316 | enum 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. */ | ||
| 4600 | struct 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); |