PARITY is current parity of quotes from the comment end. */
int string_style = -1; /* Presumed outside of any string. */
int string_lossage = 0;
+ /* Not a real lossage: indicates that we have passed a matching comment
+ starter plus an non-matching comment-ender, meaning that any matching
+ comment-starter we might see later could be a false positive (hidden
+ inside another comment).
+ Test case: { a (* b } c (* d *) */
+ int comment_lossage = 0;
int comment_end = from;
int comment_end_byte = from_byte;
int comstart_pos = 0;
int comstart_byte;
- /* Value that PARITY had, when we reached the position
- in COMSTART_POS. */
int scanstart = from - 1;
/* Place where the containing defun starts,
or 0 if we didn't come across it yet. */
case Scomment:
/* We've already checked that it is the relevant comstyle. */
- if (string_style != -1 || string_lossage)
+ if (string_style != -1 || comment_lossage || string_lossage)
/* There are odd string quotes involved, so let's be careful.
Test case in Pascal: " { " a { " } */
goto lossage;
- if (comnested && --nesting <= 0)
+ if (!comnested)
+ {
+ /* Record best comment-starter so far. */
+ comstart_pos = from;
+ comstart_byte = from_byte;
+ }
+ else if (--nesting <= 0)
/* nested comments have to be balanced, so we don't need to
keep looking for earlier ones. We use here the same (slightly
incorrect) reasoning as below: since it is followed by uniform
paired string quotes, this comment-start has to be outside of
strings, else the comment-end itself would be inside a string. */
goto done;
-
- /* Record comment-starters according to that
- quote-parity to the comment-end. */
- comstart_pos = from;
- comstart_byte = from_byte;
break;
case Sendcomment:
this comment-ender rather than ours. */
from = stop; /* Break out of the loop. */
}
+ else if (comstart_pos != 0 || c != '\n')
+ /* We're mixing comment styles here, so we'd better be careful.
+ The (comstart_pos != 0 || c != '\n') check is not quite correct
+ (we should just always set comment_lossage), but removing it
+ would imply that any multiline comment in C would go through
+ lossage, which seems overkill.
+ The failure should only happen in the rare cases such as
+ { (* } *) */
+ comment_lossage = 1;
break;
case Sopen:
break;
default:
- continue;
+ break;
}
}
from_byte = comment_end_byte;
UPDATE_SYNTAX_TABLE_FORWARD (comment_end - 1);
}
- /* If the earliest comment starter
- is followed by uniform paired string quotes or none,
- we know it can't be inside a string
- since if it were then the comment ender would be inside one.
- So it does start a comment. Skip back to it. */
- else if (!comnested)
+ /* If comstart_pos is set and we get here (ie. didn't jump to `lossage'
+ or `done'), then we've found the beginning of the non-nested comment. */
+ else if (1) /* !comnested */
{
from = comstart_pos;
from_byte = comstart_byte;
if (nbytes != size_byte)
{
str = (unsigned char *) alloca (nbytes);
- copy_text (XSTRING (string)->data, str, nbytes,
+ copy_text (XSTRING (string)->data, str, size_byte,
string_multibyte, multibyte);
size_byte = nbytes;
}
if (SINGLE_BYTE_CHAR_P (c))
{
if (! SINGLE_BYTE_CHAR_P (c2))
- error ("Invalid character range: %s",
- XSTRING (string)->data);
+ {
+ /* Handle a range such as \177-\377 in multibyte
+ mode. Split that into two ranges, the low
+ one ending at 0237, and the high one starting
+ at the smallest character in the charset of
+ C2 and ending at C2. */
+ int charset = CHAR_CHARSET (c2);
+ int c1 = MAKE_CHAR (charset, 0, 0);
+
+ fastmap[c2_leading_code] = 1;
+ char_ranges[n_char_ranges++] = c1;
+ char_ranges[n_char_ranges++] = c2;
+ c2 = 0237;
+ }
while (c <= c2)
{
fastmap[c] = 1;
c++;
}
}
- else
+ else if (! SINGLE_BYTE_CHAR_P (c2))
{
if (c_leading_code != c2_leading_code)
error ("Invalid character range: %s",
XSTRING (string)->data);
- fastmap[c_leading_code] = 1;
if (c <= c2)
{
+ fastmap[c_leading_code] = 1;
char_ranges[n_char_ranges++] = c;
char_ranges[n_char_ranges++] = c2;
}
}
else
{
- fastmap[c_leading_code] = 1;
- if (!SINGLE_BYTE_CHAR_P (c))
+ if (SINGLE_BYTE_CHAR_P (c))
+ fastmap[c] = 1;
+ else
{
+ fastmap[c_leading_code] = 1;
char_ranges[n_char_ranges++] = c;
char_ranges[n_char_ranges++] = c;
}
if (multibyte)
while (pos < XINT (lim) && fastmap[(c = FETCH_BYTE (pos_byte))])
{
- if (!BASE_LEADING_CODE_P (c))
- INC_BOTH (pos, pos_byte);
- else if (n_char_ranges)
+ /* If we are looking at a multibyte character, we
+ must look up the character in the table
+ CHAR_RANGES. If there's no data in the table,
+ that character is not what we want to skip. */
+ if (BASE_LEADING_CODE_P (c)
+ && (c = FETCH_MULTIBYTE_CHAR (pos_byte),
+ ! SINGLE_BYTE_CHAR_P (c)))
{
- /* We much check CHAR_RANGES for a multibyte
- character. */
- ch = FETCH_MULTIBYTE_CHAR (pos_byte);
+ /* The following code do the right thing even if
+ n_char_ranges is zero (i.e. no data in
+ CHAR_RANGES). */
for (i = 0; i < n_char_ranges; i += 2)
- if ((ch >= char_ranges[i] && ch <= char_ranges[i + 1]))
+ if (c >= char_ranges[i] && c <= char_ranges[i + 1])
break;
if (!(negate ^ (i < n_char_ranges)))
break;
-
- INC_BOTH (pos, pos_byte);
- }
- else
- {
- if (!negate) break;
- INC_BOTH (pos, pos_byte);
}
+ INC_BOTH (pos, pos_byte);
}
else
while (pos < XINT (lim) && fastmap[FETCH_BYTE (pos)])
if (multibyte)
while (pos > XINT (lim))
{
- int savepos = pos_byte;
- DEC_BOTH (pos, pos_byte);
- if (fastmap[(c = FETCH_BYTE (pos_byte))])
- {
- if (!BASE_LEADING_CODE_P (c))
- ;
- else if (n_char_ranges)
- {
- /* We much check CHAR_RANGES for a multibyte
- character. */
- ch = FETCH_MULTIBYTE_CHAR (pos_byte);
- for (i = 0; i < n_char_ranges; i += 2)
- if (ch >= char_ranges[i] && ch <= char_ranges[i + 1])
- break;
- if (!(negate ^ (i < n_char_ranges)))
- {
- pos++;
- pos_byte = savepos;
- break;
- }
- }
- else
- if (!negate)
- {
- pos++;
- pos_byte = savepos;
- break;
- }
- }
- else
+ int prev_pos_byte = pos_byte;
+
+ DEC_POS (prev_pos_byte);
+ if (!fastmap[(c = FETCH_BYTE (prev_pos_byte))])
+ break;
+
+ /* See the comment in the previous similar code. */
+ if (BASE_LEADING_CODE_P (c)
+ && (c = FETCH_MULTIBYTE_CHAR (prev_pos_byte),
+ ! SINGLE_BYTE_CHAR_P (c)))
{
- pos++;
- pos_byte = savepos;
- break;
+ for (i = 0; i < n_char_ranges; i += 2)
+ if (c >= char_ranges[i] && c <= char_ranges[i + 1])
+ break;
+ if (!(negate ^ (i < n_char_ranges)))
+ break;
}
+ pos--;
+ pos_byte = prev_pos_byte;
}
else
while (pos > XINT (lim) && fastmap[FETCH_BYTE (pos - 1)])