Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site spar.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!decvax!decwrl!spar!michael From: michael@spar.UUCP (michael) Newsgroups: net.emacs Subject: Re: Fix to backward paren bug wanted. Message-ID: <26@spar.UUCP> Date: Fri, 11-Jan-85 10:03:59 EST Article-I.D.: spar.26 Posted: Fri Jan 11 10:03:59 1985 Date-Received: Sun, 13-Jan-85 09:18:58 EST References: <2122@uw-june> Reply-To: ellis@spar.UUCP Organization: Schlumberger Palo Alto Research, CA Lines: 444 In response to Brian Matthew's request, I have enclosed the output from `diff -c' -- syntax.c is the source file to be updated. I can no longer remember who originally provided this fix, but whoever it was has been a frequent contributor to this group. Somewhere in here (I think..) is an additional fix I made that you'll really want if you run Gosmacs on SUNs. SUN's C compiler has problems with register variables (doesn't everybody's?) that show up here.. Oh yes, many thanks to the originator of this fix! diff -c Oldsyntax.c syntax.c *** Original Unipress EMACS syntax.c --- With paren match correction *************** *** 116,126 /* Primitive function for paren matching. Leaves dot at enclosing left paren, or at top of buffer if none. Stops at a zero-level newline if ! StopAtNewline is set. Returns (to MLisp) 1 if it finds ! a match, 0 if not */ ! /* Bugs: doesn't correctly handle comments (it'll never really handle them ! correctly... */ ! static ParenScan (StopAtNewline, forward) { register ParenLevel = 0; --- 116,125 ----- /* Primitive function for paren matching. Leaves dot at enclosing left paren, or at top of buffer if none. Stops at a zero-level newline if ! StopAtNewline is set. Returns (to MLisp) 1 if it finds a match, ! 0 if not. */ ! /* Bug: if the stop-comment auxil character is also a quote, paren, or ! prefix quote, reverse scans will sometimes be wrong. */ static ParenScan (StopAtNewline, forward) { register struct SyntaxTable *s = bf_mode.md_syntax; *************** *** 122,134 correctly... */ static ! ParenScan (StopAtNewline, forward) { ! register ParenLevel = 0; ! register char c, ! pc; ! char parenstack[200]; ! int InString = 0; ! char MatchingQuote = 0; register struct SyntaxTable *s = bf_mode.md_syntax; register enum SyntaxKinds k; register on_on = 1; --- 121,127 ----- /* Bug: if the stop-comment auxil character is also a quote, paren, or prefix quote, reverse scans will sometimes be wrong. */ static ! ParenScan (StopAtNewline, forward) { register struct SyntaxTable *s = bf_mode.md_syntax; register enum SyntaxKinds k; register c, *************** *** 131,139 char MatchingQuote = 0; register struct SyntaxTable *s = bf_mode.md_syntax; register enum SyntaxKinds k; ! register on_on = 1; ! int start = (forward ? (dot + 1) : dot); ! int SavedDot = dot; parenstack[0] = 0; MLvalue -> exp_type = IsInteger; --- 124,138 ----- ParenScan (StopAtNewline, forward) { register struct SyntaxTable *s = bf_mode.md_syntax; register enum SyntaxKinds k; ! register c, ! pc, ! on_on = 1, ! ParenLevel = 0; ! char parenstack[200]; ! int InString = 0, ! InComment = 0, ! MatchingQuote, ! delta = 1; MLvalue -> exp_type = IsInteger; MLvalue -> exp_int = 0; *************** *** 135,141 int start = (forward ? (dot + 1) : dot); int SavedDot = dot; - parenstack[0] = 0; MLvalue -> exp_type = IsInteger; MLvalue -> exp_int = 0; if (StopAtNewline) { --- 134,139 ----- MatchingQuote, delta = 1; MLvalue -> exp_type = IsInteger; MLvalue -> exp_int = 0; if (forward != 0 && forward != 1) { *************** *** 138,153 parenstack[0] = 0; MLvalue -> exp_type = IsInteger; MLvalue -> exp_int = 0; ! if (StopAtNewline) { ! register p1, ! p2, ! dp; ! for (p1 = dot - 1, p2 = (forward ? NumCharacters : FirstCharacter), ! dp = (forward ? 1 : -1); ! (forward ? p1 < p2 : p1 > p2) ! && ((c = CharAt (p1)) == ' ' || c == '\t' || c == '\n'); ! p1 += dp); ! SetDot (p1 + 1); } while (on_on && !err) { if (forward) { --- 136,144 ----- MLvalue -> exp_type = IsInteger; MLvalue -> exp_int = 0; ! if (forward != 0 && forward != 1) { ! error ("panic: ParenScan"); ! return 0; } if (StopAtNewline) { /* Skip over whitespace */ pc = dot - 1; *************** *** 149,154 p1 += dp); SetDot (p1 + 1); } while (on_on && !err) { if (forward) { if (dot > NumCharacters) { --- 140,162 ----- error ("panic: ParenScan"); return 0; } + if (StopAtNewline) { /* Skip over whitespace */ + pc = dot - 1; + if (forward) + while (pc < NumCharacters) { + if ((c = CharAt (pc)) != ' ' && c != '\t' && c != '\n') + break; + pc++; + } + else + while (pc > FirstCharacter) { + if ((c = CharAt (pc)) != ' ' && c != '\t' && c != '\n') + break; + pc--; + } + SetDot (pc + 1); + } + /* Scan through buffer until done or error */ while (on_on && !err) { if (forward) { if (dot > NumCharacters) *************** *** 151,159 } while (on_on && !err) { if (forward) { ! if (dot > NumCharacters) { ! error ("No matching close parenthesis."); ! SetDot (SavedDot); return 0; } DotRight (1); --- 159,165 ----- /* Scan through buffer until done or error */ while (on_on && !err) { if (forward) { ! if (dot > NumCharacters) return 0; DotRight (delta); delta = 1; *************** *** 155,162 error ("No matching close parenthesis."); SetDot (SavedDot); return 0; ! } ! DotRight (1); } if (dot > 2) pc = CharAt (dot - 2); --- 161,168 ----- if (forward) { if (dot > NumCharacters) return 0; ! DotRight (delta); ! delta = 1; } else if (dot <= FirstCharacter) *************** *** 158,170 } DotRight (1); } ! if (dot > 2) ! pc = CharAt (dot - 2); ! else { ! pc = 0; ! if (dot <= FirstCharacter) { ! error ("No matching open parenthesis."); ! SetDot (SavedDot); return 0; } } --- 164,171 ----- DotRight (delta); delta = 1; } ! else ! if (dot <= FirstCharacter) return 0; c = CharAt (dot - 1); /* If in a comment, see if we are now out. If not in a comment, see *************** *** 166,171 error ("No matching open parenthesis."); SetDot (SavedDot); return 0; } } k = bf_mode.md_syntax -> s_table[c = CharAt (dot - 1)].s_kind; --- 167,185 ----- else if (dot <= FirstCharacter) return 0; + c = CharAt (dot - 1); + /* If in a comment, see if we are now out. If not in a comment, see + if we are now in. The comparisons to forward account for the fact + that reverse scans start comments on seeing the end-comment character, + and end comments on seeing the start-comment character. */ + /* The bug is in here: we should look at (dot-2) for two-character + end-comment strings when doing reverse scans, not at (dot-1). I + don't think it's worth the effort. */ + if (InComment != forward && s -> s_table[c].BeginComment || + InComment == forward && s -> s_table[c].EndComment) { + if ((pc = s -> s_table[c].CommentAux) == 0) { + InComment = !InComment; + goto advance; } if (dot <= NumCharacters && pc == CharAt (dot)) { if (forward) *************** *** 167,172 SetDot (SavedDot); return 0; } } k = bf_mode.md_syntax -> s_table[c = CharAt (dot - 1)].s_kind; if (bf_mode.md_syntax -> s_table[pc].s_kind == PrefixQuote) --- 181,192 ----- InComment = !InComment; goto advance; } + if (dot <= NumCharacters && pc == CharAt (dot)) { + if (forward) + delta++; + InComment = !InComment; + goto advance; + } } /* If in a comment, just continue on */ if (InComment) *************** *** 168,179 return 0; } } ! k = bf_mode.md_syntax -> s_table[c = CharAt (dot - 1)].s_kind; ! if (bf_mode.md_syntax -> s_table[pc].s_kind == PrefixQuote) ! k = WordChar; ! if ((!InString || c == MatchingQuote) && k == PairedQuote) { ! InString = !InString; ! MatchingQuote = c; } if (InString && c == '\n') return 0; --- 188,209 ----- goto advance; } } ! /* If in a comment, just continue on */ ! if (InComment) ! goto advance; ! /* See what kind of character we have. Carefully check for quoted ! quotes (and even for quoted quoters but no further; this takes ! care of things like "'\''" and "'\\'"). */ ! k = s -> s_table[c].s_kind; ! if (dot > 2 && s -> s_table[CharAt (dot-2)].s_kind == PrefixQuote && ! (dot==3 || s -> s_table[CharAt (dot-3)].s_kind != PrefixQuote)) ! k = WordChar; ! if (k == PairedQuote) { ! if (!InString) /* start quotes */ ! InString++, MatchingQuote = c; ! else /* end quotes (if it's the same quote) */ ! if (c == MatchingQuote) ! InString = 0; } if (c == '\n' && ParenLevel == 0 && StopAtNewline) return 0; *************** *** 175,181 InString = !InString; MatchingQuote = c; } ! if (InString && c == '\n') return 0; if (StopAtNewline && c == '\n' && ParenLevel == 0) return 0; --- 205,211 ----- if (c == MatchingQuote) InString = 0; } ! if (c == '\n' && ParenLevel == 0 && StopAtNewline) return 0; if (!InString && (k == EndParen || k == BeginParen)) { if (forward == (k == BeginParen))/* Push a paren */ *************** *** 177,184 } if (InString && c == '\n') return 0; - if (StopAtNewline && c == '\n' && ParenLevel == 0) - return 0; if (!InString && (k == EndParen || k == BeginParen)) { if ((forward == 0) == (k == EndParen)) { ParenLevel++; --- 207,212 ----- } if (c == '\n' && ParenLevel == 0 && StopAtNewline) return 0; if (!InString && (k == EndParen || k == BeginParen)) { if (forward == (k == BeginParen))/* Push a paren */ parenstack[ParenLevel++] = s -> s_table[c].MatchingParen; *************** *** 180,188 if (StopAtNewline && c == '\n' && ParenLevel == 0) return 0; if (!InString && (k == EndParen || k == BeginParen)) { ! if ((forward == 0) == (k == EndParen)) { ! ParenLevel++; ! parenstack[ParenLevel] = s -> s_table[c].MatchingParen; } else { if (ParenLevel > 0 && parenstack[ParenLevel] != c) --- 208,224 ----- if (c == '\n' && ParenLevel == 0 && StopAtNewline) return 0; if (!InString && (k == EndParen || k == BeginParen)) { ! if (forward == (k == BeginParen))/* Push a paren */ ! parenstack[ParenLevel++] = s -> s_table[c].MatchingParen; ! else { /* Pop a paren */ ! if (ParenLevel == 0) ! on_on = 0; /* Should maybe be error? */ ! else { ! if (parenstack[--ParenLevel] != c) ! error ("Parenthesis mismatch."); ! if (ParenLevel == 0 && !StopAtNewline) ! on_on = 0; ! } } } advance: *************** *** 184,200 ParenLevel++; parenstack[ParenLevel] = s -> s_table[c].MatchingParen; } - else { - if (ParenLevel > 0 && parenstack[ParenLevel] != c) - error ("Parenthesis mismatch."); - ParenLevel--; - } - /* if (pc == '\n' && ParenLevel > 0 && dot != start) { - error ("Parenthesis context across function boundary"); - return 0; - } */ - if (ParenLevel < 0 || (ParenLevel == 0 && !StopAtNewline)) - on_on = 0; } if (!forward) DotLeft (1); --- 220,225 ----- on_on = 0; } } } advance: if (!forward) { *************** *** 196,203 if (ParenLevel < 0 || (ParenLevel == 0 && !StopAtNewline)) on_on = 0; } ! if (!forward) ! DotLeft (1); } MLvalue -> exp_int = 1; return 0; --- 221,231 ----- } } } ! advance: ! if (!forward) { ! DotLeft (delta); ! delta = 1; ! } } MLvalue -> exp_int = 1; return 0; =======END OF DIFF======= -michael