Mercurial > emacs
comparison src/syntax.c @ 88155:d7ddb3e565de
sync with trunk
| author | Henrik Enberg <henrik.enberg@telia.com> |
|---|---|
| date | Mon, 16 Jan 2006 00:03:54 +0000 |
| parents | 23a1cea22d13 |
| children |
comparison
equal
deleted
inserted
replaced
| 88154:8ce476d3ba36 | 88155:d7ddb3e565de |
|---|---|
| 1 /* GNU Emacs routines to deal with syntax tables; also word and list parsing. | 1 /* GNU Emacs routines to deal with syntax tables; also word and list parsing. |
| 2 Copyright (C) 1985, 87, 93, 94, 95, 97, 1998, 1999 Free Software Foundation, Inc. | 2 Copyright (C) 1985, 1987, 1993, 1994, 1995, 1997, 1998, 1999, 2002, |
| 3 2003, 2004, 2005 Free Software Foundation, Inc. | |
| 3 | 4 |
| 4 This file is part of GNU Emacs. | 5 This file is part of GNU Emacs. |
| 5 | 6 |
| 6 GNU Emacs is free software; you can redistribute it and/or modify | 7 GNU Emacs is free software; you can redistribute it and/or modify |
| 7 it under the terms of the GNU General Public License as published by | 8 it under the terms of the GNU General Public License as published by |
| 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 GNU General Public License for more details. | 15 GNU General Public License for more details. |
| 15 | 16 |
| 16 You should have received a copy of the GNU General Public License | 17 You should have received a copy of the GNU General Public License |
| 17 along with GNU Emacs; see the file COPYING. If not, write to | 18 along with GNU Emacs; see the file COPYING. If not, write to |
| 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 19 Boston, MA 02111-1307, USA. */ | 20 Boston, MA 02110-1301, USA. */ |
| 20 | 21 |
| 21 | 22 |
| 22 #include <config.h> | 23 #include <config.h> |
| 23 #include <ctype.h> | 24 #include <ctype.h> |
| 24 #include "lisp.h" | 25 #include "lisp.h" |
| 25 #include "commands.h" | 26 #include "commands.h" |
| 26 #include "buffer.h" | 27 #include "buffer.h" |
| 27 #include "charset.h" | 28 #include "charset.h" |
| 28 #include "keymap.h" | 29 #include "keymap.h" |
| 30 #include "regex.h" | |
| 29 | 31 |
| 30 /* Make syntax table lookup grant data in gl_state. */ | 32 /* Make syntax table lookup grant data in gl_state. */ |
| 31 #define SYNTAX_ENTRY_VIA_PROPERTY | 33 #define SYNTAX_ENTRY_VIA_PROPERTY |
| 32 | 34 |
| 33 #include "syntax.h" | 35 #include "syntax.h" |
| 95 | 97 |
| 96 | 98 |
| 97 static int find_defun_start P_ ((int, int)); | 99 static int find_defun_start P_ ((int, int)); |
| 98 static int back_comment P_ ((int, int, int, int, int, int *, int *)); | 100 static int back_comment P_ ((int, int, int, int, int, int *, int *)); |
| 99 static int char_quoted P_ ((int, int)); | 101 static int char_quoted P_ ((int, int)); |
| 100 static Lisp_Object skip_chars P_ ((int, int, Lisp_Object, Lisp_Object)); | 102 static Lisp_Object skip_chars P_ ((int, int, Lisp_Object, Lisp_Object, int)); |
| 101 static Lisp_Object scan_lists P_ ((int, int, int, int)); | 103 static Lisp_Object scan_lists P_ ((int, int, int, int)); |
| 102 static void scan_sexps_forward P_ ((struct lisp_parse_state *, | 104 static void scan_sexps_forward P_ ((struct lisp_parse_state *, |
| 103 int, int, int, int, | 105 int, int, int, int, |
| 104 int, Lisp_Object, int)); | 106 int, Lisp_Object, int)); |
| 107 static int in_classes P_ ((int, Lisp_Object)); | |
| 105 | 108 |
| 106 | 109 |
| 107 struct gl_state_s gl_state; /* Global state of syntax parser. */ | 110 struct gl_state_s gl_state; /* Global state of syntax parser. */ |
| 108 | 111 |
| 109 INTERVAL interval_of (); | 112 INTERVAL interval_of (); |
| 128 int charpos, count, init; | 131 int charpos, count, init; |
| 129 Lisp_Object object; | 132 Lisp_Object object; |
| 130 { | 133 { |
| 131 Lisp_Object tmp_table; | 134 Lisp_Object tmp_table; |
| 132 int cnt = 0, invalidate = 1; | 135 int cnt = 0, invalidate = 1; |
| 133 INTERVAL i, oldi; | 136 INTERVAL i; |
| 134 | 137 |
| 135 if (init) | 138 if (init) |
| 136 { | 139 { |
| 137 gl_state.old_prop = Qnil; | 140 gl_state.old_prop = Qnil; |
| 138 gl_state.start = gl_state.b_property; | 141 gl_state.start = gl_state.b_property; |
| 159 i = gl_state.forward_i; | 162 i = gl_state.forward_i; |
| 160 gl_state.b_property = i->position - gl_state.offset; | 163 gl_state.b_property = i->position - gl_state.offset; |
| 161 gl_state.e_property = INTERVAL_LAST_POS (i) - gl_state.offset; | 164 gl_state.e_property = INTERVAL_LAST_POS (i) - gl_state.offset; |
| 162 goto update; | 165 goto update; |
| 163 } | 166 } |
| 164 oldi = i = count > 0 ? gl_state.forward_i : gl_state.backward_i; | 167 i = count > 0 ? gl_state.forward_i : gl_state.backward_i; |
| 165 | 168 |
| 166 /* We are guaranteed to be called with CHARPOS either in i, | 169 /* We are guaranteed to be called with CHARPOS either in i, |
| 167 or further off. */ | 170 or further off. */ |
| 168 if (NULL_INTERVAL_P (i)) | 171 if (NULL_INTERVAL_P (i)) |
| 169 error ("Error in syntax_table logic for to-the-end intervals"); | 172 error ("Error in syntax_table logic for to-the-end intervals"); |
| 244 gl_state.e_property = i->position - gl_state.offset; | 247 gl_state.e_property = i->position - gl_state.offset; |
| 245 gl_state.forward_i = i; | 248 gl_state.forward_i = i; |
| 246 } | 249 } |
| 247 else | 250 else |
| 248 { | 251 { |
| 249 gl_state.b_property = i->position + LENGTH (i) - gl_state.offset; | 252 gl_state.b_property |
| 253 = i->position + LENGTH (i) - gl_state.offset; | |
| 250 gl_state.backward_i = i; | 254 gl_state.backward_i = i; |
| 251 } | 255 } |
| 252 return; | 256 return; |
| 253 } | 257 } |
| 254 else if (cnt == INTERVALS_AT_ONCE) | 258 else if (cnt == INTERVALS_AT_ONCE) |
| 255 { | 259 { |
| 256 if (count > 0) | 260 if (count > 0) |
| 257 { | 261 { |
| 258 gl_state.e_property = i->position + LENGTH (i) - gl_state.offset; | 262 gl_state.e_property |
| 263 = i->position + LENGTH (i) - gl_state.offset | |
| 264 /* e_property at EOB is not set to ZV but to ZV+1, so that | |
| 265 we can do INC(from);UPDATE_SYNTAX_TABLE_FORWARD without | |
| 266 having to check eob between the two. */ | |
| 267 + (NULL_INTERVAL_P (next_interval (i)) ? 1 : 0); | |
| 259 gl_state.forward_i = i; | 268 gl_state.forward_i = i; |
| 260 } | 269 } |
| 261 else | 270 else |
| 262 { | 271 { |
| 263 gl_state.b_property = i->position - gl_state.offset; | 272 gl_state.b_property = i->position - gl_state.offset; |
| 288 register int quoted = 0; | 297 register int quoted = 0; |
| 289 int orig = charpos; | 298 int orig = charpos; |
| 290 | 299 |
| 291 DEC_BOTH (charpos, bytepos); | 300 DEC_BOTH (charpos, bytepos); |
| 292 | 301 |
| 293 while (bytepos >= beg) | 302 while (charpos >= beg) |
| 294 { | 303 { |
| 304 int c; | |
| 305 | |
| 295 UPDATE_SYNTAX_TABLE_BACKWARD (charpos); | 306 UPDATE_SYNTAX_TABLE_BACKWARD (charpos); |
| 296 code = SYNTAX (FETCH_CHAR (bytepos)); | 307 c = FETCH_CHAR (bytepos); |
| 308 code = SYNTAX (c); | |
| 297 if (! (code == Scharquote || code == Sescape)) | 309 if (! (code == Scharquote || code == Sescape)) |
| 298 break; | 310 break; |
| 299 | 311 |
| 300 DEC_BOTH (charpos, bytepos); | 312 DEC_BOTH (charpos, bytepos); |
| 301 quoted = !quoted; | 313 quoted = !quoted; |
| 335 | 347 |
| 336 /* Return a defun-start position before before POS and not too far before. | 348 /* Return a defun-start position before before POS and not too far before. |
| 337 It should be the last one before POS, or nearly the last. | 349 It should be the last one before POS, or nearly the last. |
| 338 | 350 |
| 339 When open_paren_in_column_0_is_defun_start is nonzero, | 351 When open_paren_in_column_0_is_defun_start is nonzero, |
| 340 the beginning of every line is treated as a defun-start. | 352 only the beginning of the buffer is treated as a defun-start. |
| 341 | 353 |
| 342 We record the information about where the scan started | 354 We record the information about where the scan started |
| 343 and what its result was, so that another call in the same area | 355 and what its result was, so that another call in the same area |
| 344 can return the same value very quickly. | 356 can return the same value very quickly. |
| 345 | 357 |
| 350 static int | 362 static int |
| 351 find_defun_start (pos, pos_byte) | 363 find_defun_start (pos, pos_byte) |
| 352 int pos, pos_byte; | 364 int pos, pos_byte; |
| 353 { | 365 { |
| 354 int opoint = PT, opoint_byte = PT_BYTE; | 366 int opoint = PT, opoint_byte = PT_BYTE; |
| 367 | |
| 368 if (!open_paren_in_column_0_is_defun_start) | |
| 369 { | |
| 370 find_start_value_byte = BEGV_BYTE; | |
| 371 return BEGV; | |
| 372 } | |
| 355 | 373 |
| 356 /* Use previous finding, if it's valid and applies to this inquiry. */ | 374 /* Use previous finding, if it's valid and applies to this inquiry. */ |
| 357 if (current_buffer == find_start_buffer | 375 if (current_buffer == find_start_buffer |
| 358 /* Reuse the defun-start even if POS is a little farther on. | 376 /* Reuse the defun-start even if POS is a little farther on. |
| 359 POS might be in the next defun, but that's ok. | 377 POS might be in the next defun, but that's ok. |
| 370 /* We optimize syntax-table lookup for rare updates. Thus we accept | 388 /* We optimize syntax-table lookup for rare updates. Thus we accept |
| 371 only those `^\s(' which are good in global _and_ text-property | 389 only those `^\s(' which are good in global _and_ text-property |
| 372 syntax-tables. */ | 390 syntax-tables. */ |
| 373 gl_state.current_syntax_table = current_buffer->syntax_table; | 391 gl_state.current_syntax_table = current_buffer->syntax_table; |
| 374 gl_state.use_global = 0; | 392 gl_state.use_global = 0; |
| 375 if (open_paren_in_column_0_is_defun_start) | 393 while (PT > BEGV) |
| 376 { | 394 { |
| 377 while (PT > BEGV) | 395 int c; |
| 378 { | 396 |
| 379 /* Open-paren at start of line means we may have found our | 397 /* Open-paren at start of line means we may have found our |
| 380 defun-start. */ | 398 defun-start. */ |
| 381 if (SYNTAX (FETCH_CHAR (PT_BYTE)) == Sopen) | 399 c = FETCH_CHAR (PT_BYTE); |
| 382 { | 400 if (SYNTAX (c) == Sopen) |
| 383 SETUP_SYNTAX_TABLE (PT + 1, -1); /* Try again... */ | 401 { |
| 384 if (SYNTAX (FETCH_CHAR (PT_BYTE)) == Sopen) | 402 SETUP_SYNTAX_TABLE (PT + 1, -1); /* Try again... */ |
| 385 break; | 403 c = FETCH_CHAR (PT_BYTE); |
| 386 /* Now fallback to the default value. */ | 404 if (SYNTAX (c) == Sopen) |
| 387 gl_state.current_syntax_table = current_buffer->syntax_table; | 405 break; |
| 388 gl_state.use_global = 0; | 406 /* Now fallback to the default value. */ |
| 389 } | 407 gl_state.current_syntax_table = current_buffer->syntax_table; |
| 390 /* Move to beg of previous line. */ | 408 gl_state.use_global = 0; |
| 391 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -2, 1); | 409 } |
| 392 } | 410 /* Move to beg of previous line. */ |
| 411 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -2, 1); | |
| 393 } | 412 } |
| 394 | 413 |
| 395 /* Record what we found, for the next try. */ | 414 /* Record what we found, for the next try. */ |
| 396 find_start_value = PT; | 415 find_start_value = PT; |
| 397 find_start_value_byte = PT_BYTE; | 416 find_start_value_byte = PT_BYTE; |
| 607 goto done; | 626 goto done; |
| 608 break; | 627 break; |
| 609 | 628 |
| 610 case Sendcomment: | 629 case Sendcomment: |
| 611 if (SYNTAX_FLAGS_COMMENT_STYLE (syntax) == comstyle | 630 if (SYNTAX_FLAGS_COMMENT_STYLE (syntax) == comstyle |
| 612 && (SYNTAX_FLAGS_COMMENT_NESTED (prev_syntax) | 631 && ((com2end && SYNTAX_FLAGS_COMMENT_NESTED (prev_syntax)) |
| 613 || SYNTAX_FLAGS_COMMENT_NESTED (syntax)) == comnested) | 632 || SYNTAX_FLAGS_COMMENT_NESTED (syntax)) == comnested) |
| 614 /* This is the same style of comment ender as ours. */ | 633 /* This is the same style of comment ender as ours. */ |
| 615 { | 634 { |
| 616 if (comnested) | 635 if (comnested) |
| 617 nesting++; | 636 nesting++; |
| 659 or `done'), then we've found the beginning of the non-nested comment. */ | 678 or `done'), then we've found the beginning of the non-nested comment. */ |
| 660 else if (1) /* !comnested */ | 679 else if (1) /* !comnested */ |
| 661 { | 680 { |
| 662 from = comstart_pos; | 681 from = comstart_pos; |
| 663 from_byte = comstart_byte; | 682 from_byte = comstart_byte; |
| 664 /* Globals are correct now. */ | 683 UPDATE_SYNTAX_TABLE_FORWARD (from - 1); |
| 665 } | 684 } |
| 666 else | 685 else |
| 667 { | 686 { |
| 668 struct lisp_parse_state state; | 687 struct lisp_parse_state state; |
| 669 lossage: | 688 lossage: |
| 909 CHECK_STRING (string); | 928 CHECK_STRING (string); |
| 910 | 929 |
| 911 p = SDATA (string); | 930 p = SDATA (string); |
| 912 code = (enum syntaxcode) syntax_spec_code[*p++]; | 931 code = (enum syntaxcode) syntax_spec_code[*p++]; |
| 913 if (((int) code & 0377) == 0377) | 932 if (((int) code & 0377) == 0377) |
| 914 error ("invalid syntax description letter: %c", p[-1]); | 933 error ("Invalid syntax description letter: %c", p[-1]); |
| 915 | 934 |
| 916 if (code == Sinherit) | 935 if (code == Sinherit) |
| 917 return Qnil; | 936 return Qnil; |
| 918 | 937 |
| 919 if (*p) | 938 if (*p) |
| 972 /* I really don't know why this is interactive | 991 /* I really don't know why this is interactive |
| 973 help-form should at least be made useful whilst reading the second arg. */ | 992 help-form should at least be made useful whilst reading the second arg. */ |
| 974 DEFUN ("modify-syntax-entry", Fmodify_syntax_entry, Smodify_syntax_entry, 2, 3, | 993 DEFUN ("modify-syntax-entry", Fmodify_syntax_entry, Smodify_syntax_entry, 2, 3, |
| 975 "cSet syntax for character: \nsSet syntax for %s to: ", | 994 "cSet syntax for character: \nsSet syntax for %s to: ", |
| 976 doc: /* Set syntax for character CHAR according to string NEWENTRY. | 995 doc: /* Set syntax for character CHAR according to string NEWENTRY. |
| 977 The syntax is changed only for table SYNTAX_TABLE, which defaults to | 996 The syntax is changed only for table SYNTAX-TABLE, which defaults to |
| 978 the current buffer's syntax table. | 997 the current buffer's syntax table. |
| 979 The first character of NEWENTRY should be one of the following: | 998 The first character of NEWENTRY should be one of the following: |
| 980 Space or - whitespace syntax. w word constituent. | 999 Space or - whitespace syntax. w word constituent. |
| 981 _ symbol constituent. . punctuation. | 1000 _ symbol constituent. . punctuation. |
| 982 ( open-parenthesis. ) close-parenthesis. | 1001 ( open-parenthesis. ) close-parenthesis. |
| 1272 immediate_quit = 0; | 1291 immediate_quit = 0; |
| 1273 | 1292 |
| 1274 return from; | 1293 return from; |
| 1275 } | 1294 } |
| 1276 | 1295 |
| 1277 DEFUN ("forward-word", Fforward_word, Sforward_word, 1, 1, "p", | 1296 DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "p", |
| 1278 doc: /* Move point forward ARG words (backward if ARG is negative). | 1297 doc: /* Move point forward ARG words (backward if ARG is negative). |
| 1279 Normally returns t. | 1298 Normally returns t. |
| 1280 If an edge of the buffer or a field boundary is reached, point is left there | 1299 If an edge of the buffer or a field boundary is reached, point is left there |
| 1281 and the function returns nil. Field boundaries are not noticed if | 1300 and the function returns nil. Field boundaries are not noticed if |
| 1282 `inhibit-field-text-motion' is non-nil. */) | 1301 `inhibit-field-text-motion' is non-nil. */) |
| 1283 (count) | 1302 (arg) |
| 1284 Lisp_Object count; | 1303 Lisp_Object arg; |
| 1285 { | 1304 { |
| 1305 Lisp_Object tmp; | |
| 1286 int orig_val, val; | 1306 int orig_val, val; |
| 1287 CHECK_NUMBER (count); | 1307 |
| 1288 | 1308 if (NILP (arg)) |
| 1289 val = orig_val = scan_words (PT, XINT (count)); | 1309 XSETFASTINT (arg, 1); |
| 1310 else | |
| 1311 CHECK_NUMBER (arg); | |
| 1312 | |
| 1313 val = orig_val = scan_words (PT, XINT (arg)); | |
| 1290 if (! orig_val) | 1314 if (! orig_val) |
| 1291 val = XINT (count) > 0 ? ZV : BEGV; | 1315 val = XINT (arg) > 0 ? ZV : BEGV; |
| 1292 | 1316 |
| 1293 /* Avoid jumping out of an input field. */ | 1317 /* Avoid jumping out of an input field. */ |
| 1294 val = XFASTINT (Fconstrain_to_field (make_number (val), make_number (PT), | 1318 tmp = Fconstrain_to_field (make_number (val), make_number (PT), |
| 1295 Qt, Qnil, Qnil)); | 1319 Qt, Qnil, Qnil); |
| 1320 val = XFASTINT (tmp); | |
| 1296 | 1321 |
| 1297 SET_PT (val); | 1322 SET_PT (val); |
| 1298 return val == orig_val ? Qt : Qnil; | 1323 return val == orig_val ? Qt : Qnil; |
| 1299 } | 1324 } |
| 1300 | 1325 |
| 1305 STRING is like the inside of a `[...]' in a regular expression | 1330 STRING is like the inside of a `[...]' in a regular expression |
| 1306 except that `]' is never special and `\\' quotes `^', `-' or `\\' | 1331 except that `]' is never special and `\\' quotes `^', `-' or `\\' |
| 1307 (but not as the end of a range; quoting is never needed there). | 1332 (but not as the end of a range; quoting is never needed there). |
| 1308 Thus, with arg "a-zA-Z", this skips letters stopping before first nonletter. | 1333 Thus, with arg "a-zA-Z", this skips letters stopping before first nonletter. |
| 1309 With arg "^a-zA-Z", skips nonletters stopping before first letter. | 1334 With arg "^a-zA-Z", skips nonletters stopping before first letter. |
| 1310 Returns the distance traveled, either zero or positive. | 1335 Char classes, e.g. `[:alpha:]', are supported. |
| 1311 Note that char classes, e.g. `[:alpha:]', are not currently supported; | 1336 |
| 1312 they will be treated as literals. */) | 1337 Returns the distance traveled, either zero or positive. */) |
| 1313 (string, lim) | 1338 (string, lim) |
| 1314 Lisp_Object string, lim; | 1339 Lisp_Object string, lim; |
| 1315 { | 1340 { |
| 1316 return skip_chars (1, 0, string, lim); | 1341 return skip_chars (1, 0, string, lim, 1); |
| 1317 } | 1342 } |
| 1318 | 1343 |
| 1319 DEFUN ("skip-chars-backward", Fskip_chars_backward, Sskip_chars_backward, 1, 2, 0, | 1344 DEFUN ("skip-chars-backward", Fskip_chars_backward, Sskip_chars_backward, 1, 2, 0, |
| 1320 doc: /* Move point backward, stopping after a char not in STRING, or at pos LIM. | 1345 doc: /* Move point backward, stopping after a char not in STRING, or at pos LIM. |
| 1321 See `skip-chars-forward' for details. | 1346 See `skip-chars-forward' for details. |
| 1322 Returns the distance traveled, either zero or negative. */) | 1347 Returns the distance traveled, either zero or negative. */) |
| 1323 (string, lim) | 1348 (string, lim) |
| 1324 Lisp_Object string, lim; | 1349 Lisp_Object string, lim; |
| 1325 { | 1350 { |
| 1326 return skip_chars (0, 0, string, lim); | 1351 return skip_chars (0, 0, string, lim, 1); |
| 1327 } | 1352 } |
| 1328 | 1353 |
| 1329 DEFUN ("skip-syntax-forward", Fskip_syntax_forward, Sskip_syntax_forward, 1, 2, 0, | 1354 DEFUN ("skip-syntax-forward", Fskip_syntax_forward, Sskip_syntax_forward, 1, 2, 0, |
| 1330 doc: /* Move point forward across chars in specified syntax classes. | 1355 doc: /* Move point forward across chars in specified syntax classes. |
| 1331 SYNTAX is a string of syntax code characters. | 1356 SYNTAX is a string of syntax code characters. |
| 1333 If SYNTAX starts with ^, skip characters whose syntax is NOT in SYNTAX. | 1358 If SYNTAX starts with ^, skip characters whose syntax is NOT in SYNTAX. |
| 1334 This function returns the distance traveled, either zero or positive. */) | 1359 This function returns the distance traveled, either zero or positive. */) |
| 1335 (syntax, lim) | 1360 (syntax, lim) |
| 1336 Lisp_Object syntax, lim; | 1361 Lisp_Object syntax, lim; |
| 1337 { | 1362 { |
| 1338 return skip_chars (1, 1, syntax, lim); | 1363 return skip_chars (1, 1, syntax, lim, 0); |
| 1339 } | 1364 } |
| 1340 | 1365 |
| 1341 DEFUN ("skip-syntax-backward", Fskip_syntax_backward, Sskip_syntax_backward, 1, 2, 0, | 1366 DEFUN ("skip-syntax-backward", Fskip_syntax_backward, Sskip_syntax_backward, 1, 2, 0, |
| 1342 doc: /* Move point backward across chars in specified syntax classes. | 1367 doc: /* Move point backward across chars in specified syntax classes. |
| 1343 SYNTAX is a string of syntax code characters. | 1368 SYNTAX is a string of syntax code characters. |
| 1345 If SYNTAX starts with ^, skip characters whose syntax is NOT in SYNTAX. | 1370 If SYNTAX starts with ^, skip characters whose syntax is NOT in SYNTAX. |
| 1346 This function returns the distance traveled, either zero or negative. */) | 1371 This function returns the distance traveled, either zero or negative. */) |
| 1347 (syntax, lim) | 1372 (syntax, lim) |
| 1348 Lisp_Object syntax, lim; | 1373 Lisp_Object syntax, lim; |
| 1349 { | 1374 { |
| 1350 return skip_chars (0, 1, syntax, lim); | 1375 return skip_chars (0, 1, syntax, lim, 0); |
| 1351 } | 1376 } |
| 1352 | 1377 |
| 1353 static Lisp_Object | 1378 static Lisp_Object |
| 1354 skip_chars (forwardp, syntaxp, string, lim) | 1379 skip_chars (forwardp, syntaxp, string, lim, handle_iso_classes) |
| 1355 int forwardp, syntaxp; | 1380 int forwardp, syntaxp; |
| 1356 Lisp_Object string, lim; | 1381 Lisp_Object string, lim; |
| 1382 int handle_iso_classes; | |
| 1357 { | 1383 { |
| 1358 register unsigned int c; | 1384 register unsigned int c; |
| 1359 unsigned char fastmap[0400]; | 1385 unsigned char fastmap[0400]; |
| 1360 /* If SYNTAXP is 0, STRING may contain multi-byte form of characters | 1386 /* If SYNTAXP is 0, STRING may contain multi-byte form of characters |
| 1361 of which codes don't fit in FASTMAP. In that case, set the | 1387 of which codes don't fit in FASTMAP. In that case, set the |
| 1367 int multibyte = !NILP (current_buffer->enable_multibyte_characters); | 1393 int multibyte = !NILP (current_buffer->enable_multibyte_characters); |
| 1368 int string_multibyte; | 1394 int string_multibyte; |
| 1369 int size_byte; | 1395 int size_byte; |
| 1370 const unsigned char *str; | 1396 const unsigned char *str; |
| 1371 int len; | 1397 int len; |
| 1398 Lisp_Object iso_classes; | |
| 1372 | 1399 |
| 1373 CHECK_STRING (string); | 1400 CHECK_STRING (string); |
| 1374 char_ranges = (int *) alloca (SCHARS (string) * (sizeof (int)) * 2); | 1401 char_ranges = (int *) alloca (SCHARS (string) * (sizeof (int)) * 2); |
| 1375 string_multibyte = STRING_MULTIBYTE (string); | 1402 string_multibyte = STRING_MULTIBYTE (string); |
| 1376 str = SDATA (string); | 1403 str = SDATA (string); |
| 1377 size_byte = SBYTES (string); | 1404 size_byte = SBYTES (string); |
| 1405 iso_classes = Qnil; | |
| 1378 | 1406 |
| 1379 /* Adjust the multibyteness of the string to that of the buffer. */ | 1407 /* Adjust the multibyteness of the string to that of the buffer. */ |
| 1380 if (multibyte != string_multibyte) | 1408 if (multibyte != string_multibyte) |
| 1381 { | 1409 { |
| 1382 int nbytes; | 1410 int nbytes; |
| 1428 | 1456 |
| 1429 if (syntaxp) | 1457 if (syntaxp) |
| 1430 fastmap[syntax_spec_code[c & 0377]] = 1; | 1458 fastmap[syntax_spec_code[c & 0377]] = 1; |
| 1431 else | 1459 else |
| 1432 { | 1460 { |
| 1461 if (handle_iso_classes && c == '[' | |
| 1462 && i_byte < size_byte | |
| 1463 && STRING_CHAR (str + i_byte, size_byte - i_byte) == ':') | |
| 1464 { | |
| 1465 const unsigned char *class_beg = str + i_byte + 1; | |
| 1466 const unsigned char *class_end = class_beg; | |
| 1467 const unsigned char *class_limit = str + size_byte - 2; | |
| 1468 /* Leave room for the null. */ | |
| 1469 unsigned char class_name[CHAR_CLASS_MAX_LENGTH + 1]; | |
| 1470 re_wctype_t cc; | |
| 1471 | |
| 1472 if (class_limit - class_beg > CHAR_CLASS_MAX_LENGTH) | |
| 1473 class_limit = class_beg + CHAR_CLASS_MAX_LENGTH; | |
| 1474 | |
| 1475 while (class_end < class_limit | |
| 1476 && *class_end >= 'a' && *class_end <= 'z') | |
| 1477 class_end++; | |
| 1478 | |
| 1479 if (class_end == class_beg | |
| 1480 || *class_end != ':' || class_end[1] != ']') | |
| 1481 goto not_a_class_name; | |
| 1482 | |
| 1483 bcopy (class_beg, class_name, class_end - class_beg); | |
| 1484 class_name[class_end - class_beg] = 0; | |
| 1485 | |
| 1486 cc = re_wctype (class_name); | |
| 1487 if (cc == 0) | |
| 1488 error ("Invalid ISO C character class"); | |
| 1489 | |
| 1490 iso_classes = Fcons (make_number (cc), iso_classes); | |
| 1491 | |
| 1492 i_byte = class_end + 2 - str; | |
| 1493 continue; | |
| 1494 } | |
| 1495 | |
| 1496 not_a_class_name: | |
| 1433 if (c == '\\') | 1497 if (c == '\\') |
| 1434 { | 1498 { |
| 1435 if (i_byte == size_byte) | 1499 if (i_byte == size_byte) |
| 1436 break; | 1500 break; |
| 1437 | 1501 |
| 1438 c = STRING_CHAR_AND_LENGTH (str+i_byte, size_byte-i_byte, len); | 1502 c = STRING_CHAR_AND_LENGTH (str + i_byte, |
| 1503 size_byte - i_byte, len); | |
| 1439 i_byte += len; | 1504 i_byte += len; |
| 1440 } | 1505 } |
| 1441 if (i_byte < size_byte | 1506 /* Treat `-' as range character only if another character |
| 1507 follows. */ | |
| 1508 if (i_byte + 1 < size_byte | |
| 1442 && str[i_byte] == '-') | 1509 && str[i_byte] == '-') |
| 1443 { | 1510 { |
| 1444 unsigned int c2; | 1511 unsigned int c2; |
| 1445 | 1512 |
| 1446 /* Skip over the dash. */ | 1513 /* Skip over the dash. */ |
| 1447 i_byte++; | 1514 i_byte++; |
| 1448 | 1515 |
| 1449 if (i_byte == size_byte) | |
| 1450 break; | |
| 1451 | |
| 1452 /* Get the end of the range. */ | 1516 /* Get the end of the range. */ |
| 1453 c2 =STRING_CHAR_AND_LENGTH (str+i_byte, size_byte-i_byte, len); | 1517 c2 = STRING_CHAR_AND_LENGTH (str + i_byte, |
| 1518 size_byte - i_byte, len); | |
| 1454 i_byte += len; | 1519 i_byte += len; |
| 1455 | 1520 |
| 1456 if (SINGLE_BYTE_CHAR_P (c)) | 1521 if (SINGLE_BYTE_CHAR_P (c)) |
| 1457 { | 1522 { |
| 1458 if (! SINGLE_BYTE_CHAR_P (c2)) | 1523 if (! SINGLE_BYTE_CHAR_P (c2)) |
| 1502 | 1567 |
| 1503 { | 1568 { |
| 1504 int start_point = PT; | 1569 int start_point = PT; |
| 1505 int pos = PT; | 1570 int pos = PT; |
| 1506 int pos_byte = PT_BYTE; | 1571 int pos_byte = PT_BYTE; |
| 1572 unsigned char *p = PT_ADDR, *endp, *stop; | |
| 1573 | |
| 1574 if (forwardp) | |
| 1575 { | |
| 1576 endp = (XINT (lim) == GPT) ? GPT_ADDR : CHAR_POS_ADDR (XINT (lim)); | |
| 1577 stop = (pos < GPT && GPT < XINT (lim)) ? GPT_ADDR : endp; | |
| 1578 } | |
| 1579 else | |
| 1580 { | |
| 1581 endp = CHAR_POS_ADDR (XINT (lim)); | |
| 1582 stop = (pos >= GPT && GPT > XINT (lim)) ? GAP_END_ADDR : endp; | |
| 1583 } | |
| 1507 | 1584 |
| 1508 immediate_quit = 1; | 1585 immediate_quit = 1; |
| 1509 if (syntaxp) | 1586 if (syntaxp) |
| 1510 { | 1587 { |
| 1511 SETUP_SYNTAX_TABLE (pos, forwardp ? 1 : -1); | 1588 SETUP_SYNTAX_TABLE (pos, forwardp ? 1 : -1); |
| 1512 if (forwardp) | 1589 if (forwardp) |
| 1513 { | 1590 { |
| 1514 if (multibyte) | 1591 if (multibyte) |
| 1515 { | 1592 while (1) |
| 1516 if (pos < XINT (lim)) | 1593 { |
| 1517 while (fastmap[(int) SYNTAX (FETCH_CHAR (pos_byte))]) | 1594 int nbytes; |
| 1595 | |
| 1596 if (p >= stop) | |
| 1518 { | 1597 { |
| 1519 /* Since we already checked for multibyteness, | 1598 if (p >= endp) |
| 1520 avoid using INC_BOTH which checks again. */ | 1599 break; |
| 1521 INC_POS (pos_byte); | 1600 p = GAP_END_ADDR; |
| 1522 pos++; | 1601 stop = endp; |
| 1523 if (pos >= XINT (lim)) | |
| 1524 break; | |
| 1525 UPDATE_SYNTAX_TABLE_FORWARD (pos); | |
| 1526 } | 1602 } |
| 1527 } | 1603 c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes); |
| 1604 if (! fastmap[(int) SYNTAX (c)]) | |
| 1605 break; | |
| 1606 p += nbytes, pos++, pos_byte += nbytes; | |
| 1607 UPDATE_SYNTAX_TABLE_FORWARD (pos); | |
| 1608 } | |
| 1528 else | 1609 else |
| 1529 { | 1610 while (1) |
| 1530 while (pos < XINT (lim) | 1611 { |
| 1531 && fastmap[(int) SYNTAX (FETCH_BYTE (pos))]) | 1612 if (p >= stop) |
| 1532 { | 1613 { |
| 1533 pos++; | 1614 if (p >= endp) |
| 1534 UPDATE_SYNTAX_TABLE_FORWARD (pos); | 1615 break; |
| 1535 } | 1616 p = GAP_END_ADDR; |
| 1536 } | 1617 stop = endp; |
| 1618 } | |
| 1619 if (! fastmap[(int) SYNTAX (*p)]) | |
| 1620 break; | |
| 1621 p++, pos++; | |
| 1622 UPDATE_SYNTAX_TABLE_FORWARD (pos); | |
| 1623 } | |
| 1537 } | 1624 } |
| 1538 else | 1625 else |
| 1539 { | 1626 { |
| 1540 if (multibyte) | 1627 if (multibyte) |
| 1541 { | 1628 while (1) |
| 1542 while (pos > XINT (lim)) | 1629 { |
| 1543 { | 1630 unsigned char *prev_p; |
| 1544 int savepos = pos_byte; | 1631 int nbytes; |
| 1545 /* Since we already checked for multibyteness, | 1632 |
| 1546 avoid using DEC_BOTH which checks again. */ | 1633 if (p <= stop) |
| 1547 pos--; | 1634 { |
| 1548 DEC_POS (pos_byte); | 1635 if (p <= endp) |
| 1549 UPDATE_SYNTAX_TABLE_BACKWARD (pos); | |
| 1550 if (!fastmap[(int) SYNTAX (FETCH_CHAR (pos_byte))]) | |
| 1551 { | |
| 1552 pos++; | |
| 1553 pos_byte = savepos; | |
| 1554 break; | 1636 break; |
| 1555 } | 1637 p = GPT_ADDR; |
| 1556 } | 1638 stop = endp; |
| 1557 } | 1639 } |
| 1640 prev_p = p; | |
| 1641 while (--p >= stop && ! CHAR_HEAD_P (*p)); | |
| 1642 PARSE_MULTIBYTE_SEQ (p, MAX_MULTIBYTE_LENGTH, nbytes); | |
| 1643 if (prev_p - p > nbytes) | |
| 1644 p = prev_p - 1, c = *p, nbytes = 1; | |
| 1645 else | |
| 1646 c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH); | |
| 1647 pos--, pos_byte -= nbytes; | |
| 1648 UPDATE_SYNTAX_TABLE_BACKWARD (pos); | |
| 1649 if (! fastmap[(int) SYNTAX (c)]) | |
| 1650 { | |
| 1651 pos++; | |
| 1652 pos_byte += nbytes; | |
| 1653 break; | |
| 1654 } | |
| 1655 } | |
| 1558 else | 1656 else |
| 1559 { | 1657 while (1) |
| 1560 if (pos > XINT (lim)) | 1658 { |
| 1561 while (fastmap[(int) SYNTAX (FETCH_BYTE (pos - 1))]) | 1659 if (p <= stop) |
| 1562 { | 1660 { |
| 1563 pos--; | 1661 if (p <= endp) |
| 1564 if (pos <= XINT (lim)) | |
| 1565 break; | 1662 break; |
| 1566 UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1); | 1663 p = GPT_ADDR; |
| 1664 stop = endp; | |
| 1567 } | 1665 } |
| 1568 } | 1666 if (! fastmap[(int) SYNTAX (p[-1])]) |
| 1667 break; | |
| 1668 p--, pos--; | |
| 1669 UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1); | |
| 1670 } | |
| 1569 } | 1671 } |
| 1570 } | 1672 } |
| 1571 else | 1673 else |
| 1572 { | 1674 { |
| 1573 if (forwardp) | 1675 if (forwardp) |
| 1574 { | 1676 { |
| 1575 if (multibyte) | 1677 if (multibyte) |
| 1576 while (pos < XINT (lim)) | 1678 while (1) |
| 1577 { | 1679 { |
| 1578 c = FETCH_MULTIBYTE_CHAR (pos_byte); | 1680 int nbytes; |
| 1681 | |
| 1682 if (p >= stop) | |
| 1683 { | |
| 1684 if (p >= endp) | |
| 1685 break; | |
| 1686 p = GAP_END_ADDR; | |
| 1687 stop = endp; | |
| 1688 } | |
| 1689 c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes); | |
| 1690 | |
| 1691 if (! NILP (iso_classes) && in_classes (c, iso_classes)) | |
| 1692 { | |
| 1693 if (negate) | |
| 1694 break; | |
| 1695 else | |
| 1696 goto fwd_ok; | |
| 1697 } | |
| 1698 | |
| 1579 if (SINGLE_BYTE_CHAR_P (c)) | 1699 if (SINGLE_BYTE_CHAR_P (c)) |
| 1580 { | 1700 { |
| 1581 if (!fastmap[c]) | 1701 if (!fastmap[c]) |
| 1582 break; | 1702 break; |
| 1583 } | 1703 } |
| 1596 if (c >= char_ranges[i] && c <= char_ranges[i + 1]) | 1716 if (c >= char_ranges[i] && c <= char_ranges[i + 1]) |
| 1597 break; | 1717 break; |
| 1598 if (!(negate ^ (i < n_char_ranges))) | 1718 if (!(negate ^ (i < n_char_ranges))) |
| 1599 break; | 1719 break; |
| 1600 } | 1720 } |
| 1601 INC_BOTH (pos, pos_byte); | 1721 fwd_ok: |
| 1722 p += nbytes, pos++, pos_byte += nbytes; | |
| 1602 } | 1723 } |
| 1603 else | 1724 else |
| 1604 while (pos < XINT (lim) && fastmap[FETCH_BYTE (pos)]) | 1725 while (1) |
| 1605 pos++; | 1726 { |
| 1727 if (p >= stop) | |
| 1728 { | |
| 1729 if (p >= endp) | |
| 1730 break; | |
| 1731 p = GAP_END_ADDR; | |
| 1732 stop = endp; | |
| 1733 } | |
| 1734 | |
| 1735 if (!NILP (iso_classes) && in_classes (*p, iso_classes)) | |
| 1736 { | |
| 1737 if (negate) | |
| 1738 break; | |
| 1739 else | |
| 1740 goto fwd_unibyte_ok; | |
| 1741 } | |
| 1742 | |
| 1743 if (!fastmap[*p]) | |
| 1744 break; | |
| 1745 fwd_unibyte_ok: | |
| 1746 p++, pos++; | |
| 1747 } | |
| 1606 } | 1748 } |
| 1607 else | 1749 else |
| 1608 { | 1750 { |
| 1609 if (multibyte) | 1751 if (multibyte) |
| 1610 while (pos > XINT (lim)) | 1752 while (1) |
| 1611 { | 1753 { |
| 1612 int prev_pos_byte = pos_byte; | 1754 unsigned char *prev_p; |
| 1613 | 1755 int nbytes; |
| 1614 DEC_POS (prev_pos_byte); | 1756 |
| 1615 c = FETCH_MULTIBYTE_CHAR (prev_pos_byte); | 1757 if (p <= stop) |
| 1758 { | |
| 1759 if (p <= endp) | |
| 1760 break; | |
| 1761 p = GPT_ADDR; | |
| 1762 stop = endp; | |
| 1763 } | |
| 1764 prev_p = p; | |
| 1765 while (--p >= stop && ! CHAR_HEAD_P (*p)); | |
| 1766 PARSE_MULTIBYTE_SEQ (p, MAX_MULTIBYTE_LENGTH, nbytes); | |
| 1767 if (prev_p - p > nbytes) | |
| 1768 p = prev_p - 1, c = *p, nbytes = 1; | |
| 1769 else | |
| 1770 c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH); | |
| 1771 | |
| 1772 if (! NILP (iso_classes) && in_classes (c, iso_classes)) | |
| 1773 { | |
| 1774 if (negate) | |
| 1775 break; | |
| 1776 else | |
| 1777 goto back_ok; | |
| 1778 } | |
| 1779 | |
| 1616 if (SINGLE_BYTE_CHAR_P (c)) | 1780 if (SINGLE_BYTE_CHAR_P (c)) |
| 1617 { | 1781 { |
| 1618 if (!fastmap[c]) | 1782 if (!fastmap[c]) |
| 1619 break; | 1783 break; |
| 1620 } | 1784 } |
| 1625 if (c >= char_ranges[i] && c <= char_ranges[i + 1]) | 1789 if (c >= char_ranges[i] && c <= char_ranges[i + 1]) |
| 1626 break; | 1790 break; |
| 1627 if (!(negate ^ (i < n_char_ranges))) | 1791 if (!(negate ^ (i < n_char_ranges))) |
| 1628 break; | 1792 break; |
| 1629 } | 1793 } |
| 1630 pos--; | 1794 back_ok: |
| 1631 pos_byte = prev_pos_byte; | 1795 pos--, pos_byte -= nbytes; |
| 1632 } | 1796 } |
| 1633 else | 1797 else |
| 1634 while (pos > XINT (lim) && fastmap[FETCH_BYTE (pos - 1)]) | 1798 while (1) |
| 1635 pos--; | 1799 { |
| 1800 if (p <= stop) | |
| 1801 { | |
| 1802 if (p <= endp) | |
| 1803 break; | |
| 1804 p = GPT_ADDR; | |
| 1805 stop = endp; | |
| 1806 } | |
| 1807 | |
| 1808 if (! NILP (iso_classes) && in_classes (p[-1], iso_classes)) | |
| 1809 { | |
| 1810 if (negate) | |
| 1811 break; | |
| 1812 else | |
| 1813 goto back_unibyte_ok; | |
| 1814 } | |
| 1815 | |
| 1816 if (!fastmap[p[-1]]) | |
| 1817 break; | |
| 1818 back_unibyte_ok: | |
| 1819 p--, pos--; | |
| 1820 } | |
| 1636 } | 1821 } |
| 1637 } | 1822 } |
| 1638 | 1823 |
| 1639 #if 0 /* Not needed now that a position in mid-character | 1824 #if 0 /* Not needed now that a position in mid-character |
| 1640 cannot be specified in Lisp. */ | 1825 cannot be specified in Lisp. */ |
| 1650 SET_PT_BOTH (pos, pos_byte); | 1835 SET_PT_BOTH (pos, pos_byte); |
| 1651 immediate_quit = 0; | 1836 immediate_quit = 0; |
| 1652 | 1837 |
| 1653 return make_number (PT - start_point); | 1838 return make_number (PT - start_point); |
| 1654 } | 1839 } |
| 1840 } | |
| 1841 | |
| 1842 /* Return 1 if character C belongs to one of the ISO classes | |
| 1843 in the list ISO_CLASSES. Each class is represented by an | |
| 1844 integer which is its type according to re_wctype. */ | |
| 1845 | |
| 1846 static int | |
| 1847 in_classes (c, iso_classes) | |
| 1848 int c; | |
| 1849 Lisp_Object iso_classes; | |
| 1850 { | |
| 1851 int fits_class = 0; | |
| 1852 | |
| 1853 while (! NILP (iso_classes)) | |
| 1854 { | |
| 1855 Lisp_Object elt; | |
| 1856 elt = XCAR (iso_classes); | |
| 1857 iso_classes = XCDR (iso_classes); | |
| 1858 | |
| 1859 if (re_iswctype (c, XFASTINT (elt))) | |
| 1860 fits_class = 1; | |
| 1861 } | |
| 1862 | |
| 1863 return fits_class; | |
| 1655 } | 1864 } |
| 1656 | 1865 |
| 1657 /* Jump over a comment, assuming we are at the beginning of one. | 1866 /* Jump over a comment, assuming we are at the beginning of one. |
| 1658 FROM is the current position. | 1867 FROM is the current position. |
| 1659 FROM_BYTE is the bytepos corresponding to FROM. | 1868 FROM_BYTE is the bytepos corresponding to FROM. |
| 2034 if (depth == min_depth) | 2243 if (depth == min_depth) |
| 2035 last_good = from; | 2244 last_good = from; |
| 2036 INC_BOTH (from, from_byte); | 2245 INC_BOTH (from, from_byte); |
| 2037 UPDATE_SYNTAX_TABLE_FORWARD (from); | 2246 UPDATE_SYNTAX_TABLE_FORWARD (from); |
| 2038 if (from < stop && comstart_first | 2247 if (from < stop && comstart_first |
| 2039 && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from_byte)) | 2248 && (c = FETCH_CHAR (from_byte), SYNTAX_COMSTART_SECOND (c)) |
| 2040 && parse_sexp_ignore_comments) | 2249 && parse_sexp_ignore_comments) |
| 2041 { | 2250 { |
| 2042 /* we have encountered a comment start sequence and we | 2251 /* we have encountered a comment start sequence and we |
| 2043 are ignoring all text inside comments. We must record | 2252 are ignoring all text inside comments. We must record |
| 2044 the comment style this sequence begins so that later, | 2253 the comment style this sequence begins so that later, |
| 2308 | 2517 |
| 2309 case Scomment_fence: | 2518 case Scomment_fence: |
| 2310 case Sstring_fence: | 2519 case Sstring_fence: |
| 2311 while (1) | 2520 while (1) |
| 2312 { | 2521 { |
| 2522 if (from == stop) goto lose; | |
| 2313 DEC_BOTH (from, from_byte); | 2523 DEC_BOTH (from, from_byte); |
| 2314 if (from == stop) goto lose; | |
| 2315 UPDATE_SYNTAX_TABLE_BACKWARD (from); | 2524 UPDATE_SYNTAX_TABLE_BACKWARD (from); |
| 2316 if (!char_quoted (from, from_byte) | 2525 if (!char_quoted (from, from_byte) |
| 2317 && (c = FETCH_CHAR (from_byte), | 2526 && (c = FETCH_CHAR (from_byte), |
| 2318 SYNTAX_WITH_MULTIBYTE_CHECK (c) == code)) | 2527 SYNTAX_WITH_MULTIBYTE_CHECK (c) == code)) |
| 2319 break; | 2528 break; |
| 2324 case Sstring: | 2533 case Sstring: |
| 2325 stringterm = FETCH_CHAR (from_byte); | 2534 stringterm = FETCH_CHAR (from_byte); |
| 2326 while (1) | 2535 while (1) |
| 2327 { | 2536 { |
| 2328 if (from == stop) goto lose; | 2537 if (from == stop) goto lose; |
| 2329 temp_pos = from_byte; | 2538 DEC_BOTH (from, from_byte); |
| 2330 if (! NILP (current_buffer->enable_multibyte_characters)) | 2539 UPDATE_SYNTAX_TABLE_BACKWARD (from); |
| 2331 DEC_POS (temp_pos); | 2540 if (!char_quoted (from, from_byte) |
| 2332 else | 2541 && stringterm == (c = FETCH_CHAR (from_byte)) |
| 2333 temp_pos--; | |
| 2334 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1); | |
| 2335 if (!char_quoted (from - 1, temp_pos) | |
| 2336 && stringterm == (c = FETCH_CHAR (temp_pos)) | |
| 2337 && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring) | 2542 && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring) |
| 2338 break; | 2543 break; |
| 2339 DEC_BOTH (from, from_byte); | |
| 2340 } | 2544 } |
| 2341 DEC_BOTH (from, from_byte); | |
| 2342 if (!depth && sexpflag) goto done2; | 2545 if (!depth && sexpflag) goto done2; |
| 2343 break; | 2546 break; |
| 2344 default: | 2547 default: |
| 2345 /* Ignore whitespace, punctuation, quote, endcomment. */ | 2548 /* Ignore whitespace, punctuation, quote, endcomment. */ |
| 2346 break; | 2549 break; |
| 2365 lose: | 2568 lose: |
| 2366 Fsignal (Qscan_error, | 2569 Fsignal (Qscan_error, |
| 2367 Fcons (build_string ("Unbalanced parentheses"), | 2570 Fcons (build_string ("Unbalanced parentheses"), |
| 2368 Fcons (make_number (last_good), | 2571 Fcons (make_number (last_good), |
| 2369 Fcons (make_number (from), Qnil)))); | 2572 Fcons (make_number (from), Qnil)))); |
| 2370 | 2573 abort (); |
| 2371 /* NOTREACHED */ | 2574 /* NOTREACHED */ |
| 2372 } | 2575 } |
| 2373 | 2576 |
| 2374 DEFUN ("scan-lists", Fscan_lists, Sscan_lists, 3, 3, 0, | 2577 DEFUN ("scan-lists", Fscan_lists, Sscan_lists, 3, 3, 0, |
| 2375 doc: /* Scan from character number FROM by COUNT lists. | 2578 doc: /* Scan from character number FROM by COUNT lists. |
| 2504 | 2707 |
| 2505 /* Use this macro instead of `from++'. */ | 2708 /* Use this macro instead of `from++'. */ |
| 2506 #define INC_FROM \ | 2709 #define INC_FROM \ |
| 2507 do { prev_from = from; \ | 2710 do { prev_from = from; \ |
| 2508 prev_from_byte = from_byte; \ | 2711 prev_from_byte = from_byte; \ |
| 2509 prev_from_syntax \ | 2712 temp = FETCH_CHAR (prev_from_byte); \ |
| 2510 = SYNTAX_WITH_FLAGS (FETCH_CHAR (prev_from_byte)); \ | 2713 prev_from_syntax = SYNTAX_WITH_FLAGS (temp); \ |
| 2511 INC_BOTH (from, from_byte); \ | 2714 INC_BOTH (from, from_byte); \ |
| 2512 if (from < end) \ | 2715 if (from < end) \ |
| 2513 UPDATE_SYNTAX_TABLE_FORWARD (from); \ | 2716 UPDATE_SYNTAX_TABLE_FORWARD (from); \ |
| 2514 } while (0) | 2717 } while (0) |
| 2515 | 2718 |
| 2580 | 2783 |
| 2581 curlevel->prev = -1; | 2784 curlevel->prev = -1; |
| 2582 curlevel->last = -1; | 2785 curlevel->last = -1; |
| 2583 | 2786 |
| 2584 SETUP_SYNTAX_TABLE (prev_from, 1); | 2787 SETUP_SYNTAX_TABLE (prev_from, 1); |
| 2585 prev_from_syntax = SYNTAX_WITH_FLAGS (FETCH_CHAR (prev_from_byte)); | 2788 temp = FETCH_CHAR (prev_from_byte); |
| 2789 prev_from_syntax = SYNTAX_WITH_FLAGS (temp); | |
| 2586 UPDATE_SYNTAX_TABLE_FORWARD (from); | 2790 UPDATE_SYNTAX_TABLE_FORWARD (from); |
| 2587 | 2791 |
| 2588 /* Enter the loop at a place appropriate for initial state. */ | 2792 /* Enter the loop at a place appropriate for initial state. */ |
| 2589 | 2793 |
| 2590 if (state.incomment) | 2794 if (state.incomment) |
| 2602 while (from < end) | 2806 while (from < end) |
| 2603 { | 2807 { |
| 2604 INC_FROM; | 2808 INC_FROM; |
| 2605 code = prev_from_syntax & 0xff; | 2809 code = prev_from_syntax & 0xff; |
| 2606 | 2810 |
| 2607 if (code == Scomment) | 2811 if (from < end |
| 2608 { | 2812 && SYNTAX_FLAGS_COMSTART_FIRST (prev_from_syntax) |
| 2609 state.comstyle = SYNTAX_FLAGS_COMMENT_STYLE (prev_from_syntax); | 2813 && (c1 = FETCH_CHAR (from_byte), |
| 2610 state.incomment = (SYNTAX_FLAGS_COMMENT_NESTED (prev_from_syntax) ? | 2814 SYNTAX_COMSTART_SECOND (c1))) |
| 2611 1 : -1); | 2815 /* Duplicate code to avoid a complex if-expression |
| 2816 which causes trouble for the SGI compiler. */ | |
| 2817 { | |
| 2818 /* Record the comment style we have entered so that only | |
| 2819 the comment-end sequence of the same style actually | |
| 2820 terminates the comment section. */ | |
| 2821 state.comstyle = SYNTAX_COMMENT_STYLE (c1); | |
| 2822 comnested = SYNTAX_FLAGS_COMMENT_NESTED (prev_from_syntax); | |
| 2823 comnested = comnested || SYNTAX_COMMENT_NESTED (c1); | |
| 2824 state.incomment = comnested ? 1 : -1; | |
| 2612 state.comstr_start = prev_from; | 2825 state.comstr_start = prev_from; |
| 2826 INC_FROM; | |
| 2827 code = Scomment; | |
| 2613 } | 2828 } |
| 2614 else if (code == Scomment_fence) | 2829 else if (code == Scomment_fence) |
| 2615 { | 2830 { |
| 2616 /* Record the comment style we have entered so that only | 2831 /* Record the comment style we have entered so that only |
| 2617 the comment-end sequence of the same style actually | 2832 the comment-end sequence of the same style actually |
| 2619 state.comstyle = ST_COMMENT_STYLE; | 2834 state.comstyle = ST_COMMENT_STYLE; |
| 2620 state.incomment = -1; | 2835 state.incomment = -1; |
| 2621 state.comstr_start = prev_from; | 2836 state.comstr_start = prev_from; |
| 2622 code = Scomment; | 2837 code = Scomment; |
| 2623 } | 2838 } |
| 2624 else if (from < end) | 2839 else if (code == Scomment) |
| 2625 if (SYNTAX_FLAGS_COMSTART_FIRST (prev_from_syntax)) | 2840 { |
| 2626 if (c1 = FETCH_CHAR (from_byte), | 2841 state.comstyle = SYNTAX_FLAGS_COMMENT_STYLE (prev_from_syntax); |
| 2627 SYNTAX_COMSTART_SECOND (c1)) | 2842 state.incomment = (SYNTAX_FLAGS_COMMENT_NESTED (prev_from_syntax) ? |
| 2628 /* Duplicate code to avoid a complex if-expression | 2843 1 : -1); |
| 2629 which causes trouble for the SGI compiler. */ | 2844 state.comstr_start = prev_from; |
| 2630 { | 2845 } |
| 2631 /* Record the comment style we have entered so that only | |
| 2632 the comment-end sequence of the same style actually | |
| 2633 terminates the comment section. */ | |
| 2634 state.comstyle = SYNTAX_COMMENT_STYLE (c1); | |
| 2635 comnested = SYNTAX_FLAGS_COMMENT_NESTED (prev_from_syntax); | |
| 2636 comnested = comnested || SYNTAX_COMMENT_NESTED (c1); | |
| 2637 state.incomment = comnested ? 1 : -1; | |
| 2638 state.comstr_start = prev_from; | |
| 2639 INC_FROM; | |
| 2640 code = Scomment; | |
| 2641 } | |
| 2642 | 2846 |
| 2643 if (SYNTAX_FLAGS_PREFIX (prev_from_syntax)) | 2847 if (SYNTAX_FLAGS_PREFIX (prev_from_syntax)) |
| 2644 continue; | 2848 continue; |
| 2645 switch (SWITCH_ENUM_CAST (code)) | 2849 switch (SWITCH_ENUM_CAST (code)) |
| 2646 { | 2850 { |
| 2659 curlevel->last = prev_from; | 2863 curlevel->last = prev_from; |
| 2660 symstarted: | 2864 symstarted: |
| 2661 while (from < end) | 2865 while (from < end) |
| 2662 { | 2866 { |
| 2663 /* Some compilers can't handle this inside the switch. */ | 2867 /* Some compilers can't handle this inside the switch. */ |
| 2664 temp = SYNTAX (FETCH_CHAR (from_byte)); | 2868 temp = FETCH_CHAR (from_byte); |
| 2869 temp = SYNTAX (temp); | |
| 2665 switch (temp) | 2870 switch (temp) |
| 2666 { | 2871 { |
| 2667 case Scharquote: | 2872 case Scharquote: |
| 2668 case Sescape: | 2873 case Sescape: |
| 2669 INC_FROM; | 2874 INC_FROM; |
| 2813 doc: /* Parse Lisp syntax starting at FROM until TO; return status of parse at TO. | 3018 doc: /* Parse Lisp syntax starting at FROM until TO; return status of parse at TO. |
| 2814 Parsing stops at TO or when certain criteria are met; | 3019 Parsing stops at TO or when certain criteria are met; |
| 2815 point is set to where parsing stops. | 3020 point is set to where parsing stops. |
| 2816 If fifth arg OLDSTATE is omitted or nil, | 3021 If fifth arg OLDSTATE is omitted or nil, |
| 2817 parsing assumes that FROM is the beginning of a function. | 3022 parsing assumes that FROM is the beginning of a function. |
| 2818 Value is a list of ten elements describing final state of parsing: | 3023 Value is a list of elements describing final state of parsing: |
| 2819 0. depth in parens. | 3024 0. depth in parens. |
| 2820 1. character address of start of innermost containing list; nil if none. | 3025 1. character address of start of innermost containing list; nil if none. |
| 2821 2. character address of start of last complete sexp terminated. | 3026 2. character address of start of last complete sexp terminated. |
| 2822 3. non-nil if inside a string. | 3027 3. non-nil if inside a string. |
| 2823 (it is the character that will terminate the string, | 3028 (it is the character that will terminate the string, |
| 2832 9. Intermediate data for continuation of parsing (subject to change). | 3037 9. Intermediate data for continuation of parsing (subject to change). |
| 2833 If third arg TARGETDEPTH is non-nil, parsing stops if the depth | 3038 If third arg TARGETDEPTH is non-nil, parsing stops if the depth |
| 2834 in parentheses becomes equal to TARGETDEPTH. | 3039 in parentheses becomes equal to TARGETDEPTH. |
| 2835 Fourth arg STOPBEFORE non-nil means stop when come to | 3040 Fourth arg STOPBEFORE non-nil means stop when come to |
| 2836 any character that starts a sexp. | 3041 any character that starts a sexp. |
| 2837 Fifth arg OLDSTATE is a nine-element list like what this function returns. | 3042 Fifth arg OLDSTATE is a list like what this function returns. |
| 2838 It is used to initialize the state of the parse. Elements number 1, 2, 6 | 3043 It is used to initialize the state of the parse. Elements number 1, 2, 6 |
| 2839 and 8 are ignored; you can leave off element 8 (the last) entirely. | 3044 and 8 are ignored; you can leave off element 8 (the last) entirely. |
| 2840 Sixth arg COMMENTSTOP non-nil means stop at the start of a comment. | 3045 Sixth arg COMMENTSTOP non-nil means stop at the start of a comment. |
| 2841 If it is symbol `syntax-table', stop after the start of a comment or a | 3046 If it is symbol `syntax-table', stop after the start of a comment or a |
| 2842 string, or after end of a comment or a string. */) | 3047 string, or after end of a comment or a string. */) |
| 2968 Qsyntax_table_p = intern ("syntax-table-p"); | 3173 Qsyntax_table_p = intern ("syntax-table-p"); |
| 2969 staticpro (&Qsyntax_table_p); | 3174 staticpro (&Qsyntax_table_p); |
| 2970 | 3175 |
| 2971 staticpro (&Vsyntax_code_object); | 3176 staticpro (&Vsyntax_code_object); |
| 2972 | 3177 |
| 3178 staticpro (&gl_state.object); | |
| 3179 staticpro (&gl_state.global_code); | |
| 3180 staticpro (&gl_state.current_syntax_table); | |
| 3181 staticpro (&gl_state.old_prop); | |
| 3182 | |
| 3183 /* Defined in regex.c */ | |
| 3184 staticpro (&re_match_object); | |
| 3185 | |
| 2973 Qscan_error = intern ("scan-error"); | 3186 Qscan_error = intern ("scan-error"); |
| 2974 staticpro (&Qscan_error); | 3187 staticpro (&Qscan_error); |
| 2975 Fput (Qscan_error, Qerror_conditions, | 3188 Fput (Qscan_error, Qerror_conditions, |
| 2976 Fcons (Qscan_error, Fcons (Qerror, Qnil))); | 3189 Fcons (Qscan_error, Fcons (Qerror, Qnil))); |
| 2977 Fput (Qscan_error, Qerror_message, | 3190 Fput (Qscan_error, Qerror_message, |
| 3021 defsubr (&Sscan_lists); | 3234 defsubr (&Sscan_lists); |
| 3022 defsubr (&Sscan_sexps); | 3235 defsubr (&Sscan_sexps); |
| 3023 defsubr (&Sbackward_prefix_chars); | 3236 defsubr (&Sbackward_prefix_chars); |
| 3024 defsubr (&Sparse_partial_sexp); | 3237 defsubr (&Sparse_partial_sexp); |
| 3025 } | 3238 } |
| 3239 | |
| 3240 /* arch-tag: 3e297b9f-088e-4b64-8f4c-fb0b3443e412 | |
| 3241 (do not change this comment) */ |
