comparison src/syntax.c @ 20546:a475efff810e

(scan_sexps_forward): Additional arg FROM_BYTE. Calls changed. (find_defun_start): Additional arg POS_BYTE. Save final byte pos in find_start_value_byte. (find_start_value_byte): New variable. (Fforward_comment): Scan by bytes and chars. (Fbackward_prefix_chars): Scan by bytes and chars. (scan_words, scan_sexps_forward): Scan bytes as well as chars. (skip_chars, scan_lists): Scan by bytes and chars. Now static. (char_quoted): Take charpos and bytepos as args. (back_comment): Likewise. (update_syntax_table): Arg renamed. (inc_bytepos, dec_bytepos): New functions.
author Richard M. Stallman <rms@gnu.org>
date Thu, 01 Jan 1998 06:31:54 +0000
parents 26d12c66acc1
children a39bcf9c0e1e
comparison
equal deleted inserted replaced
20545:c20c92ff4055 20546:a475efff810e
39 #define ST_COMMENT_STYLE (256 + 1) 39 #define ST_COMMENT_STYLE (256 + 1)
40 #define ST_STRING_STYLE (256 + 2) 40 #define ST_STRING_STYLE (256 + 2)
41 #include "category.h" 41 #include "category.h"
42 42
43 Lisp_Object Qsyntax_table_p, Qsyntax_table, Qscan_error; 43 Lisp_Object Qsyntax_table_p, Qsyntax_table, Qscan_error;
44
45 static void scan_sexps_forward ();
46 static int char_quoted ();
47 44
48 int words_include_escapes; 45 int words_include_escapes;
49 int parse_sexp_lookup_properties; 46 int parse_sexp_lookup_properties;
50 47
51 /* Used as a temporary in SYNTAX_ENTRY and other macros in syntax.h, 48 /* Used as a temporary in SYNTAX_ENTRY and other macros in syntax.h,
70 }; 67 };
71 68
72 /* These variables are a cache for finding the start of a defun. 69 /* These variables are a cache for finding the start of a defun.
73 find_start_pos is the place for which the defun start was found. 70 find_start_pos is the place for which the defun start was found.
74 find_start_value is the defun start position found for it. 71 find_start_value is the defun start position found for it.
72 find_start_value_byte is the corresponding byte position.
75 find_start_buffer is the buffer it was found in. 73 find_start_buffer is the buffer it was found in.
76 find_start_begv is the BEGV value when it was found. 74 find_start_begv is the BEGV value when it was found.
77 find_start_modiff is the value of MODIFF when it was found. */ 75 find_start_modiff is the value of MODIFF when it was found. */
78 76
79 static int find_start_pos; 77 static int find_start_pos;
80 static int find_start_value; 78 static int find_start_value;
79 static int find_start_value_byte;
81 static struct buffer *find_start_buffer; 80 static struct buffer *find_start_buffer;
82 static int find_start_begv; 81 static int find_start_begv;
83 static int find_start_modiff; 82 static int find_start_modiff;
83
84
85 static int find_defun_start P_ ((int, int));
86 static int back_comment P_ ((int, int, int, int, int *, int *));
87 static int char_quoted P_ ((int, int));
88 static Lisp_Object skip_chars P_ ((int, int, Lisp_Object, Lisp_Object));
89 static Lisp_Object scan_lists P_ ((int, int, int, int));
90 static void scan_sexps_forward P_ ((struct lisp_parse_state *,
91 int, int, int, int,
92 int, Lisp_Object, int));
84 93
85 94
86 struct gl_state_s gl_state; /* Global state of syntax parser. */ 95 struct gl_state_s gl_state; /* Global state of syntax parser. */
87 96
88 INTERVAL interval_of (); 97 INTERVAL interval_of ();
89 #define INTERVALS_AT_ONCE 10 /* 1 + max-number of intervals 98 #define INTERVALS_AT_ONCE 10 /* 1 + max-number of intervals
90 to scan to property-change. */ 99 to scan to property-change. */
91 100
92 /* 101 /* Update gl_state to an appropriate interval which contains CHARPOS. The
93 Update gl_state to an appropriate interval which contains POS. The 102 sign of COUNT give the relative position of CHARPOS wrt the previously
94 sign of COUNT give the relative position of POS wrt the previously
95 valid interval. If INIT, only [be]_property fields of gl_state are 103 valid interval. If INIT, only [be]_property fields of gl_state are
96 valid at start, the rest is filled basing on OBJECT. 104 valid at start, the rest is filled basing on OBJECT.
97 105
98 `gl_state.*_i' are the intervals, and pos is further in the search 106 `gl_state.*_i' are the intervals, and CHARPOS is further in the search
99 direction than the intervals - or in an interval. We update the 107 direction than the intervals - or in an interval. We update the
100 current syntax-table basing on the property of this interval, and 108 current syntax-table basing on the property of this interval, and
101 update the interval to start further than POS - or be 109 update the interval to start further than CHARPOS - or be
102 NULL_INTERVAL. We also update lim_property to be the next value of 110 NULL_INTERVAL. We also update lim_property to be the next value of
103 pos to call this subroutine again - or be before/after the 111 charpos to call this subroutine again - or be before/after the
104 start/end of OBJECT. */ 112 start/end of OBJECT. */
105 113
106 void 114 void
107 update_syntax_table (pos, count, init, object) 115 update_syntax_table (charpos, count, init, object)
108 int pos, count, init; 116 int charpos, count, init;
109 Lisp_Object object; 117 Lisp_Object object;
110 { 118 {
111 Lisp_Object tmp_table; 119 Lisp_Object tmp_table;
112 int cnt = 0, doing_extra = 0, invalidate = 1; 120 int cnt = 0, doing_extra = 0, invalidate = 1;
113 INTERVAL i, oldi; 121 INTERVAL i, oldi;
114 122
115 if (init) 123 if (init)
116 { 124 {
117 gl_state.start = gl_state.b_property; 125 gl_state.start = gl_state.b_property;
118 gl_state.stop = gl_state.e_property; 126 gl_state.stop = gl_state.e_property;
119 gl_state.forward_i = interval_of (pos, object); 127 gl_state.forward_i = interval_of (charpos, object);
120 i = gl_state.backward_i = gl_state.forward_i; 128 i = gl_state.backward_i = gl_state.forward_i;
121 gl_state.left_ok = gl_state.right_ok = 1; 129 gl_state.left_ok = gl_state.right_ok = 1;
122 invalidate = 0; 130 invalidate = 0;
123 if (NULL_INTERVAL_P (i)) 131 if (NULL_INTERVAL_P (i))
124 return; 132 return;
126 gl_state.e_property = INTERVAL_LAST_POS (i); 134 gl_state.e_property = INTERVAL_LAST_POS (i);
127 goto update; 135 goto update;
128 } 136 }
129 oldi = i = count > 0 ? gl_state.forward_i : gl_state.backward_i; 137 oldi = i = count > 0 ? gl_state.forward_i : gl_state.backward_i;
130 138
131 /* We are guarantied to be called with pos either in i, of further off. */ 139 /* We are guarantied to be called with CHARPOS either in i,
140 or further off. */
132 if (NULL_INTERVAL_P (i)) 141 if (NULL_INTERVAL_P (i))
133 error ("Error in syntax_table logic for to-the-end intervals"); 142 error ("Error in syntax_table logic for to-the-end intervals");
134 else if (pos < i->position) /* Move left. */ 143 else if (charpos < i->position) /* Move left. */
135 { 144 {
136 if (count > 0) 145 if (count > 0)
137 error ("Error in syntax_table logic for intervals <-."); 146 error ("Error in syntax_table logic for intervals <-.");
138 /* Update the interval. */ 147 /* Update the interval. */
139 i = update_interval (i, pos); 148 i = update_interval (i, charpos);
140 if (oldi->position != INTERVAL_LAST_POS (i)) 149 if (oldi->position != INTERVAL_LAST_POS (i))
141 { 150 {
142 invalidate = 0; 151 invalidate = 0;
143 gl_state.right_ok = 1; /* Invalidate the other end. */ 152 gl_state.right_ok = 1; /* Invalidate the other end. */
144 gl_state.forward_i = i; 153 gl_state.forward_i = i;
145 gl_state.e_property = INTERVAL_LAST_POS (i); 154 gl_state.e_property = INTERVAL_LAST_POS (i);
146 } 155 }
147 } 156 }
148 else if (pos >= INTERVAL_LAST_POS (i)) /* Move right. */ 157 else if (charpos >= INTERVAL_LAST_POS (i)) /* Move right. */
149 { 158 {
150 if (count < 0) 159 if (count < 0)
151 error ("Error in syntax_table logic for intervals ->."); 160 error ("Error in syntax_table logic for intervals ->.");
152 /* Update the interval. */ 161 /* Update the interval. */
153 i = update_interval (i, pos); 162 i = update_interval (i, charpos);
154 if (i->position != INTERVAL_LAST_POS (oldi)) 163 if (i->position != INTERVAL_LAST_POS (oldi))
155 { 164 {
156 invalidate = 0; 165 invalidate = 0;
157 gl_state.left_ok = 1; /* Invalidate the other end. */ 166 gl_state.left_ok = 1; /* Invalidate the other end. */
158 gl_state.backward_i = i; 167 gl_state.backward_i = i;
246 gl_state.backward_i = i; 255 gl_state.backward_i = i;
247 } 256 }
248 } 257 }
249 } 258 }
250 259
251 /* Returns TRUE if char at POS is quoted. 260 /* Returns TRUE if char at CHARPOS is quoted.
252 Global syntax-table data should be set up already to be good at pos 261 Global syntax-table data should be set up already to be good at CHARPOS
253 or after. On return global syntax data is good for lookup at POS. */ 262 or after. On return global syntax data is good for lookup at CHARPOS. */
254 263
255 static int 264 static int
256 char_quoted (pos) 265 char_quoted (charpos, bytepos)
257 register int pos; 266 register int charpos, bytepos;
258 { 267 {
259 register enum syntaxcode code; 268 register enum syntaxcode code;
260 register int beg = BEGV; 269 register int beg = BEGV;
261 register int quoted = 0; 270 register int quoted = 0;
262 int temp_pos = pos; 271 int orig = charpos;
263 272
264 DEC_POS (temp_pos); 273 DEC_BOTH (charpos, bytepos);
265 while (temp_pos >= beg 274
266 && ( UPDATE_SYNTAX_TABLE_BACKWARD (temp_pos), 1) 275 while (bytepos >= beg)
267 && ((code = SYNTAX (FETCH_CHAR (temp_pos))) == Scharquote 276 {
268 || code == Sescape)) 277 UPDATE_SYNTAX_TABLE_BACKWARD (charpos);
269 { 278 code = SYNTAX (FETCH_CHAR (bytepos));
270 temp_pos--, quoted = !quoted; 279 if (! (code == Scharquote || code == Sescape))
271 } 280 break;
272 UPDATE_SYNTAX_TABLE (pos); 281
282 DEC_BOTH (charpos, bytepos);
283 quoted = !quoted;
284 }
285
286 UPDATE_SYNTAX_TABLE (orig);
273 return quoted; 287 return quoted;
288 }
289
290 /* Return the bytepos one character after BYTEPOS.
291 We assume that BYTEPOS is not at the end of the buffer. */
292
293 INLINE int
294 inc_bytepos (bytepos)
295 int bytepos;
296 {
297 INC_POS (bytepos);
298 return bytepos;
299 }
300
301 /* Return the bytepos one character before BYTEPOS.
302 We assume that BYTEPOS is not at the start of the buffer. */
303
304 INLINE int
305 dec_bytepos (bytepos)
306 int bytepos;
307 {
308 DEC_POS (bytepos);
309 return bytepos;
274 } 310 }
275 311
276 /* Find a defun-start that is the last one before POS (or nearly the last). 312 /* Find a defun-start that is the last one before POS (or nearly the last).
277 We record what we find, so that another call in the same area 313 We record what we find, so that another call in the same area
278 can return the same value right away. 314 can return the same value right away.
280 There is no promise at which position the global syntax data is 316 There is no promise at which position the global syntax data is
281 valid on return from the subroutine, so the caller should explicitly 317 valid on return from the subroutine, so the caller should explicitly
282 update the global data. */ 318 update the global data. */
283 319
284 static int 320 static int
285 find_defun_start (pos) 321 find_defun_start (pos, pos_byte)
286 int pos; 322 int pos, pos_byte;
287 { 323 {
288 int tem; 324 int tem;
289 int shortage; 325 int shortage;
326 int opoint = PT, opoint_byte = PT_BYTE;
290 327
291 /* Use previous finding, if it's valid and applies to this inquiry. */ 328 /* Use previous finding, if it's valid and applies to this inquiry. */
292 if (current_buffer == find_start_buffer 329 if (current_buffer == find_start_buffer
293 /* Reuse the defun-start even if POS is a little farther on. 330 /* Reuse the defun-start even if POS is a little farther on.
294 POS might be in the next defun, but that's ok. 331 POS might be in the next defun, but that's ok.
298 && BEGV == find_start_begv 335 && BEGV == find_start_begv
299 && MODIFF == find_start_modiff) 336 && MODIFF == find_start_modiff)
300 return find_start_value; 337 return find_start_value;
301 338
302 /* Back up to start of line. */ 339 /* Back up to start of line. */
303 tem = scan_buffer ('\n', pos, BEGV, -1, &shortage, 1); 340 scan_newline (pos, pos_byte, BEGV, BEGV_BYTE, -1, 1);
304 341
305 /* We optimize syntax-table lookup for rare updates. Thus we accept 342 /* We optimize syntax-table lookup for rare updates. Thus we accept
306 only those `^\s(' which are good in global _and_ text-property 343 only those `^\s(' which are good in global _and_ text-property
307 syntax-tables. */ 344 syntax-tables. */
308 gl_state.current_syntax_table = current_buffer->syntax_table; 345 gl_state.current_syntax_table = current_buffer->syntax_table;
309 gl_state.use_global = 0; 346 gl_state.use_global = 0;
310 while (tem > BEGV) 347 while (PT > BEGV)
311 { 348 {
312 /* Open-paren at start of line means we found our defun-start. */ 349 /* Open-paren at start of line means we found our defun-start. */
313 if (SYNTAX (FETCH_CHAR (tem)) == Sopen) 350 if (SYNTAX (FETCH_CHAR (PT_BYTE)) == Sopen)
314 { 351 {
315 SETUP_SYNTAX_TABLE (tem + 1, -1); /* Try again... */ 352 SETUP_SYNTAX_TABLE (PT + 1, -1); /* Try again... */
316 if (SYNTAX (FETCH_CHAR (tem)) == Sopen) 353 if (SYNTAX (FETCH_CHAR (PT_BYTE)) == Sopen)
317 break; 354 break;
318 /* Now fallback to the default value. */ 355 /* Now fallback to the default value. */
319 gl_state.current_syntax_table = current_buffer->syntax_table; 356 gl_state.current_syntax_table = current_buffer->syntax_table;
320 gl_state.use_global = 0; 357 gl_state.use_global = 0;
321 } 358 }
322 /* Move to beg of previous line. */ 359 /* Move to beg of previous line. */
323 tem = scan_buffer ('\n', tem, BEGV, -2, &shortage, 1); 360 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -2, 1);
324 } 361 }
325 362
326 /* Record what we found, for the next try. */ 363 /* Record what we found, for the next try. */
327 find_start_value = tem; 364 find_start_value = PT;
365 find_start_value_byte = PT_BYTE;
328 find_start_buffer = current_buffer; 366 find_start_buffer = current_buffer;
329 find_start_modiff = MODIFF; 367 find_start_modiff = MODIFF;
330 find_start_begv = BEGV; 368 find_start_begv = BEGV;
331 find_start_pos = pos; 369 find_start_pos = pos;
332 370
371 TEMP_SET_PT_BOTH (opoint, opoint_byte);
372
333 return find_start_value; 373 return find_start_value;
334 } 374 }
335 375
336 /* Checks whether FROM is at the end of a comment; 376 /* Checks whether charpos FROM is at the end of a comment.
337 and if so, returns position of the start of the comment. 377 FROM_BYTE is the bytepos corresponding to FROM.
338 But does not move back before STOP. 378 Do not move back before STOP.
339 Returns -1 if there is no comment ending at FROM. 379
380 Return a positive value if we find a comment ending at FROM/FROM_BYTE;
381 return -1 otherwise.
382
383 If successful, store the charpos of the comment's beginning
384 into *CHARPOS_PTR, and the bytepos into *BYTEPOS_PTR.
340 385
341 Global syntax data remains valid for backward search starting at 386 Global syntax data remains valid for backward search starting at
342 the returned value (or at FROM, if the search was not successful). */ 387 the returned value (or at FROM, if the search was not successful). */
343 388
344 static int 389 static int
345 back_comment (from, stop, comstyle) 390 back_comment (from, from_byte, stop, comstyle, charpos_ptr, bytepos_ptr)
346 int from, stop, comstyle; 391 int from, from_byte, stop;
392 int comstyle;
393 int *charpos_ptr, *bytepos_ptr;
347 { 394 {
348 /* Look back, counting the parity of string-quotes, 395 /* Look back, counting the parity of string-quotes,
349 and recording the comment-starters seen. 396 and recording the comment-starters seen.
350 When we reach a safe place, assume that's not in a string; 397 When we reach a safe place, assume that's not in a string;
351 then step the main scan to the earliest comment-starter seen 398 then step the main scan to the earliest comment-starter seen
356 PARITY is current parity of quotes from the comment end. */ 403 PARITY is current parity of quotes from the comment end. */
357 int parity = 0; 404 int parity = 0;
358 int my_stringend = 0; 405 int my_stringend = 0;
359 int string_lossage = 0; 406 int string_lossage = 0;
360 int comment_end = from; 407 int comment_end = from;
408 int comment_end_byte = from_byte;
361 int comstart_pos = 0; 409 int comstart_pos = 0;
362 int comstart_parity = 0; 410 int comstart_parity = 0;
411 int comstart_byte;
363 int scanstart = from - 1; 412 int scanstart = from - 1;
364 register enum syntaxcode code; 413 register enum syntaxcode code;
365 int c; 414 int c;
366 415
367 /* At beginning of range to scan, we're outside of strings; 416 /* At beginning of range to scan, we're outside of strings;
368 that determines quote parity to the comment-end. */ 417 that determines quote parity to the comment-end. */
369 while (from != stop) 418 while (from != stop)
370 { 419 {
420 int temp_byte;
421
371 /* Move back and examine a character. */ 422 /* Move back and examine a character. */
372 DEC_POS (from); 423 DEC_BOTH (from, from_byte);
373 UPDATE_SYNTAX_TABLE_BACKWARD (from); 424 UPDATE_SYNTAX_TABLE_BACKWARD (from);
374 425
375 c = FETCH_CHAR (from); 426 c = FETCH_CHAR (from_byte);
376 code = SYNTAX (c); 427 code = SYNTAX (c);
377 428
378 /* If this char is the second of a 2-char comment end sequence, 429 /* If this char is the second of a 2-char comment end sequence,
379 back up and give the pair the appropriate syntax. */ 430 back up and give the pair the appropriate syntax. */
380 if (from > stop && SYNTAX_COMEND_SECOND (c) 431 if (from > stop && SYNTAX_COMEND_SECOND (c)
381 && SYNTAX_COMEND_FIRST (FETCH_CHAR (from - 1))) 432 && (temp_byte = dec_bytepos (from_byte),
433 SYNTAX_COMEND_FIRST (FETCH_CHAR (temp_byte))))
382 { 434 {
383 code = Sendcomment; 435 code = Sendcomment;
384 DEC_POS (from); 436 DEC_BOTH (from, from_byte);
385 /* This is apparently the best we can do: */ 437 /* This is apparently the best we can do: */
386 UPDATE_SYNTAX_TABLE_BACKWARD (from); 438 UPDATE_SYNTAX_TABLE_BACKWARD (from);
387 c = FETCH_CHAR (from); 439 c = FETCH_CHAR (from_byte);
388 } 440 }
389 441
390 /* If this char starts a 2-char comment start sequence, 442 /* If this char starts a 2-char comment start sequence,
391 treat it like a 1-char comment starter. */ 443 treat it like a 1-char comment starter. */
392 if (from < scanstart && SYNTAX_COMSTART_FIRST (c) 444 if (from < scanstart && SYNTAX_COMSTART_FIRST (c)
393 && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from + 1)) 445 && (temp_byte = inc_bytepos (from_byte),
394 && comstyle == SYNTAX_COMMENT_STYLE (FETCH_CHAR (from + 1))) 446 (SYNTAX_COMSTART_SECOND (FETCH_CHAR (temp_byte))
447 && comstyle == SYNTAX_COMMENT_STYLE (FETCH_CHAR (temp_byte)))))
395 code = Scomment; 448 code = Scomment;
396 449
397 /* Ignore escaped characters. */ 450 /* Ignore escaped characters. */
398 if (char_quoted (from)) 451 if (char_quoted (from, from_byte))
399 continue; 452 continue;
400 453
401 /* Track parity of quotes. */ 454 /* Track parity of quotes. */
402 if (code == Sstring) 455 if (code == Sstring)
403 { 456 {
412 465
413 if (code == Sstring_fence || code == Scomment_fence) 466 if (code == Sstring_fence || code == Scomment_fence)
414 { 467 {
415 parity ^= 1; 468 parity ^= 1;
416 if (my_stringend == 0) 469 if (my_stringend == 0)
417 my_stringend = 470 my_stringend
418 code == Sstring_fence ? ST_STRING_STYLE : ST_COMMENT_STYLE; 471 = code == Sstring_fence ? ST_STRING_STYLE : ST_COMMENT_STYLE;
419 /* If we have two kinds of string delimiters. 472 /* If we have two kinds of string delimiters.
420 There's no way to grok this scanning backwards. */ 473 There's no way to grok this scanning backwards. */
421 else if (my_stringend != (code == Sstring_fence 474 else if (my_stringend != (code == Sstring_fence
422 ? ST_STRING_STYLE : ST_COMMENT_STYLE)) 475 ? ST_STRING_STYLE : ST_COMMENT_STYLE))
423 string_lossage = 1; 476 string_lossage = 1;
427 quote-parity to the comment-end. */ 480 quote-parity to the comment-end. */
428 if (code == Scomment) 481 if (code == Scomment)
429 { 482 {
430 comstart_parity = parity; 483 comstart_parity = parity;
431 comstart_pos = from; 484 comstart_pos = from;
485 comstart_byte = from_byte;
432 } 486 }
433 487
434 /* If we find another earlier comment-ender, 488 /* If we find another earlier comment-ender,
435 any comment-starts earlier than that don't count 489 any comment-starts earlier than that don't count
436 (because they go with the earlier comment-ender). */ 490 (because they go with the earlier comment-ender). */
437 if (code == Sendcomment 491 if (code == Sendcomment
438 && SYNTAX_COMMENT_STYLE (FETCH_CHAR (from)) == comstyle) 492 && SYNTAX_COMMENT_STYLE (FETCH_CHAR (from_byte)) == comstyle)
439 break; 493 break;
440 494
441 /* Assume a defun-start point is outside of strings. */ 495 /* Assume a defun-start point is outside of strings. */
442 if (code == Sopen 496 if (code == Sopen
443 && (from == stop || FETCH_CHAR (from - 1) == '\n')) 497 && (from == stop
498 || (temp_byte = dec_bytepos (from_byte),
499 FETCH_CHAR (temp_byte) == '\n')))
444 break; 500 break;
445 } 501 }
446 502
447 if (comstart_pos == 0) 503 if (comstart_pos == 0)
448 { 504 {
449 from = comment_end; 505 from = comment_end;
506 from_byte = comment_end_byte;
450 UPDATE_SYNTAX_TABLE_FORWARD (comment_end - 1); 507 UPDATE_SYNTAX_TABLE_FORWARD (comment_end - 1);
451 } 508 }
452 /* If the earliest comment starter 509 /* If the earliest comment starter
453 is followed by uniform paired string quotes or none, 510 is followed by uniform paired string quotes or none,
454 we know it can't be inside a string 511 we know it can't be inside a string
455 since if it were then the comment ender would be inside one. 512 since if it were then the comment ender would be inside one.
456 So it does start a comment. Skip back to it. */ 513 So it does start a comment. Skip back to it. */
457 else if (comstart_parity == 0 && !string_lossage) 514 else if (comstart_parity == 0 && !string_lossage)
458 { 515 {
459 from = comstart_pos; 516 from = comstart_pos;
517 from_byte = comstart_byte;
460 /* Globals are correct now. */ 518 /* Globals are correct now. */
461 } 519 }
462 else 520 else
463 { 521 {
464 /* We had two kinds of string delimiters mixed up 522 /* We had two kinds of string delimiters mixed up
465 together. Decode this going forwards. 523 together. Decode this going forwards.
466 Scan fwd from the previous comment ender 524 Scan fwd from the previous comment ender
467 to the one in question; this records where we 525 to the one in question; this records where we
468 last passed a comment starter. */ 526 last passed a comment starter. */
469 struct lisp_parse_state state; 527 struct lisp_parse_state state;
470 scan_sexps_forward (&state, find_defun_start (comment_end), 528 scan_sexps_forward (&state,
529 find_defun_start (comment_end, comment_end_byte),
530 find_start_value_byte,
471 comment_end - 1, -10000, 0, Qnil, 0); 531 comment_end - 1, -10000, 0, Qnil, 0);
472 if (state.incomment) 532 if (state.incomment)
473 { 533 {
474 /* scan_sexps_forward changed the direction of search in 534 /* scan_sexps_forward changed the direction of search in
475 global variables, so we need to update it completely. */ 535 global variables, so we need to update it completely. */
478 } 538 }
479 else 539 else
480 { 540 {
481 from = comment_end; 541 from = comment_end;
482 } 542 }
543 from_byte = CHAR_TO_BYTE (from);
483 UPDATE_SYNTAX_TABLE_FORWARD (from - 1); 544 UPDATE_SYNTAX_TABLE_FORWARD (from - 1);
484 } 545 }
485 546
547 *charpos_ptr = from;
548 *bytepos_ptr = from_byte;
549
486 return from; 550 return from;
487 } 551 }
488 552
489 DEFUN ("syntax-table-p", Fsyntax_table_p, Ssyntax_table_p, 1, 1, 0, 553 DEFUN ("syntax-table-p", Fsyntax_table_p, Ssyntax_table_p, 1, 1, 0,
490 "Return t if OBJECT is a syntax table.\n\ 554 "Return t if OBJECT is a syntax table.\n\
968 scan_words (from, count) 1032 scan_words (from, count)
969 register int from, count; 1033 register int from, count;
970 { 1034 {
971 register int beg = BEGV; 1035 register int beg = BEGV;
972 register int end = ZV; 1036 register int end = ZV;
1037 register int from_byte = CHAR_TO_BYTE (from);
973 register enum syntaxcode code; 1038 register enum syntaxcode code;
974 int ch0, ch1; 1039 int ch0, ch1;
975 int temp_pos;
976 1040
977 immediate_quit = 1; 1041 immediate_quit = 1;
978 QUIT; 1042 QUIT;
979 1043
980 SETUP_SYNTAX_TABLE (from, count); 1044 SETUP_SYNTAX_TABLE (from, count);
987 { 1051 {
988 immediate_quit = 0; 1052 immediate_quit = 0;
989 return 0; 1053 return 0;
990 } 1054 }
991 UPDATE_SYNTAX_TABLE_FORWARD (from); 1055 UPDATE_SYNTAX_TABLE_FORWARD (from);
992 ch0 = FETCH_CHAR (from); 1056 ch0 = FETCH_CHAR (from_byte);
993 code = SYNTAX (ch0); 1057 code = SYNTAX (ch0);
994 INC_POS (from); 1058 INC_BOTH (from, from_byte);
995 if (words_include_escapes 1059 if (words_include_escapes
996 && (code == Sescape || code == Scharquote)) 1060 && (code == Sescape || code == Scharquote))
997 break; 1061 break;
998 if (code == Sword) 1062 if (code == Sword)
999 break; 1063 break;
1002 position of the next character. */ 1066 position of the next character. */
1003 while (1) 1067 while (1)
1004 { 1068 {
1005 if (from == end) break; 1069 if (from == end) break;
1006 UPDATE_SYNTAX_TABLE_FORWARD (from); 1070 UPDATE_SYNTAX_TABLE_FORWARD (from);
1007 ch1 = FETCH_CHAR (from); 1071 ch1 = FETCH_CHAR (from_byte);
1008 code = SYNTAX (ch1); 1072 code = SYNTAX (ch1);
1009 if (!(words_include_escapes 1073 if (!(words_include_escapes
1010 && (code == Sescape || code == Scharquote))) 1074 && (code == Sescape || code == Scharquote)))
1011 if (code != Sword || WORD_BOUNDARY_P (ch0, ch1)) 1075 if (code != Sword || WORD_BOUNDARY_P (ch0, ch1))
1012 break; 1076 break;
1013 INC_POS (from); 1077 INC_BOTH (from, from_byte);
1014 ch0 = ch1; 1078 ch0 = ch1;
1015 } 1079 }
1016 count--; 1080 count--;
1017 } 1081 }
1018 while (count < 0) 1082 while (count < 0)
1022 if (from == beg) 1086 if (from == beg)
1023 { 1087 {
1024 immediate_quit = 0; 1088 immediate_quit = 0;
1025 return 0; 1089 return 0;
1026 } 1090 }
1027 DEC_POS (from); 1091 DEC_BOTH (from, from_byte);
1028 UPDATE_SYNTAX_TABLE_BACKWARD (from); 1092 UPDATE_SYNTAX_TABLE_BACKWARD (from);
1029 ch1 = FETCH_CHAR (from); 1093 ch1 = FETCH_CHAR (from_byte);
1030 code = SYNTAX (ch1); 1094 code = SYNTAX (ch1);
1031 if (words_include_escapes 1095 if (words_include_escapes
1032 && (code == Sescape || code == Scharquote)) 1096 && (code == Sescape || code == Scharquote))
1033 break; 1097 break;
1034 if (code == Sword) 1098 if (code == Sword)
1036 } 1100 }
1037 /* Now CH1 is a character which ends a word and FROM is the 1101 /* Now CH1 is a character which ends a word and FROM is the
1038 position of it. */ 1102 position of it. */
1039 while (1) 1103 while (1)
1040 { 1104 {
1041 if (from == beg) break; 1105 int temp_byte;
1042 temp_pos = from; 1106
1043 DEC_POS (temp_pos); 1107 if (from == beg)
1108 break;
1109 temp_byte = dec_bytepos (from_byte);
1044 UPDATE_SYNTAX_TABLE_BACKWARD (from); 1110 UPDATE_SYNTAX_TABLE_BACKWARD (from);
1045 ch0 = FETCH_CHAR (temp_pos); 1111 ch0 = FETCH_CHAR (temp_byte);
1046 code = SYNTAX (ch0); 1112 code = SYNTAX (ch0);
1047 if (!(words_include_escapes 1113 if (!(words_include_escapes
1048 && (code == Sescape || code == Scharquote))) 1114 && (code == Sescape || code == Scharquote)))
1049 if (code != Sword || WORD_BOUNDARY_P (ch0, ch1)) 1115 if (code != Sword || WORD_BOUNDARY_P (ch0, ch1))
1050 break; 1116 break;
1051 from = temp_pos; 1117 DEC_BOTH (from, from_byte);
1052 ch1 = ch0; 1118 ch1 = ch0;
1053 } 1119 }
1054 count++; 1120 count++;
1055 } 1121 }
1056 1122
1126 Lisp_Object syntax, lim; 1192 Lisp_Object syntax, lim;
1127 { 1193 {
1128 return skip_chars (0, 1, syntax, lim); 1194 return skip_chars (0, 1, syntax, lim);
1129 } 1195 }
1130 1196
1131 Lisp_Object 1197 static Lisp_Object
1132 skip_chars (forwardp, syntaxp, string, lim) 1198 skip_chars (forwardp, syntaxp, string, lim)
1133 int forwardp, syntaxp; 1199 int forwardp, syntaxp;
1134 Lisp_Object string, lim; 1200 Lisp_Object string, lim;
1135 { 1201 {
1136 register unsigned char *p, *pend; 1202 register unsigned char *p, *pend;
1154 char_ranges = (int *) alloca (XSTRING (string)->size * (sizeof (int)) * 2); 1220 char_ranges = (int *) alloca (XSTRING (string)->size * (sizeof (int)) * 2);
1155 1221
1156 if (NILP (lim)) 1222 if (NILP (lim))
1157 XSETINT (lim, forwardp ? ZV : BEGV); 1223 XSETINT (lim, forwardp ? ZV : BEGV);
1158 else 1224 else
1159 CHECK_NUMBER_COERCE_MARKER (lim, 1); 1225 CHECK_NUMBER_COERCE_MARKER (lim, 0);
1160 1226
1161 /* In any case, don't allow scan outside bounds of buffer. */ 1227 /* In any case, don't allow scan outside bounds of buffer. */
1162 /* jla turned this off, for no known reason.
1163 bfox turned the ZV part on, and rms turned the
1164 BEGV part back on. */
1165 if (XINT (lim) > ZV) 1228 if (XINT (lim) > ZV)
1166 XSETFASTINT (lim, ZV); 1229 XSETFASTINT (lim, ZV);
1167 if (XINT (lim) < BEGV) 1230 if (XINT (lim) < BEGV)
1168 XSETFASTINT (lim, BEGV); 1231 XSETFASTINT (lim, BEGV);
1169 1232
1251 } 1314 }
1252 1315
1253 { 1316 {
1254 int start_point = PT; 1317 int start_point = PT;
1255 int pos = PT; 1318 int pos = PT;
1319 int pos_byte = PT_BYTE;
1256 1320
1257 immediate_quit = 1; 1321 immediate_quit = 1;
1258 if (syntaxp) 1322 if (syntaxp)
1259 { 1323 {
1260 SETUP_SYNTAX_TABLE (pos, forwardp ? 1 : -1); 1324 SETUP_SYNTAX_TABLE (pos, forwardp ? 1 : -1);
1261 if (forwardp) 1325 if (forwardp)
1262 { 1326 {
1263 if (multibyte) 1327 if (multibyte)
1264 { 1328 {
1265 while (pos < XINT (lim) 1329 while (pos < XINT (lim)
1266 && fastmap[(int) SYNTAX (FETCH_CHAR (pos))]) 1330 && fastmap[(int) SYNTAX (FETCH_CHAR (pos_byte))])
1267 { 1331 {
1268 INC_POS (pos); 1332 INC_BOTH (pos, pos_byte);
1269 UPDATE_SYNTAX_TABLE_FORWARD (pos); 1333 UPDATE_SYNTAX_TABLE_FORWARD (pos);
1270 } 1334 }
1271 } 1335 }
1272 else 1336 else
1273 { 1337 {
1283 { 1347 {
1284 if (multibyte) 1348 if (multibyte)
1285 { 1349 {
1286 while (pos > XINT (lim)) 1350 while (pos > XINT (lim))
1287 { 1351 {
1288 int savepos = pos; 1352 int savepos = pos_byte;
1289 DEC_POS (pos); 1353 DEC_BOTH (pos, pos_byte);
1290 UPDATE_SYNTAX_TABLE_BACKWARD (pos); 1354 UPDATE_SYNTAX_TABLE_BACKWARD (pos);
1291 if (!fastmap[(int) SYNTAX (FETCH_CHAR (pos))]) 1355 if (!fastmap[(int) SYNTAX (FETCH_CHAR (pos_byte))])
1292 { 1356 {
1293 pos = savepos; 1357 pos++;
1358 pos_byte = savepos;
1294 break; 1359 break;
1295 } 1360 }
1296 } 1361 }
1297 } 1362 }
1298 else 1363 else
1313 else 1378 else
1314 { 1379 {
1315 if (forwardp) 1380 if (forwardp)
1316 { 1381 {
1317 if (multibyte) 1382 if (multibyte)
1318 while (pos < XINT (lim) && fastmap[(c = FETCH_BYTE (pos))]) 1383 while (pos < XINT (lim) && fastmap[(c = FETCH_BYTE (pos_byte))])
1319 { 1384 {
1320 if (!BASE_LEADING_CODE_P (c)) 1385 if (!BASE_LEADING_CODE_P (c))
1321 pos++; 1386 INC_BOTH (pos, pos_byte);
1322 else if (n_char_ranges) 1387 else if (n_char_ranges)
1323 { 1388 {
1324 /* We much check CHAR_RANGES for a multibyte 1389 /* We much check CHAR_RANGES for a multibyte
1325 character. */ 1390 character. */
1326 ch = FETCH_MULTIBYTE_CHAR (pos); 1391 ch = FETCH_MULTIBYTE_CHAR (pos_byte);
1327 for (i = 0; i < n_char_ranges; i += 2) 1392 for (i = 0; i < n_char_ranges; i += 2)
1328 if ((ch >= char_ranges[i] && ch <= char_ranges[i + 1])) 1393 if ((ch >= char_ranges[i] && ch <= char_ranges[i + 1]))
1329 break; 1394 break;
1330 if (!(negate ^ (i < n_char_ranges))) 1395 if (!(negate ^ (i < n_char_ranges)))
1331 break; 1396 break;
1332 1397
1333 INC_POS (pos); 1398 INC_BOTH (pos, pos_byte);
1334 } 1399 }
1335 else 1400 else
1336 { 1401 {
1337 if (!negate) break; 1402 if (!negate) break;
1338 INC_POS (pos); 1403 INC_BOTH (pos, pos_byte);
1339 } 1404 }
1340 } 1405 }
1341 else 1406 else
1342 while (pos < XINT (lim) && fastmap[FETCH_BYTE (pos)]) 1407 while (pos < XINT (lim) && fastmap[FETCH_BYTE (pos)])
1343 pos++; 1408 pos++;
1345 else 1410 else
1346 { 1411 {
1347 if (multibyte) 1412 if (multibyte)
1348 while (pos > XINT (lim)) 1413 while (pos > XINT (lim))
1349 { 1414 {
1350 int savepos = pos; 1415 int savepos = pos_byte;
1351 DEC_POS (pos); 1416 DEC_BOTH (pos, pos_byte);
1352 if (fastmap[(c = FETCH_BYTE (pos))]) 1417 if (fastmap[(c = FETCH_BYTE (pos_byte))])
1353 { 1418 {
1354 if (!BASE_LEADING_CODE_P (c)) 1419 if (!BASE_LEADING_CODE_P (c))
1355 ; 1420 ;
1356 else if (n_char_ranges) 1421 else if (n_char_ranges)
1357 { 1422 {
1358 /* We much check CHAR_RANGES for a multibyte 1423 /* We much check CHAR_RANGES for a multibyte
1359 character. */ 1424 character. */
1360 ch = FETCH_MULTIBYTE_CHAR (pos); 1425 ch = FETCH_MULTIBYTE_CHAR (pos_byte);
1361 for (i = 0; i < n_char_ranges; i += 2) 1426 for (i = 0; i < n_char_ranges; i += 2)
1362 if (ch >= char_ranges[i] && ch <= char_ranges[i + 1]) 1427 if (ch >= char_ranges[i] && ch <= char_ranges[i + 1])
1363 break; 1428 break;
1364 if (!(negate ^ (i < n_char_ranges))) 1429 if (!(negate ^ (i < n_char_ranges)))
1365 { 1430 {
1366 pos = savepos; 1431 pos++;
1432 pos_byte = savepos;
1367 break; 1433 break;
1368 } 1434 }
1369 } 1435 }
1370 else 1436 else
1371 if (!negate) 1437 if (!negate)
1372 { 1438 {
1373 pos = savepos; 1439 pos++;
1440 pos_byte = savepos;
1374 break; 1441 break;
1375 } 1442 }
1376 } 1443 }
1377 else 1444 else
1378 { 1445 {
1379 pos = savepos; 1446 pos++;
1447 pos_byte = savepos;
1380 break; 1448 break;
1381 } 1449 }
1382 } 1450 }
1383 else 1451 else
1384 while (pos > XINT (lim) && fastmap[FETCH_BYTE (pos - 1)]) 1452 while (pos > XINT (lim) && fastmap[FETCH_BYTE (pos - 1)])
1385 pos--; 1453 pos--;
1386 } 1454 }
1387 } 1455 }
1388 1456
1457 #if 0 /* Not needed now that a position in mid-character
1458 cannot be specified in Lisp. */
1389 if (multibyte 1459 if (multibyte
1390 /* INC_POS or DEC_POS might have moved POS over LIM. */ 1460 /* INC_POS or DEC_POS might have moved POS over LIM. */
1391 && (forwardp ? (pos > XINT (lim)) : (pos < XINT (lim)))) 1461 && (forwardp ? (pos > XINT (lim)) : (pos < XINT (lim))))
1392 pos = XINT (lim); 1462 pos = XINT (lim);
1393 1463 #endif
1394 SET_PT (pos); 1464
1465 if (! multibyte)
1466 pos_byte = pos;
1467
1468 SET_PT_BOTH (pos, pos_byte);
1395 immediate_quit = 0; 1469 immediate_quit = 0;
1396 1470
1397 return make_number (PT - start_point); 1471 return make_number (PT - start_point);
1398 } 1472 }
1399 } 1473 }
1406 between them, return t; otherwise return nil.") 1480 between them, return t; otherwise return nil.")
1407 (count) 1481 (count)
1408 Lisp_Object count; 1482 Lisp_Object count;
1409 { 1483 {
1410 register int from; 1484 register int from;
1485 int from_byte;
1411 register int stop; 1486 register int stop;
1412 register int c, c1; 1487 register int c, c1;
1413 register enum syntaxcode code; 1488 register enum syntaxcode code;
1414 int comstyle = 0; /* style of comment encountered */ 1489 int comstyle = 0; /* style of comment encountered */
1415 int found; 1490 int found;
1416 int count1; 1491 int count1;
1417 int temp_pos; 1492 int temp_pos;
1493 int out_charpos, out_bytepos;
1418 1494
1419 CHECK_NUMBER (count, 0); 1495 CHECK_NUMBER (count, 0);
1420 count1 = XINT (count); 1496 count1 = XINT (count);
1421 stop = count1 > 0 ? ZV : BEGV; 1497 stop = count1 > 0 ? ZV : BEGV;
1422 1498
1423 immediate_quit = 1; 1499 immediate_quit = 1;
1424 QUIT; 1500 QUIT;
1425 1501
1426 from = PT; 1502 from = PT;
1503 from_byte = PT_BYTE;
1427 1504
1428 SETUP_SYNTAX_TABLE (from, count1); 1505 SETUP_SYNTAX_TABLE (from, count1);
1429 while (count1 > 0) 1506 while (count1 > 0)
1430 { 1507 {
1431 do 1508 do
1432 { 1509 {
1433 if (from == stop) 1510 if (from == stop)
1434 { 1511 {
1435 SET_PT (from); 1512 if (! NILP (current_buffer->enable_multibyte_characters))
1513 SET_PT_BOTH (from, from_byte);
1514 else
1515 SET_PT_BOTH (from_byte, from_byte);
1436 immediate_quit = 0; 1516 immediate_quit = 0;
1437 return Qnil; 1517 return Qnil;
1438 } 1518 }
1439 UPDATE_SYNTAX_TABLE_FORWARD (from); 1519 UPDATE_SYNTAX_TABLE_FORWARD (from);
1440 c = FETCH_CHAR (from); 1520 c = FETCH_CHAR (from_byte);
1441 code = SYNTAX (c); 1521 code = SYNTAX (c);
1442 INC_POS (from); 1522 INC_BOTH (from, from_byte);
1443 comstyle = 0; 1523 comstyle = 0;
1444 if (from < stop && SYNTAX_COMSTART_FIRST (c) 1524 if (from < stop && SYNTAX_COMSTART_FIRST (c)
1445 && (c1 = FETCH_CHAR (from), 1525 && (c1 = FETCH_CHAR (from_byte),
1446 SYNTAX_COMSTART_SECOND (c1))) 1526 SYNTAX_COMSTART_SECOND (c1)))
1447 { 1527 {
1448 /* We have encountered a comment start sequence and we 1528 /* We have encountered a comment start sequence and we
1449 are ignoring all text inside comments. We must record 1529 are ignoring all text inside comments. We must record
1450 the comment style this sequence begins so that later, 1530 the comment style this sequence begins so that later,
1451 only a comment end of the same style actually ends 1531 only a comment end of the same style actually ends
1452 the comment section. */ 1532 the comment section. */
1453 code = Scomment; 1533 code = Scomment;
1454 comstyle = SYNTAX_COMMENT_STYLE (c1); 1534 comstyle = SYNTAX_COMMENT_STYLE (c1);
1455 INC_POS (from); 1535 INC_BOTH (from, from_byte);
1456 } 1536 }
1457 } 1537 }
1458 while (code == Swhitespace || code == Sendcomment); 1538 while (code == Swhitespace || code == Sendcomment);
1539
1459 if (code != Scomment && code != Scomment_fence) 1540 if (code != Scomment && code != Scomment_fence)
1460 { 1541 {
1461 immediate_quit = 0; 1542 immediate_quit = 0;
1462 DEC_POS (from); 1543 DEC_BOTH (from, from_byte);
1463 SET_PT (from); 1544 if (! NILP (current_buffer->enable_multibyte_characters))
1545 SET_PT_BOTH (from, from_byte);
1546 else
1547 SET_PT_BOTH (from_byte, from_byte);
1464 return Qnil; 1548 return Qnil;
1465 } 1549 }
1466 /* We're at the start of a comment. */ 1550 /* We're at the start of a comment. */
1467 while (1) 1551 while (1)
1468 { 1552 {
1469 if (from == stop) 1553 if (from == stop)
1470 { 1554 {
1471 immediate_quit = 0; 1555 immediate_quit = 0;
1472 SET_PT (from); 1556 if (! NILP (current_buffer->enable_multibyte_characters))
1557 SET_PT_BOTH (from, from_byte);
1558 else
1559 SET_PT_BOTH (from_byte, from_byte);
1473 return Qnil; 1560 return Qnil;
1474 } 1561 }
1475 UPDATE_SYNTAX_TABLE_FORWARD (from); 1562 UPDATE_SYNTAX_TABLE_FORWARD (from);
1476 c = FETCH_CHAR (from); 1563 c = FETCH_CHAR (from_byte);
1477 INC_POS (from); 1564 INC_BOTH (from, from_byte);
1478 if (SYNTAX (c) == Sendcomment 1565 if (SYNTAX (c) == Sendcomment
1479 && SYNTAX_COMMENT_STYLE (c) == comstyle) 1566 && SYNTAX_COMMENT_STYLE (c) == comstyle)
1480 /* we have encountered a comment end of the same style 1567 /* we have encountered a comment end of the same style
1481 as the comment sequence which began this comment 1568 as the comment sequence which began this comment
1482 section */ 1569 section */
1486 /* we have encountered a comment end of the same style 1573 /* we have encountered a comment end of the same style
1487 as the comment sequence which began this comment 1574 as the comment sequence which began this comment
1488 section. */ 1575 section. */
1489 break; 1576 break;
1490 if (from < stop && SYNTAX_COMEND_FIRST (c) 1577 if (from < stop && SYNTAX_COMEND_FIRST (c)
1491 && (c1 = FETCH_CHAR (from), 1578 && (c1 = FETCH_CHAR (from_byte),
1492 SYNTAX_COMEND_SECOND (c1)) 1579 SYNTAX_COMEND_SECOND (c1))
1493 && SYNTAX_COMMENT_STYLE (c) == comstyle) 1580 && SYNTAX_COMMENT_STYLE (c) == comstyle)
1494 /* we have encountered a comment end of the same style 1581 /* we have encountered a comment end of the same style
1495 as the comment sequence which began this comment 1582 as the comment sequence which began this comment
1496 section */ 1583 section */
1497 { INC_POS (from); break; } 1584 {
1585 INC_BOTH (from, from_byte);
1586 break;
1587 }
1498 } 1588 }
1499 /* We have skipped one comment. */ 1589 /* We have skipped one comment. */
1500 count1--; 1590 count1--;
1501 } 1591 }
1502 1592
1505 while (1) 1595 while (1)
1506 { 1596 {
1507 int quoted; 1597 int quoted;
1508 if (from <= stop) 1598 if (from <= stop)
1509 { 1599 {
1510 SET_PT (stop); 1600 SET_PT_BOTH (BEGV, BEGV_BYTE);
1511 immediate_quit = 0; 1601 immediate_quit = 0;
1512 return Qnil; 1602 return Qnil;
1513 } 1603 }
1514 1604
1515 DEC_POS (from); 1605 DEC_BOTH (from, from_byte);
1516 quoted = char_quoted (from); 1606 quoted = char_quoted (from, from_byte);
1517 if (quoted) 1607 if (quoted)
1518 { 1608 {
1519 DEC_POS (from); 1609 DEC_BOTH (from, from_byte);
1520 goto leave; /* ????? XXXXX */ 1610 goto leave;
1521 } 1611 }
1522 UPDATE_SYNTAX_TABLE_BACKWARD (from); 1612 UPDATE_SYNTAX_TABLE_BACKWARD (from);
1523 c = FETCH_CHAR (from); 1613 c = FETCH_CHAR (from_byte);
1524 code = SYNTAX (c); 1614 code = SYNTAX (c);
1525 comstyle = 0; 1615 comstyle = 0;
1526 if (code == Sendcomment) 1616 if (code == Sendcomment)
1527 comstyle = SYNTAX_COMMENT_STYLE (c); 1617 comstyle = SYNTAX_COMMENT_STYLE (c);
1528 temp_pos = from; 1618 temp_pos = from_byte;
1529 DEC_POS (temp_pos); 1619 DEC_POS (temp_pos);
1530 if (from > stop && SYNTAX_COMEND_SECOND (c) 1620 if (from > stop && SYNTAX_COMEND_SECOND (c)
1531 && (c1 = FETCH_CHAR (temp_pos), 1621 && (c1 = FETCH_CHAR (temp_pos),
1532 SYNTAX_COMEND_FIRST (c1)) 1622 SYNTAX_COMEND_FIRST (c1))
1533 && !char_quoted (temp_pos)) 1623 && !char_quoted (from - 1, temp_pos))
1534 { 1624 {
1535 /* We must record the comment style encountered so that 1625 /* We must record the comment style encountered so that
1536 later, we can match only the proper comment begin 1626 later, we can match only the proper comment begin
1537 sequence of the same style. */ 1627 sequence of the same style. */
1538 code = Sendcomment; 1628 code = Sendcomment;
1539 comstyle = SYNTAX_COMMENT_STYLE (c1); 1629 comstyle = SYNTAX_COMMENT_STYLE (c1);
1540 from = temp_pos; 1630 DEC_BOTH (from, from_byte);
1541 } 1631 }
1542 if (from > stop && SYNTAX_COMSTART_SECOND (c) 1632 if (from > stop && SYNTAX_COMSTART_SECOND (c)
1543 && (c1 = FETCH_CHAR (temp_pos), 1633 && (c1 = FETCH_CHAR (temp_pos),
1544 SYNTAX_COMSTART_FIRST (c1)) 1634 SYNTAX_COMSTART_FIRST (c1))
1545 && !char_quoted (temp_pos)) 1635 && !char_quoted (from - 1, temp_pos))
1546 { 1636 {
1547 /* We must record the comment style encountered so that 1637 /* We must record the comment style encountered so that
1548 later, we can match only the proper comment begin 1638 later, we can match only the proper comment begin
1549 sequence of the same style. */ 1639 sequence of the same style. */
1550 code = Scomment; 1640 code = Scomment;
1551 from = temp_pos; 1641 DEC_BOTH (from, from_byte);
1552 } 1642 }
1553 1643
1554 if (code == Scomment_fence) 1644 if (code == Scomment_fence)
1555 { 1645 {
1556 /* Skip until first preceding unquoted comment_fence. */ 1646 /* Skip until first preceding unquoted comment_fence. */
1557 int found = 0, ini = from; 1647 int found = 0, ini = from, ini_byte = from_byte;
1558 1648
1559 while (--from != stop) 1649 while (1)
1560 { 1650 {
1651 DEC_BOTH (from, from_byte);
1652 if (from == stop)
1653 break;
1561 UPDATE_SYNTAX_TABLE_BACKWARD (from); 1654 UPDATE_SYNTAX_TABLE_BACKWARD (from);
1562 c = FETCH_CHAR (from); 1655 c = FETCH_CHAR (from_byte);
1563 if (SYNTAX (c) == Scomment_fence && !char_quoted (from)) 1656 if (SYNTAX (c) == Scomment_fence
1657 && !char_quoted (from, from_byte))
1564 { 1658 {
1565 found = 1; 1659 found = 1;
1566 break; 1660 break;
1567 } 1661 }
1568 } 1662 }
1569 if (found == 0) 1663 if (found == 0)
1570 { 1664 {
1571 from = ini; /* Set point to ini + 1. */ 1665 from = ini; /* Set point to ini + 1. */
1666 from_byte = ini_byte;
1572 goto leave; 1667 goto leave;
1573 } 1668 }
1574 } 1669 }
1575 else if (code == Sendcomment) 1670 else if (code == Sendcomment)
1576 { 1671 {
1577 #if 0 1672 found = back_comment (from, from_byte, stop, comstyle,
1578 if (code != SYNTAX (c)) 1673 &out_charpos, &out_bytepos);
1579 /* For a two-char comment ender, we can assume 1674 if (found != -1)
1580 it does end a comment. So scan back in a simple way. */ 1675 from = out_charpos, from_byte = out_bytepos;
1581 {
1582 if (from != stop) DEC_POS (from);
1583 while (1)
1584 {
1585 if ((c = FETCH_CHAR (from),
1586 SYNTAX (c) == Scomment)
1587 && SYNTAX_COMMENT_STYLE (c) == comstyle)
1588 break;
1589 if (from == stop)
1590 {
1591 immediate_quit = 0;
1592 SET_PT (from);
1593 return Qnil;
1594 }
1595 DEC_POS (from);
1596 if (SYNTAX_COMSTART_SECOND (c)
1597 && (c1 = FETCH_CHAR (from),
1598 SYNTAX_COMSTART_FIRST (c1))
1599 && SYNTAX_COMMENT_STYLE (c) == comstyle
1600 && !char_quoted (from))
1601 break;
1602 }
1603 break;
1604 }
1605 #endif /* 0 */
1606 found = back_comment (from, stop, comstyle);
1607 if (found != -1) from = found;
1608 #if 0
1609 /* Look back, counting the parity of string-quotes,
1610 and recording the comment-starters seen.
1611 When we reach a safe place, assume that's not in a string;
1612 then step the main scan to the earliest comment-starter seen
1613 an even number of string quotes away from the safe place.
1614
1615 OFROM[I] is position of the earliest comment-starter seen
1616 which is I+2X quotes from the comment-end.
1617 PARITY is current parity of quotes from the comment end. */
1618 {
1619 int parity = 0;
1620 char my_stringend = 0;
1621 int string_lossage = 0;
1622 int comment_end = from;
1623 int comstart_pos = 0;
1624 int comstart_parity = 0;
1625 int scanstart = from;
1626
1627 DEC_POS (scanstart);
1628 /* At beginning of range to scan, we're outside of strings;
1629 that determines quote parity to the comment-end. */
1630 while (from != stop)
1631 {
1632 /* Move back and examine a character. */
1633 DEC_POS (from);
1634
1635 UPDATE_SYNTAX_TABLE_BACKWARD (from);
1636 c = FETCH_CHAR (from);
1637 code = SYNTAX (c);
1638
1639 /* If this char is the second of a 2-char comment sequence,
1640 back up and give the pair the appropriate syntax. */
1641 temp_pos = from;
1642 DEC_POS (temp_pos);
1643 if (from > stop && SYNTAX_COMEND_SECOND (c)
1644 && (c1 = FETCH_CHAR (temp_pos),
1645 SYNTAX_COMEND_FIRST (c1)))
1646 {
1647 code = Sendcomment;
1648 from = temp_pos;
1649 c = c1;
1650 }
1651
1652 temp_pos = from;
1653 INC_POS (temp_pos);
1654 /* If this char starts a 2-char comment start sequence,
1655 treat it like a 1-char comment starter. */
1656 if (from < scanstart && SYNTAX_COMSTART_FIRST (c)
1657 && (c1 = FETCH_CHAR (temp_pos),
1658 SYNTAX_COMSTART_SECOND (c1))
1659 && comstyle == SYNTAX_COMMENT_STYLE (c1))
1660 code = Scomment;
1661
1662 /* Ignore escaped characters. */
1663 if (char_quoted (from))
1664 continue;
1665
1666 /* Track parity of quotes. */
1667 if (code == Sstring)
1668 {
1669 parity ^= 1;
1670 if (my_stringend == 0)
1671 my_stringend = c;
1672 /* If we have two kinds of string delimiters.
1673 There's no way to grok this scanning backwards. */
1674 else if (my_stringend != c)
1675 string_lossage = 1;
1676 }
1677
1678 /* Record comment-starters according to that
1679 quote-parity to the comment-end. */
1680 if (code == Scomment)
1681 {
1682 comstart_parity = parity;
1683 comstart_pos = from;
1684 }
1685
1686 /* If we find another earlier comment-ender,
1687 any comment-starts earlier than that don't count
1688 (because they go with the earlier comment-ender). */
1689 if (code == Sendcomment
1690 && SYNTAX_COMMENT_STYLE (FETCH_CHAR (from)) == comstyle)
1691 break;
1692
1693 /* Assume a defun-start point is outside of strings. */
1694 if (code == Sopen
1695 && (from == stop || FETCH_BYTE (from - 1) == '\n'))
1696 break;
1697 }
1698
1699 if (comstart_pos == 0)
1700 from = comment_end;
1701 /* If the earliest comment starter
1702 is followed by uniform paired string quotes or none,
1703 we know it can't be inside a string
1704 since if it were then the comment ender would be inside one.
1705 So it does start a comment. Skip back to it. */
1706 else if (comstart_parity == 0 && !string_lossage)
1707 from = comstart_pos;
1708 else
1709 {
1710 /* We had two kinds of string delimiters mixed up
1711 together. Decode this going forwards.
1712 Scan fwd from the previous comment ender
1713 to the one in question; this records where we
1714 last passed a comment starter. */
1715 struct lisp_parse_state state;
1716 scan_sexps_forward (&state, find_defun_start (comment_end),
1717 comment_end - 1, -10000, 0, Qnil, 0);
1718 if (state.incomment)
1719 from = state.comstr_start;
1720 else
1721 /* We can't grok this as a comment; scan it normally. */
1722 from = comment_end;
1723 }
1724 }
1725 #endif /* 0 */
1726 /* We have skipped one comment. */ 1676 /* We have skipped one comment. */
1727 break; 1677 break;
1728 } 1678 }
1729 else if (code != Swhitespace && code != Scomment) 1679 else if (code != Swhitespace && code != Scomment)
1730 { 1680 {
1731 leave: 1681 leave:
1732 immediate_quit = 0; 1682 immediate_quit = 0;
1733 INC_POS (from); 1683 INC_BOTH (from, from_byte);
1734 SET_PT (from); 1684 if (! NILP (current_buffer->enable_multibyte_characters))
1685 SET_PT_BOTH (from, from_byte);
1686 else
1687 SET_PT_BOTH (from_byte, from_byte);
1735 return Qnil; 1688 return Qnil;
1736 } 1689 }
1737 } 1690 }
1738 1691
1739 count1++; 1692 count1++;
1740 } 1693 }
1741 1694
1742 SET_PT (from); 1695 if (! NILP (current_buffer->enable_multibyte_characters))
1696 SET_PT_BOTH (from, from_byte);
1697 else
1698 SET_PT_BOTH (from_byte, from_byte);
1743 immediate_quit = 0; 1699 immediate_quit = 0;
1744 return Qt; 1700 return Qt;
1745 } 1701 }
1746 1702
1747 Lisp_Object 1703 static Lisp_Object
1748 scan_lists (from, count, depth, sexpflag) 1704 scan_lists (from, count, depth, sexpflag)
1749 register int from; 1705 register int from;
1750 int count, depth, sexpflag; 1706 int count, depth, sexpflag;
1751 { 1707 {
1752 Lisp_Object val; 1708 Lisp_Object val;
1759 int min_depth = depth; /* Err out if depth gets less than this. */ 1715 int min_depth = depth; /* Err out if depth gets less than this. */
1760 int comstyle = 0; /* style of comment encountered */ 1716 int comstyle = 0; /* style of comment encountered */
1761 int temp_pos; 1717 int temp_pos;
1762 int last_good = from; 1718 int last_good = from;
1763 int found; 1719 int found;
1720 int from_byte = CHAR_TO_BYTE (from);
1721 int out_bytepos, out_charpos;
1764 1722
1765 if (depth > 0) min_depth = 0; 1723 if (depth > 0) min_depth = 0;
1766 1724
1767 immediate_quit = 1; 1725 immediate_quit = 1;
1768 QUIT; 1726 QUIT;
1771 while (count > 0) 1729 while (count > 0)
1772 { 1730 {
1773 while (from < stop) 1731 while (from < stop)
1774 { 1732 {
1775 UPDATE_SYNTAX_TABLE_FORWARD (from); 1733 UPDATE_SYNTAX_TABLE_FORWARD (from);
1776 c = FETCH_CHAR (from); 1734 c = FETCH_CHAR (from_byte);
1777 code = SYNTAX (c); 1735 code = SYNTAX (c);
1778 if (depth == min_depth) 1736 if (depth == min_depth)
1779 last_good = from; 1737 last_good = from;
1780 INC_POS (from); 1738 INC_BOTH (from, from_byte);
1781 UPDATE_SYNTAX_TABLE_FORWARD (from); 1739 UPDATE_SYNTAX_TABLE_FORWARD (from);
1782 if (from < stop && SYNTAX_COMSTART_FIRST (c) 1740 if (from < stop && SYNTAX_COMSTART_FIRST (c)
1783 && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from)) 1741 && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from_byte))
1784 && parse_sexp_ignore_comments) 1742 && parse_sexp_ignore_comments)
1785 { 1743 {
1786 /* we have encountered a comment start sequence and we 1744 /* we have encountered a comment start sequence and we
1787 are ignoring all text inside comments. We must record 1745 are ignoring all text inside comments. We must record
1788 the comment style this sequence begins so that later, 1746 the comment style this sequence begins so that later,
1789 only a comment end of the same style actually ends 1747 only a comment end of the same style actually ends
1790 the comment section */ 1748 the comment section */
1791 code = Scomment; 1749 code = Scomment;
1792 comstyle = SYNTAX_COMMENT_STYLE (FETCH_CHAR (from)); 1750 comstyle = SYNTAX_COMMENT_STYLE (FETCH_CHAR (from_byte));
1793 INC_POS (from); 1751 INC_BOTH (from, from_byte);
1794 } 1752 }
1795 1753
1796 UPDATE_SYNTAX_TABLE_FORWARD (from); 1754 UPDATE_SYNTAX_TABLE_FORWARD (from);
1797 if (SYNTAX_PREFIX (c)) 1755 if (SYNTAX_PREFIX (c))
1798 continue; 1756 continue;
1800 switch (SWITCH_ENUM_CAST (code)) 1758 switch (SWITCH_ENUM_CAST (code))
1801 { 1759 {
1802 case Sescape: 1760 case Sescape:
1803 case Scharquote: 1761 case Scharquote:
1804 if (from == stop) goto lose; 1762 if (from == stop) goto lose;
1805 INC_POS (from); 1763 INC_BOTH (from, from_byte);
1806 /* treat following character as a word constituent */ 1764 /* treat following character as a word constituent */
1807 case Sword: 1765 case Sword:
1808 case Ssymbol: 1766 case Ssymbol:
1809 if (depth || !sexpflag) break; 1767 if (depth || !sexpflag) break;
1810 /* This word counts as a sexp; return at end of it. */ 1768 /* This word counts as a sexp; return at end of it. */
1811 while (from < stop) 1769 while (from < stop)
1812 { 1770 {
1813 UPDATE_SYNTAX_TABLE_FORWARD (from); 1771 UPDATE_SYNTAX_TABLE_FORWARD (from);
1814 switch (SWITCH_ENUM_CAST (SYNTAX (FETCH_CHAR (from)))) 1772 switch (SWITCH_ENUM_CAST (SYNTAX (FETCH_CHAR (from_byte))))
1815 { 1773 {
1816 case Scharquote: 1774 case Scharquote:
1817 case Sescape: 1775 case Sescape:
1818 INC_POS (from); 1776 INC_BOTH (from, from_byte);
1819 if (from == stop) goto lose; 1777 if (from == stop) goto lose;
1820 break; 1778 break;
1821 case Sword: 1779 case Sword:
1822 case Ssymbol: 1780 case Ssymbol:
1823 case Squote: 1781 case Squote:
1824 break; 1782 break;
1825 default: 1783 default:
1826 goto done; 1784 goto done;
1827 } 1785 }
1828 INC_POS (from); 1786 INC_BOTH (from, from_byte);
1829 } 1787 }
1830 goto done; 1788 goto done;
1831 1789
1832 case Scomment: 1790 case Scomment:
1833 case Scomment_fence: 1791 case Scomment_fence:
1839 if (depth == 0) 1797 if (depth == 0)
1840 goto done; 1798 goto done;
1841 goto lose; 1799 goto lose;
1842 } 1800 }
1843 UPDATE_SYNTAX_TABLE_FORWARD (from); 1801 UPDATE_SYNTAX_TABLE_FORWARD (from);
1844 c = FETCH_CHAR (from); 1802 c = FETCH_CHAR (from_byte);
1845 if (code == Scomment 1803 if (code == Scomment
1846 ? (SYNTAX (c) == Sendcomment 1804 ? (SYNTAX (c) == Sendcomment
1847 && SYNTAX_COMMENT_STYLE (c) == comstyle) 1805 && SYNTAX_COMMENT_STYLE (c) == comstyle)
1848 : (SYNTAX (c) == Scomment_fence)) 1806 : (SYNTAX (c) == Scomment_fence))
1849 /* we have encountered a comment end of the same style 1807 /* we have encountered a comment end of the same style
1850 as the comment sequence which began this comment 1808 as the comment sequence which began this comment
1851 section */ 1809 section */
1852 break; 1810 break;
1853 INC_POS (from); 1811 INC_BOTH (from, from_byte);
1854 if (from < stop && SYNTAX_COMEND_FIRST (c) 1812 if (from < stop && SYNTAX_COMEND_FIRST (c)
1855 && SYNTAX_COMEND_SECOND (FETCH_CHAR (from)) 1813 && SYNTAX_COMEND_SECOND (FETCH_CHAR (from_byte))
1856 && SYNTAX_COMMENT_STYLE (c) == comstyle 1814 && SYNTAX_COMMENT_STYLE (c) == comstyle
1857 && code == Scomment) 1815 && code == Scomment)
1858 /* we have encountered a comment end of the same style 1816 /* we have encountered a comment end of the same style
1859 as the comment sequence which began this comment 1817 as the comment sequence which began this comment
1860 section */ 1818 section */
1861 { INC_POS (from); break; } 1819 {
1820 INC_BOTH (from, from_byte);
1821 break;
1822 }
1862 } 1823 }
1863 break; 1824 break;
1864 1825
1865 case Smath: 1826 case Smath:
1866 if (!sexpflag) 1827 if (!sexpflag)
1867 break; 1828 break;
1868 if (from != stop && c == FETCH_CHAR (from)) 1829 if (from != stop && c == FETCH_CHAR (from_byte))
1869 INC_POS (from); 1830 {
1831 INC_BOTH (from, from_byte);
1832 }
1870 if (mathexit) 1833 if (mathexit)
1871 { 1834 {
1872 mathexit = 0; 1835 mathexit = 0;
1873 goto close1; 1836 goto close1;
1874 } 1837 }
1888 Fcons (make_number (from), Qnil)))); 1851 Fcons (make_number (from), Qnil))));
1889 break; 1852 break;
1890 1853
1891 case Sstring: 1854 case Sstring:
1892 case Sstring_fence: 1855 case Sstring_fence:
1893 temp_pos = from; 1856 temp_pos = from_byte;
1894 DEC_POS (temp_pos); 1857 DEC_POS (temp_pos);
1895 stringterm = FETCH_CHAR (temp_pos); 1858 stringterm = FETCH_CHAR (temp_pos);
1896 while (1) 1859 while (1)
1897 { 1860 {
1898 if (from >= stop) goto lose; 1861 if (from >= stop) goto lose;
1899 UPDATE_SYNTAX_TABLE_FORWARD (from); 1862 UPDATE_SYNTAX_TABLE_FORWARD (from);
1900 if (code == Sstring 1863 if (code == Sstring
1901 ? (FETCH_CHAR (from) == stringterm) 1864 ? (FETCH_CHAR (from_byte) == stringterm)
1902 : SYNTAX (FETCH_CHAR (from)) == Sstring_fence) 1865 : SYNTAX (FETCH_CHAR (from_byte)) == Sstring_fence)
1903 break; 1866 break;
1904 switch (SWITCH_ENUM_CAST (SYNTAX (FETCH_CHAR (from)))) 1867 switch (SWITCH_ENUM_CAST (SYNTAX (FETCH_CHAR (from_byte))))
1905 { 1868 {
1906 case Scharquote: 1869 case Scharquote:
1907 case Sescape: 1870 case Sescape:
1908 INC_POS (from); 1871 INC_BOTH (from, from_byte);
1909 } 1872 }
1910 INC_POS (from); 1873 INC_BOTH (from, from_byte);
1911 } 1874 }
1912 INC_POS (from); 1875 INC_BOTH (from, from_byte);
1913 if (!depth && sexpflag) goto done; 1876 if (!depth && sexpflag) goto done;
1914 break; 1877 break;
1915 } 1878 }
1916 } 1879 }
1917 1880
1928 1891
1929 while (count < 0) 1892 while (count < 0)
1930 { 1893 {
1931 while (from > stop) 1894 while (from > stop)
1932 { 1895 {
1933 DEC_POS (from); 1896 DEC_BOTH (from, from_byte);
1934 UPDATE_SYNTAX_TABLE_BACKWARD (from); 1897 UPDATE_SYNTAX_TABLE_BACKWARD (from);
1935 if (quoted = char_quoted (from)) 1898 if (quoted = char_quoted (from, from_byte))
1936 { 1899 {
1937 DEC_POS (from); 1900 DEC_BOTH (from, from_byte);
1938 UPDATE_SYNTAX_TABLE_BACKWARD (from); 1901 UPDATE_SYNTAX_TABLE_BACKWARD (from);
1939 } 1902 }
1940 c = FETCH_CHAR (from); 1903 c = FETCH_CHAR (from_byte);
1941 code = SYNTAX (c); 1904 code = SYNTAX (c);
1942 if (depth == min_depth) 1905 if (depth == min_depth)
1943 last_good = from; 1906 last_good = from;
1944 comstyle = 0; 1907 comstyle = 0;
1945 if (code == Sendcomment) 1908 if (code == Sendcomment)
1946 comstyle = SYNTAX_COMMENT_STYLE (c); 1909 comstyle = SYNTAX_COMMENT_STYLE (c);
1947 temp_pos = from; 1910 temp_pos = from_byte;
1948 DEC_POS (temp_pos); 1911 DEC_POS (temp_pos);
1949 if (from > stop && SYNTAX_COMEND_SECOND (c) 1912 if (from > stop && SYNTAX_COMEND_SECOND (c)
1950 && (c1 = FETCH_CHAR (temp_pos), SYNTAX_COMEND_FIRST (c1)) 1913 && (c1 = FETCH_CHAR (temp_pos), SYNTAX_COMEND_FIRST (c1))
1951 && !char_quoted (temp_pos) 1914 && !char_quoted (from - 1, temp_pos)
1952 && parse_sexp_ignore_comments) 1915 && parse_sexp_ignore_comments)
1953 { 1916 {
1954 /* we must record the comment style encountered so that 1917 /* we must record the comment style encountered so that
1955 later, we can match only the proper comment begin 1918 later, we can match only the proper comment begin
1956 sequence of the same style */ 1919 sequence of the same style */
1957 code = Sendcomment; 1920 code = Sendcomment;
1958 comstyle = SYNTAX_COMMENT_STYLE (c1); 1921 comstyle = SYNTAX_COMMENT_STYLE (c1);
1959 from = temp_pos; 1922 DEC_BOTH (from, from_byte);
1960 } 1923 }
1961 1924
1962 if (SYNTAX_PREFIX (c)) 1925 if (SYNTAX_PREFIX (c))
1963 continue; 1926 continue;
1964 1927
1969 if (depth || !sexpflag) break; 1932 if (depth || !sexpflag) break;
1970 /* This word counts as a sexp; count object finished 1933 /* This word counts as a sexp; count object finished
1971 after passing it. */ 1934 after passing it. */
1972 while (from > stop) 1935 while (from > stop)
1973 { 1936 {
1974 temp_pos = from; 1937 temp_pos = from_byte;
1975 DEC_POS (temp_pos); 1938 DEC_POS (temp_pos);
1976 UPDATE_SYNTAX_TABLE_BACKWARD (temp_pos); 1939 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
1977 quoted = char_quoted (temp_pos); 1940 quoted = char_quoted (from - 1, temp_pos);
1978 if (quoted) 1941 if (quoted)
1979 { 1942 {
1980 from = temp_pos; 1943 DEC_BOTH (from, from_byte);
1981 DEC_POS (temp_pos); 1944 DEC_POS (temp_pos);
1982 UPDATE_SYNTAX_TABLE_BACKWARD (temp_pos); 1945 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
1983 } 1946 }
1984 c1 = FETCH_CHAR (temp_pos); 1947 c1 = FETCH_CHAR (temp_pos);
1985 temp_code = SYNTAX (c1); 1948 temp_code = SYNTAX (c1);
1986 if (! (quoted || temp_code == Sword 1949 if (! (quoted || temp_code == Sword
1987 || temp_code == Ssymbol 1950 || temp_code == Ssymbol
1988 || temp_code == Squote)) 1951 || temp_code == Squote))
1989 goto done2; 1952 goto done2;
1990 from = temp_pos; 1953 DEC_BOTH (from, from_byte);
1991 } 1954 }
1992 goto done2; 1955 goto done2;
1993 1956
1994 case Smath: 1957 case Smath:
1995 if (!sexpflag) 1958 if (!sexpflag)
1996 break; 1959 break;
1997 temp_pos = from; 1960 temp_pos = from_byte;
1998 DEC_POS (temp_pos); 1961 DEC_POS (temp_pos);
1999 UPDATE_SYNTAX_TABLE_BACKWARD (temp_pos); 1962 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2000 if (from != stop && c == FETCH_CHAR (temp_pos)) 1963 if (from != stop && c == FETCH_CHAR (temp_pos))
2001 from = temp_pos; 1964 DEC_BOTH (from, from_byte);
2002 if (mathexit) 1965 if (mathexit)
2003 { 1966 {
2004 mathexit = 0; 1967 mathexit = 0;
2005 goto open2; 1968 goto open2;
2006 } 1969 }
2021 break; 1984 break;
2022 1985
2023 case Sendcomment: 1986 case Sendcomment:
2024 if (!parse_sexp_ignore_comments) 1987 if (!parse_sexp_ignore_comments)
2025 break; 1988 break;
2026 #if 0 1989 found = back_comment (from, from_byte, stop, comstyle,
2027 if (code != SYNTAX (c)) 1990 &out_charpos, &out_bytepos);
2028 /* For a two-char comment ender, we can assume 1991 if (found != -1)
2029 it does end a comment. So scan back in a simple way. */ 1992 from = out_charpos, from_byte = out_bytepos;
2030 {
2031 if (from != stop) DEC_POS (from);
2032 while (1)
2033 {
2034 if (SYNTAX (c = FETCH_CHAR (from)) == Scomment
2035 && SYNTAX_COMMENT_STYLE (c) == comstyle)
2036 break;
2037 if (from == stop)
2038 {
2039 if (depth == 0)
2040 goto done2;
2041 goto lose;
2042 }
2043 DEC_POS (from);
2044 if (SYNTAX_COMSTART_SECOND (c)
2045 && SYNTAX_COMSTART_FIRST (FETCH_CHAR (from))
2046 && SYNTAX_COMMENT_STYLE (c) == comstyle
2047 && !char_quoted (from))
2048 break;
2049 }
2050 break;
2051 }
2052 #endif /* 0 */
2053 found = back_comment (from, stop, comstyle);
2054 if (found != -1) from = found;
2055 #if 0
2056 /* Look back, counting the parity of string-quotes,
2057 and recording the comment-starters seen.
2058 When we reach a safe place, assume that's not in a string;
2059 then step the main scan to the earliest comment-starter seen
2060 an even number of string quotes away from the safe place.
2061
2062 OFROM[I] is position of the earliest comment-starter seen
2063 which is I+2X quotes from the comment-end.
2064 PARITY is current parity of quotes from the comment end. */
2065 {
2066 int parity = 0;
2067 char my_stringend = 0;
2068 int string_lossage = 0;
2069 int comment_end = from;
2070 int comstart_pos = 0;
2071 int comstart_parity = 0;
2072 int scanstart = from;
2073
2074 DEC_POS (scanstart);
2075
2076 /* At beginning of range to scan, we're outside of strings;
2077 that determines quote parity to the comment-end. */
2078 while (from != stop)
2079 {
2080 /* Move back and examine a character. */
2081 DEC_POS (from);
2082
2083 c = FETCH_CHAR (from);
2084 code = SYNTAX (c);
2085
2086 /* If this char is the second of a 2-char comment sequence,
2087 back up and give the pair the appropriate syntax. */
2088 temp_pos = from;
2089 DEC_POS (temp_pos);
2090 if (from > stop && SYNTAX_COMEND_SECOND (c)
2091 && (c1 = FETCH_CHAR (temp_pos),
2092 SYNTAX_COMEND_FIRST (c1)))
2093 {
2094 code = Sendcomment;
2095 from = temp_pos;
2096 c = c1;
2097 }
2098
2099 /* If this char starts a 2-char comment start sequence,
2100 treat it like a 1-char comment starter. */
2101 temp_pos = from;
2102 INC_POS (temp_pos);
2103 if (from < scanstart && SYNTAX_COMSTART_FIRST (c)
2104 && (c1 = FETCH_CHAR (temp_pos),
2105 SYNTAX_COMSTART_SECOND (c1))
2106 && comstyle == SYNTAX_COMMENT_STYLE (c1))
2107 code = Scomment;
2108
2109 /* Ignore escaped characters. */
2110 if (char_quoted (from))
2111 continue;
2112
2113 /* Track parity of quotes. */
2114 if (code == Sstring)
2115 {
2116 parity ^= 1;
2117 if (my_stringend == 0)
2118 my_stringend = c;
2119 /* If we have two kinds of string delimiters.
2120 There's no way to grok this scanning backwards. */
2121 else if (my_stringend != c)
2122 string_lossage = 1;
2123 }
2124
2125 /* Record comment-starters according to that
2126 quote-parity to the comment-end. */
2127 if (code == Scomment)
2128 {
2129 comstart_parity = parity;
2130 comstart_pos = from;
2131 }
2132
2133 /* If we find another earlier comment-ender,
2134 any comment-starts earlier than that don't count
2135 (because they go with the earlier comment-ender). */
2136 if (code == Sendcomment
2137 && SYNTAX_COMMENT_STYLE (FETCH_CHAR (from)) == comstyle)
2138 break;
2139
2140 /* Assume a defun-start point is outside of strings. */
2141 if (code == Sopen
2142 && (from == stop || FETCH_BYTE (from - 1) == '\n'))
2143 break;
2144 }
2145
2146 if (comstart_pos == 0)
2147 from = comment_end;
2148 /* If the earliest comment starter
2149 is followed by uniform paired string quotes or none,
2150 we know it can't be inside a string
2151 since if it were then the comment ender would be inside one.
2152 So it does start a comment. Skip back to it. */
2153 else if (comstart_parity == 0 && !string_lossage)
2154 from = comstart_pos;
2155 else
2156 {
2157 /* We had two kinds of string delimiters mixed up
2158 together. Decode this going forwards.
2159 Scan fwd from the previous comment ender
2160 to the one in question; this records where we
2161 last passed a comment starter. */
2162 struct lisp_parse_state state;
2163 scan_sexps_forward (&state, find_defun_start (comment_end),
2164 comment_end - 1, -10000, 0, Qnil, 0);
2165 if (state.incomment)
2166 from = state.comstr_start;
2167 else
2168 /* We can't grok this as a comment; scan it normally. */
2169 from = comment_end;
2170 }
2171 }
2172 #endif /* 0 */
2173 break; 1993 break;
2174 1994
2175 case Scomment_fence: 1995 case Scomment_fence:
2176 case Sstring_fence: 1996 case Sstring_fence:
2177 while (1) 1997 while (1)
2178 { 1998 {
2179 DEC_POS (from); 1999 DEC_BOTH (from, from_byte);
2180 if (from == stop) goto lose; 2000 if (from == stop) goto lose;
2181 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2001 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2182 if (!char_quoted (from) 2002 if (!char_quoted (from, from_byte)
2183 && SYNTAX (FETCH_CHAR (from)) == code) 2003 && SYNTAX (FETCH_CHAR (from_byte)) == code)
2184 break; 2004 break;
2185 } 2005 }
2186 if (code == Sstring_fence && !depth && sexpflag) goto done2; 2006 if (code == Sstring_fence && !depth && sexpflag) goto done2;
2187 break; 2007 break;
2188 2008
2189 case Sstring: 2009 case Sstring:
2190 stringterm = FETCH_CHAR (from); 2010 stringterm = FETCH_CHAR (from_byte);
2191 while (1) 2011 while (1)
2192 { 2012 {
2193 if (from == stop) goto lose; 2013 if (from == stop) goto lose;
2194 temp_pos = from; 2014 temp_pos = from_byte;
2195 DEC_POS (temp_pos); 2015 DEC_POS (temp_pos);
2196 UPDATE_SYNTAX_TABLE_BACKWARD (temp_pos); 2016 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2197 if (!char_quoted (temp_pos) 2017 if (!char_quoted (from - 1, temp_pos)
2198 && stringterm == FETCH_CHAR (temp_pos)) 2018 && stringterm == FETCH_CHAR (temp_pos))
2199 break; 2019 break;
2200 from = temp_pos; 2020 DEC_BOTH (from, from_byte);
2201 } 2021 }
2202 DEC_POS (from); 2022 DEC_BOTH (from, from_byte);
2203 if (!depth && sexpflag) goto done2; 2023 if (!depth && sexpflag) goto done2;
2204 break; 2024 break;
2205 } 2025 }
2206 } 2026 }
2207 2027
2278 "Move point backward over any number of chars with prefix syntax.\n\ 2098 "Move point backward over any number of chars with prefix syntax.\n\
2279 This includes chars with \"quote\" or \"prefix\" syntax (' or p).") 2099 This includes chars with \"quote\" or \"prefix\" syntax (' or p).")
2280 () 2100 ()
2281 { 2101 {
2282 int beg = BEGV; 2102 int beg = BEGV;
2103 int opoint = PT;
2104 int opoint_byte = PT_BYTE;
2283 int pos = PT; 2105 int pos = PT;
2106 int pos_byte = PT_BYTE;
2284 int c; 2107 int c;
2285 int temp_pos = pos;
2286 2108
2287 if (pos > beg) 2109 if (pos > beg)
2288 { 2110 {
2289 SETUP_SYNTAX_TABLE (pos, -1); 2111 SETUP_SYNTAX_TABLE (pos, -1);
2290 } 2112 }
2291 DEC_POS (temp_pos); 2113
2292 2114 DEC_BOTH (pos, pos_byte);
2293 while (pos > beg && !char_quoted (temp_pos) 2115
2116 while (pos + 1 > beg && !char_quoted (pos, pos_byte)
2294 /* Previous statement updates syntax table. */ 2117 /* Previous statement updates syntax table. */
2295 && ((c = FETCH_CHAR (temp_pos), SYNTAX (c) == Squote) 2118 && ((c = FETCH_CHAR (pos_byte), SYNTAX (c) == Squote)
2296 || SYNTAX_PREFIX (c))) 2119 || SYNTAX_PREFIX (c)))
2297 { 2120 {
2298 pos = temp_pos; 2121 DEC_BOTH (pos, pos_byte);
2299 DEC_POS (temp_pos); 2122 }
2300 } 2123
2301 2124 SET_PT_BOTH (opoint, opoint_byte);
2302 SET_PT (pos);
2303 2125
2304 return Qnil; 2126 return Qnil;
2305 } 2127 }
2306 2128
2307 /* Parse forward from FROM to END, 2129 /* Parse forward from FROM / FROM_BYTE to END,
2308 assuming that FROM has state OLDSTATE (nil means FROM is start of function), 2130 assuming that FROM has state OLDSTATE (nil means FROM is start of function),
2309 and return a description of the state of the parse at END. 2131 and return a description of the state of the parse at END.
2310 If STOPBEFORE is nonzero, stop at the start of an atom. 2132 If STOPBEFORE is nonzero, stop at the start of an atom.
2311 If COMMENTSTOP is 1, stop at the start of a comment. 2133 If COMMENTSTOP is 1, stop at the start of a comment.
2312 If COMMENTSTOP is -1, stop at the start or end of a comment, 2134 If COMMENTSTOP is -1, stop at the start or end of a comment,
2313 after the beginning of a string, or after the end of a string. */ 2135 after the beginning of a string, or after the end of a string. */
2314 2136
2315 static void 2137 static void
2316 scan_sexps_forward (stateptr, from, end, targetdepth, 2138 scan_sexps_forward (stateptr, from, from_byte, end, targetdepth,
2317 stopbefore, oldstate, commentstop) 2139 stopbefore, oldstate, commentstop)
2318 struct lisp_parse_state *stateptr; 2140 struct lisp_parse_state *stateptr;
2319 register int from; 2141 register int from;
2320 int end, targetdepth, stopbefore; 2142 int end, targetdepth, stopbefore;
2321 Lisp_Object oldstate; 2143 Lisp_Object oldstate;
2334 when the depth becomes negative. */ 2156 when the depth becomes negative. */
2335 int mindepth; /* Lowest DEPTH value seen. */ 2157 int mindepth; /* Lowest DEPTH value seen. */
2336 int start_quoted = 0; /* Nonzero means starting after a char quote */ 2158 int start_quoted = 0; /* Nonzero means starting after a char quote */
2337 Lisp_Object tem; 2159 Lisp_Object tem;
2338 int prev_from; /* Keep one character before FROM. */ 2160 int prev_from; /* Keep one character before FROM. */
2161 int prev_from_byte;
2339 int boundary_stop = commentstop == -1; 2162 int boundary_stop = commentstop == -1;
2340 int nofence; 2163 int nofence;
2341 2164
2342 prev_from = from; 2165 prev_from = from;
2343 DEC_POS (prev_from); 2166 prev_from_byte = from_byte;
2167 if (from != BEGV)
2168 DEC_BOTH (prev_from, prev_from_byte);
2344 2169
2345 /* Use this macro instead of `from++'. */ 2170 /* Use this macro instead of `from++'. */
2346 #define INC_FROM do { prev_from = from; INC_POS (from); } while (0) 2171 #define INC_FROM \
2172 do { prev_from = from; \
2173 prev_from_byte = from_byte; \
2174 from++; \
2175 INC_POS (from_byte); \
2176 } while (0)
2347 2177
2348 immediate_quit = 1; 2178 immediate_quit = 1;
2349 QUIT; 2179 QUIT;
2350 2180
2351 SETUP_SYNTAX_TABLE (from, 1); 2181 SETUP_SYNTAX_TABLE (from, 1);
2413 if (start_quoted) goto startquoted; 2243 if (start_quoted) goto startquoted;
2414 2244
2415 while (from < end) 2245 while (from < end)
2416 { 2246 {
2417 UPDATE_SYNTAX_TABLE_FORWARD (from); 2247 UPDATE_SYNTAX_TABLE_FORWARD (from);
2418 code = SYNTAX (FETCH_CHAR (from)); 2248 code = SYNTAX (FETCH_CHAR (from_byte));
2419 INC_FROM; 2249 INC_FROM;
2420 2250
2421 if (code == Scomment) 2251 if (code == Scomment)
2422 state.comstr_start = prev_from; 2252 state.comstr_start = prev_from;
2423 else if (code == Scomment_fence) 2253 else if (code == Scomment_fence)
2425 /* Record the comment style we have entered so that only 2255 /* Record the comment style we have entered so that only
2426 the comment-end sequence of the same style actually 2256 the comment-end sequence of the same style actually
2427 terminates the comment section. */ 2257 terminates the comment section. */
2428 state.comstyle = ( code == Scomment_fence 2258 state.comstyle = ( code == Scomment_fence
2429 ? ST_COMMENT_STYLE 2259 ? ST_COMMENT_STYLE
2430 : SYNTAX_COMMENT_STYLE (FETCH_CHAR (from))); 2260 : SYNTAX_COMMENT_STYLE (FETCH_CHAR (from_byte)));
2431 state.comstr_start = prev_from; 2261 state.comstr_start = prev_from;
2432 if (code != Scomment_fence) INC_FROM; 2262 if (code != Scomment_fence) INC_FROM;
2433 code = Scomment; 2263 code = Scomment;
2434 } 2264 }
2435 else if (from < end) 2265 else if (from < end)
2436 if (SYNTAX_COMSTART_FIRST (FETCH_CHAR (prev_from))) 2266 if (SYNTAX_COMSTART_FIRST (FETCH_CHAR (prev_from_byte)))
2437 if (SYNTAX_COMSTART_SECOND (FETCH_CHAR (from))) 2267 if (SYNTAX_COMSTART_SECOND (FETCH_CHAR (from_byte)))
2438 /* Duplicate code to avoid a very complex if-expression 2268 /* Duplicate code to avoid a very complex if-expression
2439 which causes trouble for the SGI compiler. */ 2269 which causes trouble for the SGI compiler. */
2440 { 2270 {
2441 /* Record the comment style we have entered so that only 2271 /* Record the comment style we have entered so that only
2442 the comment-end sequence of the same style actually 2272 the comment-end sequence of the same style actually
2443 terminates the comment section. */ 2273 terminates the comment section. */
2444 state.comstyle = ( code == Scomment_fence 2274 state.comstyle = ( code == Scomment_fence
2445 ? ST_COMMENT_STYLE 2275 ? ST_COMMENT_STYLE
2446 : SYNTAX_COMMENT_STYLE (FETCH_CHAR (from))); 2276 : SYNTAX_COMMENT_STYLE (FETCH_CHAR (from_byte)));
2447 state.comstr_start = prev_from; 2277 state.comstr_start = prev_from;
2448 if (code != Scomment_fence) INC_FROM; 2278 if (code != Scomment_fence) INC_FROM;
2449 code = Scomment; 2279 code = Scomment;
2450 } 2280 }
2451 2281
2452 if (SYNTAX_PREFIX (FETCH_CHAR (prev_from))) 2282 if (SYNTAX_PREFIX (FETCH_CHAR (prev_from_byte)))
2453 continue; 2283 continue;
2454 switch (SWITCH_ENUM_CAST (code)) 2284 switch (SWITCH_ENUM_CAST (code))
2455 { 2285 {
2456 case Sescape: 2286 case Sescape:
2457 case Scharquote: 2287 case Scharquote:
2468 curlevel->last = prev_from; 2298 curlevel->last = prev_from;
2469 symstarted: 2299 symstarted:
2470 while (from < end) 2300 while (from < end)
2471 { 2301 {
2472 UPDATE_SYNTAX_TABLE_FORWARD (from); 2302 UPDATE_SYNTAX_TABLE_FORWARD (from);
2473 switch (SWITCH_ENUM_CAST (SYNTAX (FETCH_CHAR (from)))) 2303 switch (SWITCH_ENUM_CAST (SYNTAX (FETCH_CHAR (from_byte))))
2474 { 2304 {
2475 case Scharquote: 2305 case Scharquote:
2476 case Sescape: 2306 case Sescape:
2477 INC_FROM; 2307 INC_FROM;
2478 if (from == end) goto endquoted; 2308 if (from == end) goto endquoted;
2495 goto done; 2325 goto done;
2496 if (from != BEGV) 2326 if (from != BEGV)
2497 { 2327 {
2498 /* Enter the loop in the middle so that we find 2328 /* Enter the loop in the middle so that we find
2499 a 2-char comment ender if we start in the middle of it. */ 2329 a 2-char comment ender if we start in the middle of it. */
2500 prev = FETCH_CHAR (prev_from); 2330 prev = FETCH_CHAR (prev_from_byte);
2501 goto startincomment_1; 2331 goto startincomment_1;
2502 } 2332 }
2503 /* At beginning of buffer, enter the loop the ordinary way. */ 2333 /* At beginning of buffer, enter the loop the ordinary way. */
2504 state.incomment = 1; 2334 state.incomment = 1;
2505 goto commentloop; 2335 goto commentloop;
2510 commentloop: 2340 commentloop:
2511 while (1) 2341 while (1)
2512 { 2342 {
2513 if (from == end) goto done; 2343 if (from == end) goto done;
2514 UPDATE_SYNTAX_TABLE_FORWARD (from); 2344 UPDATE_SYNTAX_TABLE_FORWARD (from);
2515 prev = FETCH_CHAR (from); 2345 prev = FETCH_CHAR (from_byte);
2516 if (SYNTAX (prev) == Sendcomment 2346 if (SYNTAX (prev) == Sendcomment
2517 && SYNTAX_COMMENT_STYLE (prev) == state.comstyle) 2347 && SYNTAX_COMMENT_STYLE (prev) == state.comstyle)
2518 /* Only terminate the comment section if the endcomment 2348 /* Only terminate the comment section if the endcomment
2519 of the same style as the start sequence has been 2349 of the same style as the start sequence has been
2520 encountered. */ 2350 encountered. */
2523 && SYNTAX (prev) == Scomment_fence) 2353 && SYNTAX (prev) == Scomment_fence)
2524 break; 2354 break;
2525 INC_FROM; 2355 INC_FROM;
2526 startincomment_1: 2356 startincomment_1:
2527 if (from < end && SYNTAX_COMEND_FIRST (prev) 2357 if (from < end && SYNTAX_COMEND_FIRST (prev)
2528 && SYNTAX_COMEND_SECOND (FETCH_CHAR (from)) 2358 && SYNTAX_COMEND_SECOND (FETCH_CHAR (from_byte))
2529 && SYNTAX_COMMENT_STYLE (prev) == state.comstyle) 2359 && SYNTAX_COMMENT_STYLE (prev) == state.comstyle)
2530 /* Only terminate the comment section if the end-comment 2360 /* Only terminate the comment section if the end-comment
2531 sequence of the same style as the start sequence has 2361 sequence of the same style as the start sequence has
2532 been encountered. */ 2362 been encountered. */
2533 { break; } 2363 break;
2534 } 2364 }
2535 INC_FROM; 2365 INC_FROM;
2536 state.incomment = 0; 2366 state.incomment = 0;
2537 state.comstyle = 0; /* reset the comment style */ 2367 state.comstyle = 0; /* reset the comment style */
2538 if (boundary_stop) goto done; 2368 if (boundary_stop) goto done;
2564 case Sstring_fence: 2394 case Sstring_fence:
2565 state.comstr_start = from - 1; 2395 state.comstr_start = from - 1;
2566 if (stopbefore) goto stop; /* this arg means stop at sexp start */ 2396 if (stopbefore) goto stop; /* this arg means stop at sexp start */
2567 curlevel->last = prev_from; 2397 curlevel->last = prev_from;
2568 state.instring = (code == Sstring 2398 state.instring = (code == Sstring
2569 ? (FETCH_CHAR (prev_from)) 2399 ? (FETCH_CHAR (prev_from_byte))
2570 : ST_STRING_STYLE); 2400 : ST_STRING_STYLE);
2571 if (boundary_stop) goto done; 2401 if (boundary_stop) goto done;
2572 startinstring: 2402 startinstring:
2573 { 2403 {
2574 nofence = state.instring != ST_STRING_STYLE; 2404 nofence = state.instring != ST_STRING_STYLE;
2576 while (1) 2406 while (1)
2577 { 2407 {
2578 int c; 2408 int c;
2579 2409
2580 if (from >= end) goto done; 2410 if (from >= end) goto done;
2581 c = FETCH_CHAR (from); 2411 c = FETCH_CHAR (from_byte);
2582 if (nofence && c == state.instring) break; 2412 if (nofence && c == state.instring) break;
2583 UPDATE_SYNTAX_TABLE_FORWARD (from); 2413 UPDATE_SYNTAX_TABLE_FORWARD (from);
2584 switch (SWITCH_ENUM_CAST (SYNTAX (c))) 2414 switch (SWITCH_ENUM_CAST (SYNTAX (c)))
2585 { 2415 {
2586 case Sstring_fence: 2416 case Sstring_fence:
2677 } 2507 }
2678 else 2508 else
2679 target = -100000; /* We won't reach this depth */ 2509 target = -100000; /* We won't reach this depth */
2680 2510
2681 validate_region (&from, &to); 2511 validate_region (&from, &to);
2682 scan_sexps_forward (&state, XINT (from), XINT (to), 2512 scan_sexps_forward (&state, XINT (from), CHAR_TO_BYTE (XINT (from)),
2513 XINT (to),
2683 target, !NILP (stopbefore), oldstate, 2514 target, !NILP (stopbefore), oldstate,
2684 (NILP (commentstop) 2515 (NILP (commentstop)
2685 ? 0 : (EQ (commentstop, Qsyntax_table) ? -1 : 1))); 2516 ? 0 : (EQ (commentstop, Qsyntax_table) ? -1 : 1)));
2686 2517
2687 SET_PT (state.location); 2518 SET_PT (state.location);