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) */