Reply-To: mule-jp@etl.go.jp
Sender: handa@etl.go.jp
X-Seqno: 2524
Return-Path: <enami@sys.ptg.sony.co.jp>
From: enami@sys.ptg.sony.co.jp
To: mule-jp@etl.go.jp
Subject: c++-mode/syntax patch for mule
Date: Thu, 24 Jun 93 08:39:05 +0900

	Barry A. Warsaw $B$5$s$N(B c++-mode.el $B$O(B gnu.emacs.sources $B$K$b2?(B
	$BEY$+(B post $B$5$l$F$$$k$N$G;H$C$F$k?M$bB?$$$H;W$$$^$9(B($B$[$s$H$+$J(B?). 
	$B$=$N(B c++-mode.el $B$K$O(B syntax.[ch] $B$K$"$F$k@lMQ$N(B patch $B$,$"$C(B
	$B$F(B, $B$=$l$r$r$"$F$k$H$h$j$&$^$/F0:n$7$^$9(B.  $B$=$N(B patch $B$N(B mule 
	$BHG$r$*FO$1$7$^$9(B:).

	$B0l1~(B base $B$K$7$?(B original $B$N(B patch $B$b4^$s$G$$$^$9(B.  contrib $B$K(B
	$B$G$b$*$$$H$$$F$/$@$5$$(B.

	$B$\$/$O(B M-f/M-b $B$G(B block $B$H$P$7$F0\F0$9$k$N$G(B, $B$3$N%Q%C%A$J$7$N(B 
	c++-mode $B$@$H$D$i$$$s$G$9(B:).

# $B$`$j$d$j$"$F$?$@$1$J$N$G(B, $B$*$+$7$JItJ,$b$"$k$+$b$7$l$J$$!D(B
$B$($J$_(B $B$D$0$H$b(B / $B%=%K!<(B

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  syntax.18.59.GNU syntax.MULE-0.9.8
# Wrapped by enami@chihaya on Thu Jun 24 08:25:54 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'syntax.18.59.GNU' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'syntax.18.59.GNU'\"
else
echo shar: Extracting \"'syntax.18.59.GNU'\" \(62612 characters\)
sed "s/^X//" >'syntax.18.59.GNU' <<'END_OF_FILE'
XIt is possible that these patches will fail for some VMS or 8-bit
Xpatched Emacsen.  Symptoms are that ctrl_arrow will not be a legal
Xfield in the buffer struct.
X
XSorry, there's no workaround for that at the moment.
X-------------------- snip snip --------------------
X*** syntax.c@@/18.59	Sat Sep 12 01:07:25 1992
X--- syntax.c	Fri May 21 17:37:19 1993
X***************
X*** 1,11 ****
X  /* GNU Emacs routines to deal with syntax tables; also word and list parsing.
X!    Copyright (C) 1985, 1987, 1990 Free Software Foundation, Inc.
X  
X  This file is part of GNU Emacs.
X  
X  GNU Emacs is free software; you can redistribute it and/or modify
X  it under the terms of the GNU General Public License as published by
X! the Free Software Foundation; either version 1, or (at your option)
X  any later version.
X  
X  GNU Emacs is distributed in the hope that it will be useful,
X--- 1,11 ----
X  /* GNU Emacs routines to deal with syntax tables; also word and list parsing.
X!    Copyright (C) 1985-1993 Free Software Foundation, Inc.
X  
X  This file is part of GNU Emacs.
X  
X  GNU Emacs is free software; you can redistribute it and/or modify
X  it under the terms of the GNU General Public License as published by
X! the Free Software Foundation; either version 2, or (at your option)
X  any later version.
X  
X  GNU Emacs is distributed in the hope that it will be useful,
X***************
X*** 25,32 ****
X--- 25,120 ----
X  #include "buffer.h"
X  #include "syntax.h"
X  
X+ /* Equivalent macro, extern names (v.19 == v.18):
X+    NILP(obj)			== NULL(obj)
X+    VECTORP(obj)			== (XTYPE(obj)==Lisp_Vector)
X+    FIXNUMP(obj)			== (XTYPE(obj)==Lisp_Int)
X+    CHECK_FIXNUM(a,b)		== CHECK_NUMBER(a,b)
X+    insert_string(string)	== InsStr(string)
X+    insert_raw_string(s,l)	== insert(s,l)
X+    internal_set_buffer(b)	== set_buffer_internal(b)
X+    CHAR_AT(from)		== FETCH_CHAR(from)
X+ */
X+ 
X  Lisp_Object Qsyntax_table_p;
X  
X+ int words_include_escapes;
X+ 
X+ /* There is an alist of syntax tables: names (strings) vs obarrays. */
X+ 
X+ /* This is the internal form of the parse state used in parse-partial-sexp.  */
X+ 
X+ struct lisp_parse_state
X+   {
X+     int depth;		/* Depth at end of parsing */
X+     int instring;	/* -1 if not within string, else desired terminator. */
X+     int incomment;	/* Nonzero if within a comment at end of parsing */
X+     int comstyle;	/* comment style a=0, or b=1 */
X+     int quoted;		/* Nonzero if just after an escape char at end of parsing */
X+     int thislevelstart;	/* Char number of most recent start-of-expression at current level */
X+     int prevlevelstart; /* Char number of start of containing expression */
X+     int location;	/* Char number at which parsing stopped. */
X+     int mindepth;	/* Minimum depth seen while scanning.  */
X+     int comstart;	/* Position just after last comment starter.  */
X+   };
X+ 
X+ /* These variables are a cache for finding the start of a defun.
X+    find_start_pos is the place for which the defun start was found.
X+    find_start_value is the defun start position found for it.
X+    find_start_buffer is the buffer it was found in.
X+    find_start_begv is the BEGV value when it was found.
X+    find_start_modiff is the value of MODIFF when it was found.  */
X+ 
X+ static int find_start_pos;
X+ static int find_start_value;
X+ static struct buffer *find_start_buffer;
X+ static int find_start_begv;
X+ static int find_start_modiff;
X+ 
X+ /* Find a defun-start that is the last one before POS (or nearly the last).
X+    We record what we find, so that another call in the same area
X+    can return the same value right away.  */
X+ 
X+ static int
X+ find_defun_start (pos)
X+      int pos;
X+ {
X+   int tem;
X+   int shortage;
X+ 
X+   /* Use previous finding, if it's valid and applies to this inquiry.  */
X+   if (current_buffer == find_start_buffer
X+       /* Reuse the defun-start even if POS is a little farther on.
X+ 	 POS might be in the next defun, but that's ok.
X+ 	 Our value may not be the best possible, but will still be usable.  */
X+       && pos <= find_start_pos + 1000
X+       && pos >= find_start_value
X+       && BEGV == find_start_begv
X+       && MODIFF == find_start_modiff)
X+     return find_start_value;
X+ 
X+   /* Back up to start of line.  */
X+   tem = scan_buffer ('\n', pos, -1, &shortage);
X+ 
X+   while (tem > BEGV)
X+     {
X+       /* Open-paren at start of line means we found our defun-start.  */
X+       if (SYNTAX (FETCH_CHAR (tem)) == Sopen)
X+ 	break;
X+       /* Move to beg of previous line.  */
X+       tem = scan_buffer ('\n', tem, -2, &shortage);
X+     }
X+ 
X+   /* Record what we found, for the next try.  */
X+   find_start_value = tem;
X+   find_start_buffer = current_buffer;
X+   find_start_modiff = MODIFF;
X+   find_start_begv = BEGV;
X+   find_start_pos = pos;
X+ 
X+   return find_start_value;
X+ }
X+ 
X  DEFUN ("syntax-table-p", Fsyntax_table_p, Ssyntax_table_p, 1, 1, 0,
X    "Return t if ARG is a syntax table.\n\
X  Any vector of 256 elements will do.")
X***************
X*** 33,44 ****
X    (obj)
X       Lisp_Object obj;
X  {
X!   if (XTYPE (obj) == Lisp_Vector && XVECTOR (obj)->size == 0400)
X      return Qt;
X    return Qnil;
X  }
X  
X! Lisp_Object
X  check_syntax_table (obj)
X       Lisp_Object obj;
X  {
X--- 121,132 ----
X    (obj)
X       Lisp_Object obj;
X  {
X!   if ((XTYPE(obj)==Lisp_Vector) && XVECTOR (obj)->size == 0400)
X      return Qt;
X    return Qnil;
X  }
X  
X! static Lisp_Object
X  check_syntax_table (obj)
X       Lisp_Object obj;
X  {
X***************
X*** 45,51 ****
X    register Lisp_Object tem;
X    while (tem = Fsyntax_table_p (obj),
X  	 NULL (tem))
X!     obj = wrong_type_argument (Qsyntax_table_p, obj, 0);
X    return obj;
X  }   
X  
X--- 133,139 ----
X    register Lisp_Object tem;
X    while (tem = Fsyntax_table_p (obj),
X  	 NULL (tem))
X!     obj = wrong_type_argument (Qsyntax_table_p, obj);
X    return obj;
X  }   
X  
X***************
X*** 84,91 ****
X      return val;
X    else table = Vstandard_syntax_table;
X  
X!   bcopy (XVECTOR (table)->contents,
X! 	 XVECTOR (val)->contents, 0400 * sizeof (Lisp_Object));
X    return val;
X  }
X  
X--- 172,179 ----
X      return val;
X    else table = Vstandard_syntax_table;
X  
X!   memcpy (XVECTOR (val)->contents, XVECTOR (table)->contents,
X! 	  0400 * sizeof (Lisp_Object));
X    return val;
X  }
X  
X***************
X*** 98,104 ****
X    table = check_syntax_table (table);
X    current_buffer->syntax_table = table;
X    /* Indicate that this buffer now has a specified syntax table.  */
X!   current_buffer->local_var_flags |= buffer_local_flags.syntax_table;
X    return table;
X  }
X  
X--- 186,193 ----
X    table = check_syntax_table (table);
X    current_buffer->syntax_table = table;
X    /* Indicate that this buffer now has a specified syntax table.  */
X!   current_buffer->local_var_flags |=
X!     XFASTINT (buffer_local_flags.syntax_table);
X    return table;
X  }
X  
X***************
X*** 130,136 ****
X  
X  /* Indexed by syntax code, give the letter that describes it. */
X  
X! char syntax_code_spec[13] =
X    {
X      ' ', '.', 'w', '_', '(', ')', '\'', '\"', '$', '\\', '/', '<', '>'
X    };
X--- 219,225 ----
X  
X  /* Indexed by syntax code, give the letter that describes it. */
X  
X! unsigned char syntax_code_spec[13] =
X    {
X      ' ', '.', 'w', '_', '(', ')', '\'', '\"', '$', '\\', '/', '<', '>'
X    };
X***************
X*** 137,145 ****
X  
X  DEFUN ("char-syntax", Fchar_syntax, Schar_syntax, 1, 1, 0,
X    "Return the syntax code of CHAR, described by a character.\n\
X! For example, if CHAR is a word constituent, ?w is returned.\n\
X  The characters that correspond to various syntax codes\n\
X! are listed in the documentation of  modify-syntax-entry.")
X    (ch)
X       Lisp_Object ch;
X  {
X--- 226,234 ----
X  
X  DEFUN ("char-syntax", Fchar_syntax, Schar_syntax, 1, 1, 0,
X    "Return the syntax code of CHAR, described by a character.\n\
X! For example, if CHAR is a word constituent, the character `?w' is returned.\n\
X  The characters that correspond to various syntax codes\n\
X! are listed in the documentation of `modify-syntax-entry'.")
X    (ch)
X       Lisp_Object ch;
X  {
X***************
X*** 156,179 ****
X  The syntax is changed only for table TABLE, which defaults to\n\
X   the current buffer's syntax table.\n\
X  The first character of S should be one of the following:\n\
X!   Space or -   whitespace syntax.    w   word constituent.\n\
X!   _            symbol constituent.   .   punctuation.\n\
X!   (            open-parenthesis.     )   close-parenthesis.\n\
X!   \"            string quote.         \\   escape character.\n\
X!   $            paired delimiter.     '   expression prefix operator.\n\
X!   <            comment starter.      >   comment ender.\n\
X!   /	       character quote.\n\
X  Only single-character comment start and end sequences are represented thus.\n\
X  Two-character sequences are represented as described below.\n\
X  The second character of S is the matching parenthesis,\n\
X!  used only if the first character is ( or ).\n\
X  Any additional characters are flags.\n\
X! Defined flags are the characters 1, 2, 3 and 4.\n\
X!  1 means C is the start of a two-char comment start sequence.\n\
X   2 means C is the second character of such a sequence.\n\
X!  3 means C is the start of a two-char comment end sequence.\n\
X!  4 means C is the second character of such a sequence.")
X! 
X  */
X  
X  DEFUN ("modify-syntax-entry", Fmodify_syntax_entry, Smodify_syntax_entry, 2, 3, 
X--- 245,276 ----
X  The syntax is changed only for table TABLE, which defaults to\n\
X   the current buffer's syntax table.\n\
X  The first character of S should be one of the following:\n\
X!   Space    whitespace syntax.    w   word constituent.\n\
X!   _        symbol constituent.   .   punctuation.\n\
X!   (        open-parenthesis.     )   close-parenthesis.\n\
X!   \"        string quote.         \\   character-quote.\n\
X!   $        paired delimiter.     '   expression quote or prefix operator.\n\
X!   <	   comment starter.	 >   comment ender.\n\
X  Only single-character comment start and end sequences are represented thus.\n\
X  Two-character sequences are represented as described below.\n\
X  The second character of S is the matching parenthesis,\n\
X!  used only if the first character is `(' or `)'.\n\
X  Any additional characters are flags.\n\
X! Defined flags are the characters 1, 2, 3, 4, 5, 6, 7, 8, p, a, and b.\n\
X!  1 means C is the first of a two-char comment start sequence of style a.\n\
X   2 means C is the second character of such a sequence.\n\
X!  3 means C is the first of a two-char comment end sequence of style a.\n\
X!  4 means C is the second character of such a sequence.\n\
X!  5 means C is the first of a two-char comment start sequence of style b.\n\
X!  6 means C is the second character of such a sequence.\n\
X!  7 means C is the first of a two-char comment end sequence of style b.\n\
X!  8 means C is the second character of such a sequence.\n\
X!  p means C is a prefix character for `backward-prefix-chars';\n\
X!    such characters are treated as whitespace when they occur\n\
X!    between expressions.\n\
X!  a means C is comment starter or comment ender for comment style a (default)\n\
X!  b means C is comment starter or comment ender for comment style b.")
X!   (c, newentry, syntax_table)
X  */
X  
X  DEFUN ("modify-syntax-entry", Fmodify_syntax_entry, Smodify_syntax_entry, 2, 3, 
X***************
X*** 188,193 ****
X--- 285,291 ----
X    register unsigned char *p, match;
X    register enum syntaxcode code;
X    Lisp_Object val;
X+   int b_flag_seen_p = 0;
X  
X    CHECK_NUMBER (c, 0);
X    CHECK_STRING (newentry, 1);
X***************
X*** 206,231 ****
X    if (match == ' ') match = 0;
X  
X    XFASTINT (val) = (match << 8) + (int) code;
X    while (*p)
X      switch (*p++)
X        {
X        case '1':
X! 	XFASTINT (val) |= 1 << 16;
X  	break;
X  
X        case '2':
X! 	XFASTINT (val) |= 1 << 17;
X  	break;
X  
X        case '3':
X! 	XFASTINT (val) |= 1 << 18;
X  	break;
X  
X        case '4':
X! 	XFASTINT (val) |= 1 << 19;
X  	break;
X        }
X  	
X    XVECTOR (syntax_table)->contents[0xFF & XINT (c)] = val;
X  
X    return Qnil;
X--- 304,374 ----
X    if (match == ' ') match = 0;
X  
X    XFASTINT (val) = (match << 8) + (int) code;
X+   
X    while (*p)
X      switch (*p++)
X        {
X        case '1':
X! 	XFASTINT (val) |= SYNTAX_FIRST_OF_START_A << 16;
X  	break;
X  
X        case '2':
X! 	XFASTINT (val) |= SYNTAX_SECOND_OF_START_A << 16;
X  	break;
X  
X        case '3':
X! 	XFASTINT (val) |= SYNTAX_FIRST_OF_END_A << 16;
X  	break;
X  
X        case '4':
X! 	XFASTINT (val) |= SYNTAX_SECOND_OF_END_A << 16;
X  	break;
X+ 
X+       case '5':
X+ 	XFASTINT (val) |= SYNTAX_FIRST_OF_START_B << 16;
X+ 	break;
X+ 
X+       case '6':
X+ 	XFASTINT (val) |= SYNTAX_SECOND_OF_START_B << 16;
X+ 	break;
X+ 
X+       case '7':
X+ 	XFASTINT (val) |= SYNTAX_FIRST_OF_END_B << 16;
X+ 	break;
X+ 
X+       case '8':
X+ 	XFASTINT (val) |= SYNTAX_SECOND_OF_END_B << 16;
X+ 	break;
X+ 
X+       case 'a':
X+ 	if (code == Scomment)
X+ 	  XFASTINT (val) |= SYNTAX_FIRST_OF_START_A << 16;
X+ 	else if (code == Sendcomment)
X+ 	  XFASTINT (val) |= SYNTAX_FIRST_OF_END_A << 16;
X+ 
X+ 	break;
X+ 
X+       case 'b':
X+ 	if (code == Scomment)
X+ 	  XFASTINT (val) |= SYNTAX_FIRST_OF_START_B << 16;
X+ 	else if (code == Sendcomment)
X+ 	  XFASTINT (val) |= SYNTAX_FIRST_OF_END_B << 16;
X+ 
X+ 	b_flag_seen_p = 1;
X+ 	break;
X+ 
X+       case 'p':
X+ 	XFASTINT (val) |= 1 << 7;
X+ 	break;
X        }
X  	
X+   /* default single char style is a if b has not been seen */
X+   if (!b_flag_seen_p)
X+     if (code == Scomment)
X+       XFASTINT (val) |= SYNTAX_FIRST_OF_START_A << 16;
X+     else if (code == Sendcomment)
X+       XFASTINT (val) |= SYNTAX_FIRST_OF_END_A << 16;
X+ 
X    XVECTOR (syntax_table)->contents[0xFF & XINT (c)] = val;
X  
X    return Qnil;
X***************
X*** 233,248 ****
X  
X  /* Dump syntax table to buffer in human-readable format */
X  
X  describe_syntax (value)
X      Lisp_Object value;
X  {
X    register enum syntaxcode code;
X!   char desc, match, start1, start2, end1, end2;
X    char str[2];
X  
X    Findent_to (make_number (16), make_number (1));
X  
X!   if (XTYPE (value) != Lisp_Int)
X      {
X        InsStr ("invalid");
X        return;
X--- 376,393 ----
X  
X  /* Dump syntax table to buffer in human-readable format */
X  
X+ static void
X  describe_syntax (value)
X      Lisp_Object value;
X  {
X    register enum syntaxcode code;
X!   char desc, match, start1, start2, end1, end2, prefix;
X!   char start1b, start2b, end1b, end2b;
X    char str[2];
X  
X    Findent_to (make_number (16), make_number (1));
X  
X!   if (!(XTYPE(value)==Lisp_Int))
X      {
X        InsStr ("invalid");
X        return;
X***************
X*** 250,260 ****
X  
X    code = (enum syntaxcode) (XINT (value) & 0377);
X    match = (XINT (value) >> 8) & 0377;
X-   start1 = (XINT (value) >> 16) & 1;
X-   start2 = (XINT (value) >> 17) & 1;
X-   end1 = (XINT (value) >> 18) & 1;
X-   end2 = (XINT (value) >> 19) & 1;
X  
X    if ((int) code < 0 || (int) code >= (int) Smax)
X      {
X        InsStr ("invalid");
X--- 395,411 ----
X  
X    code = (enum syntaxcode) (XINT (value) & 0377);
X    match = (XINT (value) >> 8) & 0377;
X  
X+   start1 = (XINT (value) >> 16) & SYNTAX_FIRST_OF_START_A;
X+   start2 = (XINT (value) >> 16) & SYNTAX_SECOND_OF_START_A;
X+   end1 = (XINT (value) >> 16) & SYNTAX_FIRST_OF_END_A;
X+   end2 = (XINT (value) >> 16) & SYNTAX_SECOND_OF_END_A;
X+   start1b = (XINT (value) >> 16) & SYNTAX_FIRST_OF_START_B;
X+   start2b = (XINT (value) >> 16) & SYNTAX_SECOND_OF_START_B;
X+   end1b = (XINT (value) >> 16) & SYNTAX_FIRST_OF_END_B;
X+   end2b = (XINT (value) >> 16) & SYNTAX_SECOND_OF_END_B;
X+   prefix = (XINT (value) >> 7) & 1;
X+ 
X    if ((int) code < 0 || (int) code >= (int) Smax)
X      {
X        InsStr ("invalid");
X***************
X*** 268,284 ****
X    str[0] = match ? match : ' ';
X    insert (str, 1);
X  
X- 
X    if (start1)
X!     insert ("1", 1);
X    if (start2)
X      insert ("2", 1);
X  
X    if (end1)
X!     insert ("3", 1);
X    if (end2)
X      insert ("4", 1);
X  
X    InsStr ("\twhich means: ");
X  
X  #ifdef SWITCH_ENUM_BUG
X--- 419,463 ----
X    str[0] = match ? match : ' ';
X    insert (str, 1);
X  
X    if (start1)
X!     if (code==Scomment)
X!       insert ("a", 1);
X!     else
X!       insert ("1", 1);
X! 
X    if (start2)
X      insert ("2", 1);
X  
X    if (end1)
X!     if (code==Sendcomment)
X!       insert ("a", 1);
X!     else
X!       insert ("3", 1);
X! 
X    if (end2)
X      insert ("4", 1);
X  
X+   if (start1b)
X+     if (code==Scomment)
X+       insert ("b", 1);
X+     else
X+       insert ("5", 1);
X+ 
X+   if (start2b)
X+     insert ("6", 1);
X+ 
X+   if (end1b)
X+     if (code==Sendcomment)
X+       insert ("b", 1);
X+     else
X+       insert ("7", 1);
X+ 
X+   if (end2b)
X+     insert ("8", 1);
X+ 
X+   if (prefix)
X+     insert ("p", 1);
X+ 
X    InsStr ("\twhich means: ");
X  
X  #ifdef SWITCH_ENUM_BUG
X***************
X*** 327,351 ****
X      }
X  
X    if (start1)
X!     InsStr (",\n\t  is the first character of a comment-start sequence");
X    if (start2)
X!     InsStr (",\n\t  is the second character of a comment-start sequence");
X  
X    if (end1)
X!     InsStr (",\n\t  is the first character of a comment-end sequence");
X    if (end2)
X!     InsStr (",\n\t  is the second character of a comment-end sequence");
X  
X    InsStr ("\n");
X  }
X  
X! Lisp_Object
X  describe_syntax_1 (vector)
X       Lisp_Object vector;
X  {
X    struct buffer *old = current_buffer;
X    set_buffer_internal (XBUFFER (Vstandard_output));
X!   describe_vector (vector, Qnil, describe_syntax, 0, Qnil);
X    set_buffer_internal (old);
X    return Qnil;
X  }
X--- 506,608 ----
X      }
X  
X    if (start1)
X!     if (code==Scomment)
X!       InsStr (",\n\t  starts comment style-a");
X!     else
X!       InsStr (",\n\t  is the first char of a style-a, comment-start sequence");
X! 
X    if (start2)
X!     InsStr (",\n\t  is the second char of a style-a, comment-start sequence");
X  
X    if (end1)
X!     if (code==Sendcomment)
X!       InsStr (",\n\t  ends comment style-a");
X!     else
X!       InsStr (",\n\t  is the first char of a style-a, comment-end sequence");
X! 
X    if (end2)
X!     InsStr (",\n\t  is the second char of a style-a, comment-end sequence");
X  
X+   if (start1b)
X+     if (code==Scomment)
X+       InsStr (",\n\t  starts comment style-b");
X+     else
X+       InsStr (",\n\t  is the first char of a style-b, comment-start sequence");
X+ 
X+   if (start2b)
X+     InsStr (",\n\t  is the second char of a style-b, comment-start sequence");
X+ 
X+   if (end1b)
X+     if (code==Sendcomment)
X+       InsStr (",\n\t  ends comment style-b");
X+     else
X+       InsStr (",\n\t  is the first char of a style-b, comment-end sequence");
X+ 
X+   if (end2b)
X+     InsStr (",\n\t  is the second char of a style-b, comment-end sequence");
X+ 
X+   if (prefix)
X+     InsStr (",\n\t  is a prefix character for `backward-prefix-chars'");
X+ 
X    InsStr ("\n");
X  }
X  
X! 
X! static Lisp_Object
X  describe_syntax_1 (vector)
X       Lisp_Object vector;
X  {
X    struct buffer *old = current_buffer;
X+   int i, size = XVECTOR (vector)->size, range_start = 0;
X+   Lisp_Object string, current_code = XVECTOR (vector)->contents[0];
X+   int top;
X+ 
X    set_buffer_internal (XBUFFER (Vstandard_output));
X! 
X!   top = ((NULL (current_buffer->ctl_arrow) ||
X! 	  EQ (current_buffer->ctl_arrow, Qt))
X! 	 ? size : ((XTYPE (current_buffer->ctl_arrow) == Lisp_Int)
X! 		   ? XINT (current_buffer->ctl_arrow)
X! 		   : 0240));
X!   for (i = 1; i <= size; i++)
X!     {
X!       QUIT;
X! 
X!       if ((i == size ) || 
X! 	  (XINT (current_code) != XINT (XVECTOR (vector)->contents[i])))
X! 	/* end of vector or end of range */
X! 	{
X! 	  unsigned char c = range_start;
X! 	  if (c >= top)
X! 	    insert ((char *) &c, 1);
X! 	  else
X! 	    {
X! 	      string = Fsingle_key_description (make_number (range_start));
X! 	      insert ((char *) XSTRING (string)->data,
X! 				 XSTRING (string)->size);
X! 	    }
X! 	  
X! 	  if (i - range_start > 1)	/* Really was a range */
X! 	    {
X! 	      InsStr (" .. ");
X! 	      c = i - 1;
X! 	      if (c >= top)
X! 		insert ((char *) &c, 1);
X! 	      else
X! 		{
X! 		  string = Fsingle_key_description (make_number (i - 1));
X! 		  insert ((char *) XSTRING (string)->data,
X! 				     XSTRING (string)->size);
X! 		}
X! 	      describe_syntax (current_code);
X! 	    }
X! 	  describe_syntax (current_code);
X! 	}
X!       range_start = i;
X!       if (i < size)
X! 	current_code = XVECTOR (vector)->contents[i];
X!     }
X! 
X    set_buffer_internal (old);
X    return Qnil;
X  }
X***************
X*** 352,379 ****
X  
X  DEFUN ("describe-syntax", Fdescribe_syntax, Sdescribe_syntax, 0, 0, "",
X    "Describe the syntax specifications in the syntax table.\n\
X! The descriptions are inserted in a buffer, which is selected so you can see it.")
X!   ()
X  {
X    internal_with_output_to_temp_buffer
X!      ("*Help*", describe_syntax_1, current_buffer->syntax_table);
X! 
X    return Qnil;
X  }
X  
X! /* Return the position across `count' words from `from'.
X     If that many words cannot be found before the end of the buffer, return 0.
X!    `count' negative means scan backward and stop at word beginning.  */
X  
X  scan_words (from, count)
X       register int from, count;
X  {
X    register int beg = BEGV;
X    register int end = ZV;
X! 
X    immediate_quit = 1;
X    QUIT;
X! 
X    while (count > 0)
X      {
X        while (1)
X--- 609,638 ----
X  
X  DEFUN ("describe-syntax", Fdescribe_syntax, Sdescribe_syntax, 0, 0, "",
X    "Describe the syntax specifications in the syntax table.\n\
X! The descriptions are inserted in a buffer, which is then displayed.")
X!      ()
X  {
X    internal_with_output_to_temp_buffer
X!     ("*Help*", describe_syntax_1, current_buffer->syntax_table);
X!   
X    return Qnil;
X  }
X  
X! /* Return the position across COUNT words from FROM.
X     If that many words cannot be found before the end of the buffer, return 0.
X!    COUNT negative means scan backward and stop at word beginning.  */
X  
X+ int
X  scan_words (from, count)
X       register int from, count;
X  {
X    register int beg = BEGV;
X    register int end = ZV;
X!   register enum syntaxcode code;
X!   
X    immediate_quit = 1;
X    QUIT;
X!   
X    while (count > 0)
X      {
X        while (1)
X***************
X*** 383,397 ****
X  	      immediate_quit = 0;
X  	      return 0;
X  	    }
X! 	  if (SYNTAX(FETCH_CHAR (from)) == Sword)
X  	    break;
X  	  from++;
X  	}
X        while (1)
X  	{
X  	  if (from == end) break;
X! 	  if (SYNTAX(FETCH_CHAR (from)) != Sword)
X! 	    break;
X  	  from++;
X  	}
X        count--;
X--- 642,663 ----
X  	      immediate_quit = 0;
X  	      return 0;
X  	    }
X! 	  code = SYNTAX (FETCH_CHAR (from));
X! 	  if (words_include_escapes
X! 	      && (code == Sescape || code == Scharquote))
X  	    break;
X+ 	  if (code == Sword)
X+ 	    break;
X  	  from++;
X  	}
X        while (1)
X  	{
X  	  if (from == end) break;
X! 	  code = SYNTAX (FETCH_CHAR (from));
X! 	  if (!(words_include_escapes
X! 		&& (code == Sescape || code == Scharquote)))
X! 	    if (code != Sword)
X! 	      break;
X  	  from++;
X  	}
X        count--;
X***************
X*** 405,419 ****
X  	      immediate_quit = 0;
X  	      return 0;
X  	    }
X! 	  if (SYNTAX(FETCH_CHAR (from - 1)) == Sword)
X  	    break;
X  	  from--;
X  	}
X        while (1)
X  	{
X  	  if (from == beg) break;
X! 	  if (SYNTAX(FETCH_CHAR (from - 1)) != Sword)
X! 	    break;
X  	  from--;
X  	}
X        count++;
X--- 671,692 ----
X  	      immediate_quit = 0;
X  	      return 0;
X  	    }
X! 	  code = SYNTAX (FETCH_CHAR (from - 1));
X! 	  if (words_include_escapes
X! 	      && (code == Sescape || code == Scharquote))
X  	    break;
X+ 	  if (code == Sword)
X+ 	    break;
X  	  from--;
X  	}
X        while (1)
X  	{
X  	  if (from == beg) break;
X! 	  code = SYNTAX (FETCH_CHAR (from - 1));
X! 	  if (!(words_include_escapes
X! 		&& (code == Sescape || code == Scharquote)))
X! 	    if (code != Sword)
X! 	      break;
X  	  from--;
X  	}
X        count++;
X***************
X*** 444,451 ****
X--- 717,1042 ----
X    return Qt;
X  }
X  
X+ static int char_quoted ();
X+ static void scan_sexps_forward ();
X+ 
X+ static int
X+ find_start_of_comment (from, stop, mask)
X+     int from, stop, mask;
X+ {
X+     int c;
X+     enum syntaxcode code;
X+ 
X+     /* Look back, counting the parity of string-quotes,
X+        and recording the comment-starters seen.
X+        When we reach a safe place, assume that's not in a string;
X+        then step the main scan to the earliest comment-starter seen
X+        an even number of string quotes away from the safe place.
X+        
X+        OFROM[I] is position of the earliest comment-starter seen
X+        which is I+2X quotes from the comment-end.
X+        PARITY is current parity of quotes from the comment end.  */
X+     int parity = 0;
X+     char my_stringend = 0;
X+     int string_lossage = 0;
X+     int comment_end = from;
X+     int comstart_pos = 0;
X+     int comstart_parity = 0;
X+     int styles_match_p = 0;
X+ 
X+     /* At beginning of range to scan, we're outside of strings;
X+        that determines quote parity to the comment-end.  */
X+     while (from != stop)
X+     {
X+ 	/* Move back and examine a character.  */
X+ 	from--;
X+ 
X+ 	c = FETCH_CHAR (from);
X+ 	code = SYNTAX (c);
X+ 
X+ 	/* is this a 1-char comment end sequence? if so, try
X+ 	   to see if style matches previously extracted mask */
X+ 	if (code == Sendcomment)
X+ 	{
X+ 	    styles_match_p = SYNTAX_STYLES_MATCH_1CHAR_P (c, mask);
X+ 	}
X+ 
X+ 	/* otherwise, is this a 2-char comment end sequence?
X+ 	   if so, back up, and see if style matches previously
X+ 	   extracted mask */
X+ 	else if (from > stop
X+ 		 && SYNTAX_END_P (FETCH_CHAR (from-1), c))
X+ 	{
X+ 	    code = Sendcomment;
X+ 	    styles_match_p =
X+ 	      SYNTAX_STYLES_MATCH_END_P (FETCH_CHAR (from-1), c, mask);
X+ 
X+ 	    from--;
X+ 	}
X+ 			
X+ 	/* or are we looking at a 1-char comment start sequence
X+ 	   of the style matching mask? */
X+ 	else if (code == Scomment
X+ 		 && SYNTAX_STYLES_MATCH_1CHAR_P (c, mask))
X+ 	{
X+ 	    styles_match_p = 1;
X+ 	}
X+ 		    
X+ 	/* or possibly, a 2-char comment start sequence */
X+ 	else if (from > stop
X+ 		 && SYNTAX_STYLES_MATCH_START_P (FETCH_CHAR (from-1), c, mask))
X+ 	{
X+ 	    code = Scomment;
X+ 	    from--;
X+ 	    styles_match_p = 1;
X+ 	}
X+ 
X+ 	/* Ignore escaped characters.  */
X+ 	if (char_quoted (from))
X+ 	    continue;
X+ 
X+ 	/* Track parity of quotes.  */
X+ 	if (code == Sstring)
X+ 	{
X+ 	    parity ^= 1;
X+ 	    if (my_stringend == 0)
X+ 		my_stringend = c;
X+ 	    /* If we have two kinds of string delimiters.
X+ 	       There's no way to grok this scanning backwards.  */
X+ 	    else if (my_stringend != c)
X+ 		string_lossage = 1;
X+ 	}
X+ 
X+ 	/* Record comment-starters according to that
X+ 	   quote-parity to the comment-end.  */
X+ 	if (code == Scomment && styles_match_p)
X+ 	{
X+ 	    comstart_parity = parity;
X+ 	    comstart_pos = from;
X+ 	}
X+ 
X+ 	/* If we find another earlier comment-ender,
X+ 	   any comment-starts earier than that don't count
X+ 	   (because they go with the earlier comment-ender).  */
X+ 	if (code == Sendcomment && styles_match_p)
X+ 	    break;
X+ 
X+ 	/* Assume a defun-start point is outside of strings.  */
X+ 	if (code == Sopen
X+ 	    && (from == stop || FETCH_CHAR (from - 1) == '\n'))
X+ 	    break;
X+     }
X+ 
X+     if (comstart_pos == 0)
X+ 	from = comment_end;
X+     /* If the earliest comment starter
X+        is followed by uniform paired string quotes or none,
X+        we know it can't be inside a string
X+        since if it were then the comment ender would be inside one.
X+        So it does start a comment.  Skip back to it.  */
X+     else if (comstart_parity == 0 && !string_lossage)
X+ 	from = comstart_pos;
X+     else
X+     {
X+       /* We had two kinds of string delimiters mixed up
X+ 	 together.  Decode this going forwards.
X+ 	 Scan fwd from the previous comment ender
X+ 	 to the one in question; this records where we
X+ 	 last passed a comment starter.  */
X+ 
X+       struct lisp_parse_state state;
X+       scan_sexps_forward (&state, find_defun_start (comment_end),
X+ 			  comment_end - 1, -10000, 0, Qnil);
X+       if (state.incomment)
X+ 	from = state.comstart;
X+       else
X+       /* We can't grok this as a comment; scan it normally.  */
X+ 	from = comment_end;
X+     }
X+     return from;
X+ }  
X+ 
X+ static int
X+ find_end_of_comment (from, stop, mask)
X+      int from, stop, mask;
X+ {
X+   int c;
X+ 
X+   while (1)
X+     {
X+       if (from == stop)
X+ 	{
X+ 	  return -1;
X+ 	}
X+       c = FETCH_CHAR (from);
X+       if (SYNTAX (c) == Sendcomment
X+ 	  && SYNTAX_STYLES_MATCH_1CHAR_P (c, mask))
X+ 	/* we have encountered a comment end of the same style
X+ 	   as the comment sequence which began this comment
X+ 	   section */
X+ 	break;
X+ 
X+       from++;
X+       if (from < stop
X+ 	  && SYNTAX_STYLES_MATCH_END_P (c, FETCH_CHAR (from), mask))
X+ 	/* we have encountered a comment end of the same style
X+ 	   as the comment sequence which began this comment
X+ 	   section */
X+ 	{ from++; break; }
X+     }
X+   return from;
X+ }
X+ 
X+ 
X  int parse_sexp_ignore_comments;
X  
X+ DEFUN ("forward-comment", Fforward_comment, Sforward_comment, 1, 1, 0,
X+   "Move forward across up to N comments.  If N is negative, move backward.\n\
X+ Set point to the far end of the last comment found.\n\
X+ Stop scanning if we find something other than a comment or whitespace.\n\
X+ If N comments are found as expected, with nothing except whitespace\n\
X+ between them, return t; otherwise return nil.  Point is set in either case.")
X+   (cntarg)
X+      Lisp_Object cntarg;
X+ {
X+   register int from;
X+   register int stop;
X+   register int c;
X+   register enum syntaxcode code;
X+   int count;
X+   int mask = 0;			/* mask for finding matching comment style */
X+ 
X+   CHECK_NUMBER (cntarg, 0);
X+   count = XINT (cntarg);
X+ 
X+   immediate_quit = 1;
X+   QUIT;
X+ 
X+   from = PT;
X+ 
X+   while (count > 0)
X+     {
X+       stop = ZV;
X+       while (from < stop)
X+ 	{
X+ 	  if (char_quoted (from))
X+ 	    { from++; continue; }
X+ 
X+ 	  c = FETCH_CHAR (from);
X+ 	  code = SYNTAX (c);
X+ 	  mask = 0x0;
X+ 
X+ 	  if (code == Scomment)
X+ 	    {
X+ 	      /* we have encountered a single character comment start
X+ 		 sequence, and we are ignoring all text inside comments.
X+ 		 we must record the comment style this character begins
X+ 		 so that later, only a comment end of the same style actually
X+ 		 ends the comment section */
X+ 	      mask = SYNTAX_COMMENT_1CHAR_MASK (c);
X+ 	    }
X+ 
X+ 	  else if (from < stop && SYNTAX_START_P (c, FETCH_CHAR (from+1)))
X+ 	    {
X+ 	      /* we have encountered a 2char comment start sequence and we 
X+ 		 are ignoring all text inside comments. we must record
X+ 		 the comment style this sequence begins so that later,
X+ 		 only a comment end of the same style actually ends
X+ 		 the comment section */
X+ 	      code = Scomment;
X+ 	      mask = SYNTAX_COMMENT_MASK_START (c, FETCH_CHAR (from+1));
X+ 	      from++;
X+ 	    }
X+ 
X+ 	  if (code == Scomment)
X+ 	    {
X+ 	      int newfrom;
X+ 
X+ 	      newfrom = find_end_of_comment (from, stop, mask);
X+ 	      if (newfrom < 0)
X+ 		{
X+ 		  /* we stopped because from==stop */
X+ 		  immediate_quit = 0;
X+ 		  SET_PT (stop);
X+ 		  return Qnil;
X+ 		}
X+ 	      from = newfrom;
X+ 
X+ 	      /* We have skipped one comment.  */
X+ 	      break;
X+ 	    }
X+ 	  else if (code != Swhitespace &&
X+ 		   code != Sendcomment &&
X+ 		   code != Scomment )
X+ 	    {
X+ 	      immediate_quit = 0;
X+ 	      SET_PT (from);
X+ 	      return Qnil;
X+ 	    }
X+ 	  from++;
X+ 	}
X+ 
X+       /* End of comment reached */
X+       count--;
X+     }
X+ 
X+   while (count < 0)
X+     {
X+       stop = BEGV;
X+       while (from > stop)
X+ 	{
X+ 	  int quoted;
X+ 
X+ 	  from--;
X+ 	  if (char_quoted (from))
X+ 	    { from--; continue; }
X+ 	      
X+ 	  c = FETCH_CHAR (from);
X+ 	  code = SYNTAX (c);
X+ 	  mask = 0x0;
X+ 
X+ 	  if (code == Sendcomment)
X+ 	    {
X+ 	      /* we have found a single char end comment. we must record
X+ 		 the comment style encountered so that later, we can match
X+ 		 only the proper comment begin sequence of the same style */
X+ 	      mask = SYNTAX_COMMENT_1CHAR_MASK (c);
X+ 	    }
X+ 
X+ 	  else if (from > stop
X+ 		   && SYNTAX_END_P (FETCH_CHAR (from-1), c)
X+ 		   && !char_quoted (from - 1))
X+ 	    {
X+ 	      /* we must record the comment style encountered so that
X+ 		 later, we can match only the proper comment begin
X+ 		 sequence of the same style */
X+ 	      code = Sendcomment;
X+ 	      mask = SYNTAX_COMMENT_MASK_END (FETCH_CHAR (from-1), c);
X+ 	      from--;
X+ 	    }
X+ 
X+ 	  if (code == Sendcomment)
X+ 	    from = find_start_of_comment (from, stop, mask);
X+ 
X+ 	  else if (code != Swhitespace &&
X+ 		   SYNTAX (c) != Scomment &&
X+ 		   SYNTAX (c) != Sendcomment)
X+ 	    {
X+ 	      immediate_quit = 0;
X+ 	      SET_PT (from+1);
X+ 	      return Qnil;
X+ 	    }
X+ 	}
X+ 
X+       count++;
X+     }
X+ 
X+   SET_PT (from);
X+   immediate_quit = 0;
X+   return Qt;
X+ }
X+ 
X+ 
X  Lisp_Object
X  scan_lists (from, count, depth, sexpflag)
X       register int from;
X***************
X*** 459,464 ****
X--- 1050,1056 ----
X    int mathexit = 0;
X    register enum syntaxcode code;
X    int min_depth = depth;    /* Err out if depth gets less than this. */
X+   int mask = 0x0;	    /* comment style mask */
X  
X    if (depth > 0) min_depth = 0;
X  
X***************
X*** 471,483 ****
X        while (from < stop)
X  	{
X  	  c = FETCH_CHAR (from);
X! 	  code = SYNTAX(c);
X  	  from++;
X- 	  if (from < stop && SYNTAX_COMSTART_FIRST (c)
X- 	      && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from))
X- 	      && parse_sexp_ignore_comments)
X- 	    code = Scomment, from++;
X  
X  #ifdef SWITCH_ENUM_BUG
X  	  switch ((int) code)
X  #else
X--- 1063,1095 ----
X        while (from < stop)
X  	{
X  	  c = FETCH_CHAR (from);
X! 	  code = SYNTAX (c);
X  	  from++;
X  
X+ 	  /* a 1-char comment start sequence */
X+ 	  if (code == Scomment && parse_sexp_ignore_comments)
X+ 	    {
X+ 	      mask = SYNTAX_COMMENT_1CHAR_MASK (c);
X+ 	    }
X+ 
X+ 	  /* else, a 2-char comment start sequence? */
X+ 	  else if (from < stop
X+ 		   && SYNTAX_START_P (c, FETCH_CHAR (from))
X+ 		   && parse_sexp_ignore_comments)
X+ 	    {
X+ 	      /* we have encountered a comment start sequence and we 
X+ 		 are ignoring all text inside comments. we must record
X+ 		 the comment style this sequence begins so that later,
X+ 		 only a comment end of the same style actually ends
X+ 		 the comment section */
X+ 	      code = Scomment;
X+ 	      mask = SYNTAX_COMMENT_MASK_START (c, FETCH_CHAR (from));
X+ 	      from++;
X+ 	    }
X+ 	  
X+ 	  if (SYNTAX_PREFIX (c))
X+ 	    continue;
X+ 
X  #ifdef SWITCH_ENUM_BUG
X  	  switch ((int) code)
X  #else
X***************
X*** 496,504 ****
X  	      while (from < stop)
X  		{
X  #ifdef SWITCH_ENUM_BUG
X! 		  switch ((int) SYNTAX(FETCH_CHAR (from)))
X  #else
X! 		  switch (SYNTAX(FETCH_CHAR (from)))
X  #endif
X  		    {
X  		    case Scharquote:
X--- 1108,1116 ----
X  	      while (from < stop)
X  		{
X  #ifdef SWITCH_ENUM_BUG
X! 		  switch ((int) SYNTAX (FETCH_CHAR (from)))
X  #else
X! 		  switch (SYNTAX (FETCH_CHAR (from)))
X  #endif
X  		    {
X  		    case Scharquote:
X***************
X*** 519,534 ****
X  
X  	    case Scomment:
X  	      if (!parse_sexp_ignore_comments) break;
X! 	      while (1)
X! 		{
X! 		  if (from == stop) goto done;
X! 		  if (SYNTAX (c = FETCH_CHAR (from)) == Sendcomment)
X! 		    break;
X! 		  from++;
X! 		  if (from < stop && SYNTAX_COMEND_FIRST (c)
X! 		       && SYNTAX_COMEND_SECOND (FETCH_CHAR (from)))
X! 		    { from++; break; }
X! 		}
X  	      break;
X  
X  	    case Smath:
X--- 1131,1146 ----
X  
X  	    case Scomment:
X  	      if (!parse_sexp_ignore_comments) break;
X! 	      {
X! 		int newfrom = find_end_of_comment (from, stop, mask);
X! 		if (newfrom < 0)
X! 		  {
X! 		    /* we stopped because from == stop in search forward */
X! 		    from = stop;
X! 		    goto done;
X! 		  }
X! 		from = newfrom;
X! 	      }
X  	      break;
X  
X  	    case Smath:
X***************
X*** 561,569 ****
X  		  if (from >= stop) goto lose;
X  		  if (FETCH_CHAR (from) == stringterm) break;
X  #ifdef SWITCH_ENUM_BUG
X! 		  switch ((int) SYNTAX(FETCH_CHAR (from)))
X  #else
X! 		  switch (SYNTAX(FETCH_CHAR (from)))
X  #endif
X  		    {
X  		    case Scharquote:
X--- 1173,1181 ----
X  		  if (from >= stop) goto lose;
X  		  if (FETCH_CHAR (from) == stringterm) break;
X  #ifdef SWITCH_ENUM_BUG
X! 		  switch ((int) SYNTAX (FETCH_CHAR (from)))
X  #else
X! 		  switch (SYNTAX (FETCH_CHAR (from)))
X  #endif
X  		    {
X  		    case Scharquote:
X***************
X*** 597,610 ****
X  	  from--;
X  	  if (quoted = char_quoted (from))
X  	    from--;
X  	  c = FETCH_CHAR (from);
X  	  code = SYNTAX (c);
X! 	  if (from > stop && SYNTAX_COMEND_SECOND (c)
X! 	      && SYNTAX_COMEND_FIRST (FETCH_CHAR (from - 1))
X! 	      && !char_quoted (from - 1)
X! 	      && parse_sexp_ignore_comments)
X! 	    code = Sendcomment, from--;
X  
X  #ifdef SWITCH_ENUM_BUG
X  	  switch ((int) (quoted ? Sword : code))
X  #else
X--- 1209,1243 ----
X  	  from--;
X  	  if (quoted = char_quoted (from))
X  	    from--;
X+ 
X  	  c = FETCH_CHAR (from);
X  	  code = SYNTAX (c);
X! 	  mask = 0x0;
X  
X+ 	  if (code == Sendcomment && parse_sexp_ignore_comments)
X+ 	    {
X+ 	      /* we have found a single char end comment. we must record
X+ 		 the comment style encountered so that later, we can match
X+ 		 only the proper comment begin sequence of the same style */
X+ 	      mask = SYNTAX_COMMENT_1CHAR_MASK (c);
X+ 	    }
X+ 
X+ 	  else if (from > stop
X+ 		   && SYNTAX_END_P (FETCH_CHAR (from-1), c)
X+ 		   && !char_quoted (from - 1)
X+ 		   && parse_sexp_ignore_comments)
X+ 	    {
X+ 	      /* we must record the comment style encountered so that
X+ 		 later, we can match only the proper comment begin
X+ 		 sequence of the same style */
X+ 	      code = Sendcomment;
X+ 	      mask = SYNTAX_COMMENT_MASK_END (FETCH_CHAR (from-1), c);
X+ 	      from--;
X+ 	    }
X+ 
X+ 	  if (SYNTAX_PREFIX (c))
X+ 	    continue;
X+ 
X  #ifdef SWITCH_ENUM_BUG
X  	  switch ((int) (quoted ? Sword : code))
X  #else
X***************
X*** 614,627 ****
X  	    case Sword:
X  	    case Ssymbol:
X  	      if (depth || !sexpflag) break;
X! 	      /* This word counts as a sexp; count object finished after passing it. */
X  	      while (from > stop)
X  		{
X! 		  if (quoted = char_quoted (from - 1))
X  		    from--;
X! 		  if (! (quoted || SYNTAX(FETCH_CHAR (from - 1)) == Sword ||
X! 			 SYNTAX(FETCH_CHAR (from - 1)) == Ssymbol ||
X! 			 SYNTAX(FETCH_CHAR (from - 1)) == Squote))
X              	    goto done2;
X  		  from--;
X  		}
X--- 1247,1262 ----
X  	    case Sword:
X  	    case Ssymbol:
X  	      if (depth || !sexpflag) break;
X! 	      /* This word counts as a sexp; count object finished after 
X! 		 passing it. */
X  	      while (from > stop)
X  		{
X! 		  quoted = char_quoted (from - 1);
X! 		  if (quoted)
X  		    from--;
X! 		  if (! (quoted || SYNTAX (FETCH_CHAR (from - 1)) == Sword
X! 			 || SYNTAX (FETCH_CHAR (from - 1)) == Ssymbol
X! 			 || SYNTAX (FETCH_CHAR (from - 1)) == Squote))
X              	    goto done2;
X  		  from--;
X  		}
X***************
X*** 651,669 ****
X  	      break;
X  
X  	    case Sendcomment:
X! 	      if (!parse_sexp_ignore_comments) break;
X! 	      if (from != stop) from--;
X! 	      while (1)
X! 		{
X! 		  if (SYNTAX (c = FETCH_CHAR (from)) == Scomment)
X! 		    break;
X! 		  if (from == stop) goto done;
X! 		  from--;
X! 		  if (SYNTAX_COMSTART_SECOND (c)
X! 		      && SYNTAX_COMSTART_FIRST (FETCH_CHAR (from))
X! 		      && !char_quoted (from))
X! 		    break;
X! 		}
X  	      break;
X  
X  	    case Sstring:
X--- 1286,1294 ----
X  	      break;
X  
X  	    case Sendcomment:
X! 	      if (parse_sexp_ignore_comments)
X! 		from = find_start_of_comment (from, stop, mask);
X! 
X  	      break;
X  
X  	    case Sstring:
X***************
X*** 700,707 ****
X--- 1325,1334 ----
X   lose:
X    error ("Unbalanced parentheses");
X    /* NOTREACHED */
X+   return Qnil; /* warning suppression */
X  }
X  
X+ static int
X  char_quoted (pos)
X       register int pos;
X  {
X***************
X*** 709,717 ****
X    register int beg = BEGV;
X    register int quoted = 0;
X  
X!   while (pos > beg &&
X! 	 ((code = SYNTAX (FETCH_CHAR (pos - 1))) == Scharquote
X! 	  || code == Sescape))
X      pos--, quoted = !quoted;
X    return quoted;
X  }
X--- 1336,1344 ----
X    register int beg = BEGV;
X    register int quoted = 0;
X  
X!   while (pos > beg
X! 	 && ((code = SYNTAX (FETCH_CHAR (pos - 1))) == Scharquote
X! 	     || code == Sescape))
X      pos--, quoted = !quoted;
X    return quoted;
X  }
X***************
X*** 725,733 ****
X  are candidates for stopping; COUNT such places are counted.\n\
X  Thus, a positive value for DEPTH means go out levels.\n\
X  \n\
X! Comments are ignored if parse-sexp-ignore-comments is non-nil.\n\
X  \n\
X! If the beginning or end of (the visible part of) the buffer is reached\n\
X  and the depth is wrong, an error is signaled.\n\
X  If the depth is right but the count is not used up, nil is returned.")
X    (from, count, depth)
X--- 1352,1360 ----
X  are candidates for stopping; COUNT such places are counted.\n\
X  Thus, a positive value for DEPTH means go out levels.\n\
X  \n\
X! Comments are ignored if `parse-sexp-ignore-comments' is non-nil.\n\
X  \n\
X! If the beginning or end of (the accessible part of) the buffer is reached\n\
X  and the depth is wrong, an error is signaled.\n\
X  If the depth is right but the count is not used up, nil is returned.")
X    (from, count, depth)
X***************
X*** 742,755 ****
X  
X  DEFUN ("scan-sexps", Fscan_sexps, Sscan_sexps, 2, 2, 0,
X    "Scan from character number FROM by COUNT balanced expressions.\n\
X  Returns the character number of the position thus found.\n\
X  \n\
X! Comments are ignored if parse-sexp-ignore-comments is non-nil.\n\
X  \n\
X! If the beginning or end of (the visible part of) the buffer is reached\n\
X  in the middle of a parenthetical grouping, an error is signaled.\n\
X! If the beginning or end is reached between groupings but before count is used up,\n\
X! nil is returned.")
X    (from, count)
X       Lisp_Object from, count;
X  {
X--- 1369,1383 ----
X  
X  DEFUN ("scan-sexps", Fscan_sexps, Sscan_sexps, 2, 2, 0,
X    "Scan from character number FROM by COUNT balanced expressions.\n\
X+ If COUNT is negative, scan backwards.\n\
X  Returns the character number of the position thus found.\n\
X  \n\
X! Comments are ignored if `parse-sexp-ignore-comments' is non-nil.\n\
X  \n\
X! If the beginning or end of (the accessible part of) the buffer is reached\n\
X  in the middle of a parenthetical grouping, an error is signaled.\n\
X! If the beginning or end is reached between groupings\n\
X! but before count is used up, nil is returned.")
X    (from, count)
X       Lisp_Object from, count;
X  {
X***************
X*** 761,773 ****
X  
X  DEFUN ("backward-prefix-chars", Fbackward_prefix_chars, Sbackward_prefix_chars,
X    0, 0, 0,
X!   "Move point backward over any number of chars with syntax \"prefix\".")
X    ()
X  {
X    int beg = BEGV;
X    int pos = point;
X  
X!   while (pos > beg && !char_quoted (pos - 1) && SYNTAX (FETCH_CHAR (pos - 1)) == Squote)
X      pos--;
X  
X    SET_PT (pos);
X--- 1389,1404 ----
X  
X  DEFUN ("backward-prefix-chars", Fbackward_prefix_chars, Sbackward_prefix_chars,
X    0, 0, 0,
X!   "Move point backward over any number of chars with prefix syntax.\n\
X! This includes chars with \"quote\" or \"prefix\" syntax (' or p).")
X    ()
X  {
X    int beg = BEGV;
X    int pos = point;
X  
X!   while (pos > beg && !char_quoted (pos - 1)
X! 	 && (SYNTAX (FETCH_CHAR (pos - 1)) == Squote
X! 	     || SYNTAX_PREFIX (FETCH_CHAR (pos - 1))))
X      pos--;
X  
X    SET_PT (pos);
X***************
X*** 775,800 ****
X    return Qnil;
X  }
X  
X- struct lisp_parse_state
X-   {
X-     int depth;		/* Depth at end of parsing */
X-     int instring;	/* -1 if not within string, else desired terminator. */
X-     int incomment;	/* Nonzero if within a comment at end of parsing */
X-     int quoted;		/* Nonzero if just after an escape char at end of parsing */
X-     int thislevelstart;	/* Char number of most recent start-of-expression at current level */
X-     int prevlevelstart; /* Char number of start of containing expression */
X-     int location;	/* Char number at which parsing stopped. */
X-     int mindepth;	/* Minimum depth seen while scanning.  */
X-   };
X- 
X  /* Parse forward from FROM to END,
X     assuming that FROM is the start of a function, 
X     and return a description of the state of the parse at END. */
X  
X! struct lisp_parse_state val_scan_sexps_forward;
X! 
X! struct lisp_parse_state *
X! scan_sexps_forward (from, end, targetdepth, stopbefore, oldstate)
X       register int from;
X       int end, targetdepth, stopbefore;
X       Lisp_Object oldstate;
X--- 1406,1418 ----
X    return Qnil;
X  }
X  
X  /* Parse forward from FROM to END,
X     assuming that FROM is the start of a function, 
X     and return a description of the state of the parse at END. */
X  
X! static void
X! scan_sexps_forward (stateptr, from, end, targetdepth, stopbefore, oldstate)
X!      struct lisp_parse_state *stateptr;
X       register int from;
X       int end, targetdepth, stopbefore;
X       Lisp_Object oldstate;
X***************
X*** 813,818 ****
X--- 1431,1437 ----
X    int mindepth;		/* Lowest DEPTH value seen.  */
X    int start_quoted = 0;		/* Nonzero means starting after a char quote */
X    Lisp_Object tem;
X+   int mask;				     /* comment mask */
X  
X    immediate_quit = 1;
X    QUIT;
X***************
X*** 822,827 ****
X--- 1441,1448 ----
X        depth = 0;
X        state.instring = -1;
X        state.incomment = 0;
X+       state.comstyle = 0;	/* default comstyle is a */
X+       mask = SYNTAX_COMMENT_STYLE_A;
X      }
X    else
X      {
X***************
X*** 844,849 ****
X--- 1465,1479 ----
X        oldstate = Fcdr (oldstate);
X        tem = Fcar (oldstate);
X        start_quoted = !NULL (tem);
X+ 
X+       /* if eighth element of the list is nil, we are in comment style
X+ 	 a. if it is non-nil, we are in comment style b */
X+       oldstate = Fcdr (oldstate);
X+       oldstate = Fcdr (oldstate);
X+       oldstate = Fcdr (oldstate);
X+       tem = Fcar (oldstate);
X+       state.comstyle = !NULL (tem);
X+       mask = state.comstyle ? SYNTAX_COMMENT_STYLE_B : SYNTAX_COMMENT_STYLE_A;
X      }
X    state.quoted = 0;
X    mindepth = depth;
X***************
X*** 863,873 ****
X  
X    while (from < end)
X      {
X!       code = SYNTAX(FETCH_CHAR (from));
X        from++;
X!       if (from < end && SYNTAX_COMSTART_FIRST (FETCH_CHAR (from - 1))
X! 	   && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from)))
X! 	code = Scomment, from++;
X  #ifdef SWITCH_ENUM_BUG
X        switch ((int) code)
X  #else
X--- 1493,1526 ----
X  
X    while (from < end)
X      {
X!       code = SYNTAX (FETCH_CHAR (from));
X        from++;
X! 
X!       if (code == Scomment)
X! 	{
X! 	  /* record the comment style we have entered so that only the
X! 	     comment-ender sequence (or single char) of the same style
X! 	     actually terminates the comment section. */
X! 	  mask = SYNTAX_COMMENT_1CHAR_MASK (FETCH_CHAR (from-1));
X! 	  state.comstyle = (mask == SYNTAX_COMMENT_STYLE_B);
X! 	  state.comstart = from-1;
X! 	}
X!       
X!       else if (from < end &&
X! 	       SYNTAX_START_P (FETCH_CHAR (from-1), FETCH_CHAR (from)))
X! 	{
X! 	  /* Record the comment style we have entered so that only
X! 	     the comment-end sequence of the same style actually
X! 	     terminates the comment section.  */
X! 	  code = Scomment;
X! 	  mask = SYNTAX_COMMENT_MASK_START (FETCH_CHAR (from-1), FETCH_CHAR (from));
X! 	  state.comstyle = (mask == SYNTAX_COMMENT_STYLE_B);
X! 	  state.comstart = from-1;
X! 	  from++;
X! 	}
X! 
X!       if (SYNTAX_PREFIX (FETCH_CHAR (from - 1)))
X! 	continue;
X  #ifdef SWITCH_ENUM_BUG
X        switch ((int) code)
X  #else
X***************
X*** 891,899 ****
X  	  while (from < end)
X  	    {
X  #ifdef SWITCH_ENUM_BUG
X! 	      switch ((int) SYNTAX(FETCH_CHAR (from)))
X  #else
X! 	      switch (SYNTAX(FETCH_CHAR (from)))
X  #endif
X  		{
X  		case Scharquote:
X--- 1544,1552 ----
X  	  while (from < end)
X  	    {
X  #ifdef SWITCH_ENUM_BUG
X! 	      switch ((int) SYNTAX (FETCH_CHAR (from)))
X  #else
X! 	      switch (SYNTAX (FETCH_CHAR (from)))
X  #endif
X  		{
X  		case Scharquote:
X***************
X*** 917,933 ****
X  	case Scomment:
X  	  state.incomment = 1;
X  	startincomment:
X! 	  while (1)
X! 	    {
X! 	      if (from == end) goto done;
X! 	      if (SYNTAX (prev = FETCH_CHAR (from)) == Sendcomment)
X! 		break;
X! 	      from++;
X! 	      if (from < end && SYNTAX_COMEND_FIRST (prev)
X! 		   && SYNTAX_COMEND_SECOND (FETCH_CHAR (from)))
X! 		{ from++; break; }
X! 	    }
X  	  state.incomment = 0;
X  	  break;
X  
X  	case Sopen:
X--- 1570,1588 ----
X  	case Scomment:
X  	  state.incomment = 1;
X  	startincomment:
X! 	  {
X! 	    int newfrom = find_end_of_comment (from, end, mask);
X! 	    if (newfrom < 0)
X! 	      {
X! 		/* we terminated search because from == end */
X! 		from = end;
X! 		goto done;
X! 	      }
X! 	    from = newfrom;
X! 	  }
X  	  state.incomment = 0;
X+ 	  state.comstyle = 0;		     /* reset the comment style */
X+ 	  mask = 0;
X  	  break;
X  
X  	case Sopen:
X***************
X*** 962,970 ****
X  	      if (from >= end) goto done;
X  	      if (FETCH_CHAR (from) == state.instring) break;
X  #ifdef SWITCH_ENUM_BUG
X! 	      switch ((int) SYNTAX(FETCH_CHAR (from)))
X  #else
X! 	      switch (SYNTAX(FETCH_CHAR (from)))
X  #endif
X  		{
X  		case Scharquote:
X--- 1617,1625 ----
X  	      if (from >= end) goto done;
X  	      if (FETCH_CHAR (from) == state.instring) break;
X  #ifdef SWITCH_ENUM_BUG
X! 	      switch ((int) SYNTAX (FETCH_CHAR (from)))
X  #else
X! 	      switch (SYNTAX (FETCH_CHAR (from)))
X  #endif
X  		{
X  		case Scharquote:
X***************
X*** 1001,1008 ****
X    state.location = from;
X    immediate_quit = 0;
X  
X!   val_scan_sexps_forward = state;
X!   return &val_scan_sexps_forward;
X  }
X  
X  /* This comment supplies the doc string for parse-partial-sexp,
X--- 1656,1662 ----
X    state.location = from;
X    immediate_quit = 0;
X  
X!   *stateptr = state;
X  }
X  
X  /* This comment supplies the doc string for parse-partial-sexp,
X***************
X*** 1009,1021 ****
X     for make-docfile to see.  We cannot put this in the real DEFUN
X     due to limits in the Unix cpp.
X  
X! DEFUN ("parse-partial-sexp", Ffoo, Sfoo, 0, 0, 0,
X    "Parse Lisp syntax starting at FROM until TO; return status of parse at TO.\n\
X  Parsing stops at TO or when certain criteria are met;\n\
X   point is set to where parsing stops.\n\
X  If fifth arg STATE is omitted or nil,\n\
X   parsing assumes that FROM is the beginning of a function.\n\
X! Value is a list of seven elements describing final state of parsing:\n\
X   1. depth in parens.\n\
X   2. character address of start of innermost containing list; nil if none.\n\
X   3. character address of start of last complete sexp terminated.\n\
X--- 1663,1675 ----
X     for make-docfile to see.  We cannot put this in the real DEFUN
X     due to limits in the Unix cpp.
X  
X! DEFUN ("parse-partial-sexp", Ffoo, Sfoo, 2, 5, 0,
X    "Parse Lisp syntax starting at FROM until TO; return status of parse at TO.\n\
X  Parsing stops at TO or when certain criteria are met;\n\
X   point is set to where parsing stops.\n\
X  If fifth arg STATE is omitted or nil,\n\
X   parsing assumes that FROM is the beginning of a function.\n\
X! Value is a list of eight elements describing final state of parsing:\n\
X   1. depth in parens.\n\
X   2. character address of start of innermost containing list; nil if none.\n\
X   3. character address of start of last complete sexp terminated.\n\
X***************
X*** 1024,1029 ****
X--- 1678,1684 ----
X   5. t if inside a comment.\n\
X   6. t if following a quote character.\n\
X   7. the minimum paren-depth encountered during this scan.\n\
X+  8. nil if in comment style a, or not in a comment; t if in comment style b\n\
X  If third arg TARGETDEPTH is non-nil, parsing stops if the depth\n\
X  in parentheses becomes equal to TARGETDEPTH.\n\
X  Fourth arg STOPBEFORE non-nil means stop when come to\n\
X***************
X*** 1030,1036 ****
X   any character that starts a sexp.\n\
X  Fifth arg STATE is a seven-list like what this function returns.\n\
X  It is used to initialize the state of the parse.")
X! 
X  */
X  
X  DEFUN ("parse-partial-sexp", Fparse_partial_sexp, Sparse_partial_sexp, 2, 5, 0,
X--- 1685,1691 ----
X   any character that starts a sexp.\n\
X  Fifth arg STATE is a seven-list like what this function returns.\n\
X  It is used to initialize the state of the parse.")
X!   (from, to, targetdepth, stopbefore, oldstate)
X  */
X  
X  DEFUN ("parse-partial-sexp", Fparse_partial_sexp, Sparse_partial_sexp, 2, 5, 0,
X***************
X*** 1050,1057 ****
X      target = -100000;		/* We won't reach this depth */
X  
X    validate_region (&from, &to);
X!   state = *scan_sexps_forward (XINT (from), XINT (to),
X! 			       target, !NULL (stopbefore), oldstate);
X  
X    SET_PT (state.location);
X    
X--- 1705,1712 ----
X      target = -100000;		/* We won't reach this depth */
X  
X    validate_region (&from, &to);
X!   scan_sexps_forward (&state, XINT (from), XINT (to),
X! 		      target, !NULL (stopbefore), oldstate);
X  
X    SET_PT (state.location);
X    
X***************
X*** 1061,1069 ****
X  	       Fcons (state.instring >= 0 ? make_number (state.instring) : Qnil,
X  		 Fcons (state.incomment ? Qt : Qnil,
X  		   Fcons (state.quoted ? Qt : Qnil,
X! 			  Fcons (make_number (state.mindepth), Qnil)))))));
X  }
X  
X  init_syntax_once ()
X  {
X    register int i;
X--- 1716,1727 ----
X  	       Fcons (state.instring >= 0 ? make_number (state.instring) : Qnil,
X  		 Fcons (state.incomment ? Qt : Qnil,
X  		   Fcons (state.quoted ? Qt : Qnil,
X! 		     Fcons (make_number (state.mindepth), 
X! 		       Fcons (state.comstyle ? Qt : Qnil,
X! 			    Qnil))))))));
X  }
X  
X+ void
X  init_syntax_once ()
X  {
X    register int i;
X***************
X*** 1102,1107 ****
X--- 1760,1766 ----
X      XFASTINT (v->contents[".,;:?!#@~^'`"[i]]) = (int) Spunct;
X  }
X  
X+ void
X  syms_of_syntax ()
X  {
X    Qsyntax_table_p = intern ("syntax-table-p");
X***************
X*** 1108,1119 ****
X    staticpro (&Qsyntax_table_p);
X  
X    DEFVAR_BOOL ("parse-sexp-ignore-comments", &parse_sexp_ignore_comments,
X!     "Non-nil means forward-sexp, etc., should treat comments as whitespace.\n\
X! Non-nil works only when the comment terminator is something like *\/,\n\
X! and appears only when it ends a comment.\n\
X! If comments are terminated by newlines,\n\
X! you must make this variable nil.");
X  
X    defsubr (&Ssyntax_table_p);
X    defsubr (&Ssyntax_table);
X    defsubr (&Sstandard_syntax_table);
X--- 1767,1778 ----
X    staticpro (&Qsyntax_table_p);
X  
X    DEFVAR_BOOL ("parse-sexp-ignore-comments", &parse_sexp_ignore_comments,
X!     "Non-nil means `forward-sexp', etc., should treat comments as whitespace.");
X  
X+   words_include_escapes = 0;
X+   DEFVAR_BOOL ("words-include-escapes", &words_include_escapes,
X+     "Non-nil means `forward-word', etc., should treat escape chars part of words.");
X+ 
X    defsubr (&Ssyntax_table_p);
X    defsubr (&Ssyntax_table);
X    defsubr (&Sstandard_syntax_table);
X***************
X*** 1124,1132 ****
X--- 1783,1793 ----
X    defsubr (&Sdescribe_syntax);
X  
X    defsubr (&Sforward_word);
X+   defsubr (&Sforward_comment);
X  
X    defsubr (&Sscan_lists);
X    defsubr (&Sscan_sexps);
X    defsubr (&Sbackward_prefix_chars);
X+ 
X    defsubr (&Sparse_partial_sexp);
X  }
X*** syntax.h@@/18.59	Sat Sep 12 00:20:52 1992
X--- syntax.h	Wed May 19 17:14:37 1993
X***************
X*** 1,11 ****
X  /* Declarations having to do with GNU Emacs syntax tables.
X!    Copyright (C) 1985 Free Software Foundation, Inc.
X  
X  This file is part of GNU Emacs.
X  
X  GNU Emacs is free software; you can redistribute it and/or modify
X  it under the terms of the GNU General Public License as published by
X! the Free Software Foundation; either version 1, or (at your option)
X  any later version.
X  
X  GNU Emacs is distributed in the hope that it will be useful,
X--- 1,11 ----
X  /* Declarations having to do with GNU Emacs syntax tables.
X!    Copyright (C) 1985, 1992, 1993 Free Software Foundation, Inc.
X  
X  This file is part of GNU Emacs.
X  
X  GNU Emacs is free software; you can redistribute it and/or modify
X  it under the terms of the GNU General Public License as published by
X! the Free Software Foundation; either version 2, or (at your option)
X  any later version.
X  
X  GNU Emacs is distributed in the hope that it will be useful,
X***************
X*** 17,22 ****
X--- 17,24 ----
X  along with GNU Emacs; see the file COPYING.  If not, write to
X  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
X  
X+ #ifndef _EMACS_SYNTAX_H_
X+ #define _EMACS_SYNTAX_H_
X  
X  extern Lisp_Object Qsyntax_table_p;
X  extern Lisp_Object Fsyntax_table_p (), Fsyntax_table (), Fset_syntax_table ();
X***************
X*** 25,33 ****
X     be used in all new buffers.  */
X  #define Vstandard_syntax_table buffer_defaults.syntax_table
X  
X  /* A syntax table is a Lisp vector of length 0400, whose elements are integers.
X  
X! The low 8 bits of the integer is a code, as follows:
X  */
X  
X  enum syntaxcode
X--- 27,37 ----
X     be used in all new buffers.  */
X  #define Vstandard_syntax_table buffer_defaults.syntax_table
X  
X+ 
X  /* A syntax table is a Lisp vector of length 0400, whose elements are integers.
X  
X! The low 7 bits of the integer is a code, as follows. The 8th bit is
X! used as the prefix bit flag (see below).
X  */
X  
X  enum syntaxcode
X***************
X*** 49,84 ****
X    };
X  
X  #define SYNTAX(c) \
X!   ((enum syntaxcode) (XINT (XVECTOR (current_buffer->syntax_table)->contents[(unsigned char) (c)]) & 0377))
X  
X  /* The next 8 bits of the number is a character,
X   the matching delimiter in the case of Sopen or Sclose. */
X  
X  #define SYNTAX_MATCH(c) \
X!   ((XINT (XVECTOR (current_buffer->syntax_table)->contents[(unsigned char) (c)]) >> 8) & 0377)
X  
X! /* Then there are four single-bit flags that have the following meanings:
X!   1. This character is the first of a two-character comment-start sequence.
X!   2. This character is the second of a two-character comment-start sequence.
X!   3. This character is the first of a two-character comment-end sequence.
X!   4. This character is the second of a two-character comment-end sequence.
X!  Note that any two-character sequence whose first character has flag 1
X!   and whose second character has flag 2 will be interpreted as a comment start. */
X  
X! #define SYNTAX_COMSTART_FIRST(c) \
X!   ((XINT (XVECTOR (current_buffer->syntax_table)->contents[(unsigned char) (c)]) >> 16) & 1)
X  
X! #define SYNTAX_COMSTART_SECOND(c) \
X!   ((XINT (XVECTOR (current_buffer->syntax_table)->contents[(unsigned char) (c)]) >> 17) & 1)
X  
X! #define SYNTAX_COMEND_FIRST(c) \
X!   ((XINT (XVECTOR (current_buffer->syntax_table)->contents[(unsigned char) (c)]) >> 18) & 1)
X  
X! #define SYNTAX_COMEND_SECOND(c) \
X!   ((XINT (XVECTOR (current_buffer->syntax_table)->contents[(unsigned char) (c)]) >> 19) & 1)
X  
X  /* This array, indexed by a character, contains the syntax code which that
X   character signifies (as a char).  For example,
X   (enum syntaxcode) syntax_spec_code['w'] is Sword. */
X  
X  extern unsigned char syntax_spec_code[0400];
X--- 53,156 ----
X    };
X  
X  #define SYNTAX(c) \
X!   ((enum syntaxcode) (XINT (XVECTOR (current_buffer->syntax_table)->contents[(unsigned char) (c)]) & 0177))
X  
X+ /* If emacs was compiled with the NEW_SYNTAX flag, then the prefix
X+    flag bit for backward-prefix-chars is put into bit 7. */
X+ #define SYNTAX_PREFIX(c) \
X+   ((XUINT (XVECTOR (current_buffer->syntax_table)->contents[(unsigned char) (c)]) >> 7) & 1)
X+ 
X  /* The next 8 bits of the number is a character,
X   the matching delimiter in the case of Sopen or Sclose. */
X  
X  #define SYNTAX_MATCH(c) \
X!   ((XUINT (XVECTOR (current_buffer->syntax_table)->contents[(unsigned char) (c)]) >> 8) & 0377)
X  
X! /* The next 8 bits are used to implement up to two comment styles
X!    in a single buffer. They have the following meanings:
X  
X!   1. first of a one or two character comment-start sequence of style a.
X!   2. first of a one or two character comment-start sequence of style b.
X!   3. second of a two-character comment-start sequence of style a.
X!   4. second of a two-character comment-start sequence of style b.
X!   5. first of a one or two character comment-end sequence of style a.
X!   6. first of a one or two character comment-end sequence of style b.
X!   7. second of a two-character comment-end sequence of style a.
X!   8. second of a two-character comment-end sequence of style b.
X!  */
X  
X! #define SYNTAX_COMMENT_BITS(c) \
X!   ((XUINT (XVECTOR (current_buffer->syntax_table)->contents[(unsigned int) (c)]) >> 16) &0xff)
X  
X! #define SYNTAX_FIRST_OF_START_A  0x80
X! #define SYNTAX_FIRST_OF_START_B  0x40
X! #define SYNTAX_SECOND_OF_START_A 0x20
X! #define SYNTAX_SECOND_OF_START_B 0x10
X! #define SYNTAX_FIRST_OF_END_A    0x08
X! #define SYNTAX_FIRST_OF_END_B    0x04
X! #define SYNTAX_SECOND_OF_END_A   0x02
X! #define SYNTAX_SECOND_OF_END_B   0x01
X  
X! #define SYNTAX_COMMENT_STYLE_A   0xaa
X! #define SYNTAX_COMMENT_STYLE_B   0x55
X! #define SYNTAX_FIRST_CHAR_START  0xc0
X! #define SYNTAX_FIRST_CHAR_END    0x0c
X! #define SYNTAX_FIRST_CHAR        0xcc
X! #define SYNTAX_SECOND_CHAR_START 0x30
X! #define SYNTAX_SECOND_CHAR_END   0x03
X! #define SYNTAX_SECOND_CHAR       0x33
X  
X+ #define SYNTAX_START_P(a,b) \
X+ ((SYNTAX_COMMENT_BITS(a)&SYNTAX_FIRST_CHAR_START) \
X+  &&(SYNTAX_COMMENT_BITS(b)&SYNTAX_SECOND_CHAR_START))
X+ 
X+ #define SYNTAX_END_P(a,b) \
X+ ((SYNTAX_COMMENT_BITS(a)&SYNTAX_FIRST_CHAR_END) \
X+  &&(SYNTAX_COMMENT_BITS(b)&SYNTAX_SECOND_CHAR_END))
X+ 
X+ #define SYNTAX_STYLES_MATCH_START_P(a,b,mask) \
X+ ((SYNTAX_COMMENT_BITS(a)&SYNTAX_FIRST_CHAR_START&(mask)) \
X+  &&(SYNTAX_COMMENT_BITS(b)&SYNTAX_SECOND_CHAR_START&(mask)))
X+ 
X+ #define SYNTAX_STYLES_MATCH_END_P(a,b,mask) \
X+ ((SYNTAX_COMMENT_BITS(a)&SYNTAX_FIRST_CHAR_END&(mask)) \
X+  &&(SYNTAX_COMMENT_BITS(b)&SYNTAX_SECOND_CHAR_END&(mask)))
X+ 
X+ #define SYNTAX_STYLES_MATCH_1CHAR_P(a,mask) \
X+ ((SYNTAX_COMMENT_BITS(a)&(mask)))
X+ 
X+ #define STYLE_FOUND_P(a,b,startp,style) \
X+ ((SYNTAX_COMMENT_BITS(a) & \
X+   ((startp) ? SYNTAX_FIRST_CHAR_START : SYNTAX_FIRST_CHAR_END) & (style)) \
X+  &&(SYNTAX_COMMENT_BITS(b) & \
X+ 	((startp) ? SYNTAX_SECOND_CHAR_START : SYNTAX_SECOND_CHAR_END) &(style)))
X+ 
X+ #define SYNTAX_COMMENT_MASK_START(a,b) \
X+ ((STYLE_FOUND_P((a),(b),1,SYNTAX_COMMENT_STYLE_A) ? SYNTAX_COMMENT_STYLE_A \
X+   : (STYLE_FOUND_P((a),(b),1,SYNTAX_COMMENT_STYLE_B) ? SYNTAX_COMMENT_STYLE_B \
X+ 	 : 0)))
X+ 
X+ #define SYNTAX_COMMENT_MASK_END(a,b) \
X+ ((STYLE_FOUND_P((a),(b),0,SYNTAX_COMMENT_STYLE_A) ? SYNTAX_COMMENT_STYLE_A \
X+   : (STYLE_FOUND_P((a),(b),0,SYNTAX_COMMENT_STYLE_B) ? SYNTAX_COMMENT_STYLE_B \
X+ 	 : 0)))
X+ 
X+ #define STYLE_FOUND_1CHAR_P(a,style) \
X+ ((SYNTAX_COMMENT_BITS(a)&(style)))
X+ 
X+ #define SYNTAX_COMMENT_1CHAR_MASK(a) \
X+ ((STYLE_FOUND_1CHAR_P((a),SYNTAX_COMMENT_STYLE_A) ? SYNTAX_COMMENT_STYLE_A \
X+   : (STYLE_FOUND_1CHAR_P((a),SYNTAX_COMMENT_STYLE_B) ? SYNTAX_COMMENT_STYLE_B \
X+ 	 : 0)))
X+ 
X  /* This array, indexed by a character, contains the syntax code which that
X   character signifies (as a char).  For example,
X   (enum syntaxcode) syntax_spec_code['w'] is Sword. */
X  
X  extern unsigned char syntax_spec_code[0400];
X+ 
X+ /* Indexed by syntax code, give the letter that describes it. */
X+ 
X+ extern unsigned char syntax_code_spec[13];
X+ 
X+ #endif /* _EMACS_SYNTAX_H_ */
X
X
END_OF_FILE
if test 62612 -ne `wc -c <'syntax.18.59.GNU'`; then
    echo shar: \"'syntax.18.59.GNU'\" unpacked with wrong size!
fi
# end of 'syntax.18.59.GNU'
fi
if test -f 'syntax.MULE-0.9.8' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'syntax.MULE-0.9.8'\"
else
echo shar: Extracting \"'syntax.MULE-0.9.8'\" \(49926 characters\)
sed "s/^X//" >'syntax.MULE-0.9.8' <<'END_OF_FILE'
X--- orig/syntax.c	Tue Jun 15 08:08:46 1993
X+++ syntax.c	Wed Jun 16 14:34:41 1993
X@@ -1,11 +1,11 @@
X /* GNU Emacs routines to deal with syntax tables; also word and list parsing.
X-   Copyright (C) 1985, 1987, 1990 Free Software Foundation, Inc.
X+   Copyright (C) 1985-1993 Free Software Foundation, Inc.
X 
X This file is part of GNU Emacs.
X 
X GNU Emacs is free software; you can redistribute it and/or modify
X it under the terms of the GNU General Public License as published by
X-the Free Software Foundation; either version 1, or (at your option)
X+the Free Software Foundation; either version 2, or (at your option)
X any later version.
X 
X GNU Emacs is distributed in the hope that it will be useful,
X@@ -44,27 +44,118 @@
X #include "regex.h"		/* 92.7.17 by K.Handa */
X #include "mule.h"		/* 91.12.22 by K.Handa */
X 
X+/* Equivalent macro, extern names (v.19 == v.18):
X+   NILP(obj)			== NULL(obj)
X+   VECTORP(obj)			== (XTYPE(obj)==Lisp_Vector)
X+   FIXNUMP(obj)			== (XTYPE(obj)==Lisp_Int)
X+   CHECK_FIXNUM(a,b)		== CHECK_NUMBER(a,b)
X+   insert_string(string)	== InsStr(string)
X+   insert_raw_string(s,l)	== insert(s,l)
X+   internal_set_buffer(b)	== set_buffer_internal(b)
X+   CHAR_AT(from)		== FETCH_CHAR(from)
X+*/
X+
X Lisp_Object Qsyntax_table_p;
X 
X+int words_include_escapes;
X+
X+/* There is an alist of syntax tables: names (strings) vs obarrays. */
X+
X+/* This is the internal form of the parse state used in parse-partial-sexp.  */
X+
X+struct lisp_parse_state
X+  {
X+    int depth;		/* Depth at end of parsing */
X+    int instring;	/* -1 if not within string, else desired terminator. */
X+    int incomment;	/* Nonzero if within a comment at end of parsing */
X+    int comstyle;	/* comment style a=0, or b=1 */
X+    int quoted;		/* Nonzero if just after an escape char at end of parsing */
X+    int thislevelstart;	/* Char number of most recent start-of-expression at current level */
X+    int prevlevelstart; /* Char number of start of containing expression */
X+    int location;	/* Char number at which parsing stopped. */
X+    int mindepth;	/* Minimum depth seen while scanning.  */
X+    int comstart;	/* Position just after last comment starter.  */
X+  };
X+
X+/* These variables are a cache for finding the start of a defun.
X+   find_start_pos is the place for which the defun start was found.
X+   find_start_value is the defun start position found for it.
X+   find_start_buffer is the buffer it was found in.
X+   find_start_begv is the BEGV value when it was found.
X+   find_start_modiff is the value of MODIFF when it was found.  */
X+
X+static int find_start_pos;
X+static int find_start_value;
X+static struct buffer *find_start_buffer;
X+static int find_start_begv;
X+static int find_start_modiff;
X+
X+/* Find a defun-start that is the last one before POS (or nearly the last).
X+   We record what we find, so that another call in the same area
X+   can return the same value right away.  */
X+
X+static int
X+find_defun_start (pos)
X+     int pos;
X+{
X+  int tem;
X+  int shortage;
X+
X+  /* Use previous finding, if it's valid and applies to this inquiry.  */
X+  if (current_buffer == find_start_buffer
X+      /* Reuse the defun-start even if POS is a little farther on.
X+	 POS might be in the next defun, but that's ok.
X+	 Our value may not be the best possible, but will still be usable.  */
X+      && pos <= find_start_pos + 1000
X+      && pos >= find_start_value
X+      && BEGV == find_start_begv
X+      && MODIFF == find_start_modiff)
X+    return find_start_value;
X+
X+  /* Back up to start of line.  */
X+  tem = scan_buffer ('\n', pos, -1, &shortage);
X+
X+  while (tem > BEGV)
X+    {
X+      int c;
X+
X+      /* Open-paren at start of line means we found our defun-start.  */
X+      FETCH_MC_CHAR (c, tem);
X+      if (SYNTAX (c) == Sopen)
X+	break;
X+      /* Move to beg of previous line.  */
X+      tem = scan_buffer ('\n', tem, -2, &shortage);
X+    }
X+
X+  /* Record what we found, for the next try.  */
X+  find_start_value = tem;
X+  find_start_buffer = current_buffer;
X+  find_start_modiff = MODIFF;
X+  find_start_begv = BEGV;
X+  find_start_pos = pos;
X+
X+  return find_start_value;
X+}
X+
X DEFUN ("syntax-table-p", Fsyntax_table_p, Ssyntax_table_p, 1, 1, 0,
X   "Return t if ARG is a syntax table.\n\
X Any vector of 256 elements will do.")
X   (obj)
X      Lisp_Object obj;
X {
X-  if (XTYPE (obj) == Lisp_Vector && XVECTOR (obj)->size == 0400)
X+  if ((XTYPE (obj) == Lisp_Vector) && XVECTOR (obj)->size == 0400)
X     return Qt;
X   return Qnil;
X }
X 
X-Lisp_Object
X+static Lisp_Object
X check_syntax_table (obj)
X      Lisp_Object obj;
X {
X   register Lisp_Object tem;
X   while (tem = Fsyntax_table_p (obj),
X 	 NULL (tem))
X-    obj = wrong_type_argument (Qsyntax_table_p, obj, 0);
X+    obj = wrong_type_argument (Qsyntax_table_p, obj);
X   return obj;
X }   
X 
X@@ -138,7 +229,8 @@
X   table = check_syntax_table (table);
X   current_buffer->syntax_table = table;
X   /* Indicate that this buffer now has a specified syntax table.  */
X-  current_buffer->local_var_flags |= buffer_local_flags.syntax_table;
X+  current_buffer->local_var_flags |=
X+    XFASTINT (buffer_local_flags.syntax_table);
X   return table;
X }
X 
X@@ -171,7 +263,7 @@
X 
X /* Indexed by syntax code, give the letter that describes it. */
X 
X-char syntax_code_spec[14] =	/* 92.7.16 by K.Handa */
X+unsigned char syntax_code_spec[14] =	/* 92.7.16 by K.Handa */
X   {
X     ' ', '.', 'w', '_', '(', ')', '\'', '\"', '$', '\\', '/', '<', '>', 'e'
X   };
X@@ -250,9 +342,9 @@
X 
X DEFUN ("char-syntax", Fchar_syntax, Schar_syntax, 1, 1, 0,
X   "Return the syntax code of CHAR, described by a character.\n\
X-For example, if CHAR is a word constituent, ?w is returned.\n\
X+For example, if CHAR is a word constituent, the character `?w' is returned.\n\
X The characters that correspond to various syntax codes\n\
X-are listed in the documentation of  modify-syntax-entry.")
X+are listed in the documentation of `modify-syntax-entry'.")
X   (ch)
X      Lisp_Object ch;
X {				/* 92.1.10 by K.Handa */
X@@ -322,25 +414,34 @@
X The syntax is changed only for table TABLE, which defaults to\n\
X  the current buffer's syntax table.\n\
X The first character of S should be one of the following:\n\
X-  Space or -   whitespace syntax.    w   word constituent.\n\
X-  _            symbol constituent.   .   punctuation.\n\
X-  (            open-parenthesis.     )   close-parenthesis.\n\
X-  \"            string quote.         \\   escape character.\n\
X-  $            paired delimiter.     '   expression prefix operator.\n\
X-  <            comment starter.      >   comment ender.\n\
X-  /	       character quote.\n\
X+  Space    whitespace syntax.    w   word constituent.\n\
X+  _        symbol constituent.   .   punctuation.\n\
X+  (        open-parenthesis.     )   close-parenthesis.\n\
X+  \"        string quote.         \\   character-quote.\n\
X+  $        paired delimiter.     '   expression quote or prefix operator.\n\
X+  <	   comment starter.	 >   comment ender.\n\
X Only single-character comment start and end sequences are represented thus.\n\
X Two-character sequences are represented as described below.\n\
X The second character of S is the matching parenthesis,\n\
X- used only if the first character is ( or ).\n\
X+ used only if the first character is `(' or `)'.\n\
X If CHAR is a multilingual character,\n\
X  it should be the same as CHAR except for the last byte.\n\
X Any additional characters are flags.\n\
X-Defined flags are the characters 1, 2, 3 and 4.\n\
X- 1 means C is the start of a two-char comment start sequence.\n\
X+Defined flags are the characters 1, 2, 3, 4, 5, 6, 7, 8, p, a, and b.\n\
X+ 1 means C is the first of a two-char comment start sequence of style a.\n\
X  2 means C is the second character of such a sequence.\n\
X- 3 means C is the start of a two-char comment end sequence.\n\
X- 4 means C is the second character of such a sequence.")\n\
X+ 3 means C is the first of a two-char comment end sequence of style a.\n\
X+ 4 means C is the second character of such a sequence.\n\
X+ 5 means C is the first of a two-char comment start sequence of style b.\n\
X+ 6 means C is the second character of such a sequence.\n\
X+ 7 means C is the first of a two-char comment end sequence of style b.\n\
X+ 8 means C is the second character of such a sequence.\n\
X+ p means C is a prefix character for `backward-prefix-chars';\n\
X+   such characters are treated as whitespace when they occur\n\
X+   between expressions.\n\
X+ a means C is comment starter or comment ender for comment style a (default)\n\
X+ b means C is comment starter or comment ender for comment style b.")
X+  (c, newentry, syntax_table)
X */
X 
X /* 92.12.22 by M.Higashida */
X@@ -356,6 +457,7 @@
X   register unsigned char *p, match;
X   register enum syntaxcode code;
X   Lisp_Object val;
X+  int b_flag_seen_p = 0;
X 
X   CHECK_CHARACTER (c, 0);	/* 92.1.10 by K.Handa */
X   CHECK_STRING (newentry, 1);
X@@ -378,38 +480,85 @@
X   if (match == ' ') match = 0;
X 
X   XFASTINT (val) = (match << 8) + (int) code;
X+
X   while (*p)
X     switch (*p++)
X       {
X       case '1':
X-	XFASTINT (val) |= 1 << 16;
X+	XFASTINT (val) |= SYNTAX_FIRST_OF_START_A << 16;
X 	break;
X 
X       case '2':
X-	XFASTINT (val) |= 1 << 17;
X+	XFASTINT (val) |= SYNTAX_SECOND_OF_START_A << 16;
X 	break;
X 
X       case '3':
X-	XFASTINT (val) |= 1 << 18;
X+	XFASTINT (val) |= SYNTAX_FIRST_OF_END_A << 16;
X 	break;
X 
X       case '4':
X-	XFASTINT (val) |= 1 << 19;
X+	XFASTINT (val) |= SYNTAX_SECOND_OF_END_A << 16;
X+	break;
X+
X+      case '5':
X+	XFASTINT (val) |= SYNTAX_FIRST_OF_START_B << 16;
X+	break;
X+
X+      case '6':
X+	XFASTINT (val) |= SYNTAX_SECOND_OF_START_B << 16;
X+	break;
X+
X+      case '7':
X+	XFASTINT (val) |= SYNTAX_FIRST_OF_END_B << 16;
X 	break;
X+
X+      case '8':
X+	XFASTINT (val) |= SYNTAX_SECOND_OF_END_B << 16;
X+	break;
X+
X+      case 'a':
X+	if (code == Scomment)
X+	  XFASTINT (val) |= SYNTAX_FIRST_OF_START_A << 16;
X+	else if (code == Sendcomment)
X+	  XFASTINT (val) |= SYNTAX_FIRST_OF_END_A << 16;
X+
X+	break;
X+
X+      case 'b':
X+	if (code == Scomment)
X+	  XFASTINT (val) |= SYNTAX_FIRST_OF_START_B << 16;
X+	else if (code == Sendcomment)
X+	  XFASTINT (val) |= SYNTAX_FIRST_OF_END_B << 16;
X+
X+	b_flag_seen_p = 1;
X+	break;
X+
X+      case 'p':
X+	XFASTINT (val) |= 1 << 7;
X+	break;
X       }
X 	
X+  /* default single char style is a if b has not been seen */
X+  if (!b_flag_seen_p)
X+    if (code == Scomment)
X+      XFASTINT (val) |= SYNTAX_FIRST_OF_START_A << 16;
X+    else if (code == Sendcomment)
X+      XFASTINT (val) |= SYNTAX_FIRST_OF_END_A << 16;
X+
X   modify_syntax_entry(c, syntax_table, val); /* 92.1.10 by K.Handa */
X   return Qnil;
X }
X 
X /* Dump syntax table to buffer in human-readable format */
X 
X+static void
X describe_syntax (value, indent)	/* 93.6.7 by K.Handa */
X      Lisp_Object value;
X      int indent;
X {
X   register enum syntaxcode code;
X-  char desc, match, start1, start2, end1, end2;
X+  char desc, match, start1, start2, end1, end2, prefix;
X+  char start1b, start2b, end1b, end2b;
X   char str[2];
X 
X   Findent_to (make_number (indent + 16), make_number (1));
X@@ -421,7 +570,7 @@
X       return;
X     }
X 
X-  if (XTYPE (value) != Lisp_Int)
X+  if (!(XTYPE(value) == Lisp_Int))
X     {
X       InsStr ("invalid");
X       return;
X@@ -429,11 +578,17 @@
X 
X   code = (enum syntaxcode) (XINT (value) & 0377);
X   match = (XINT (value) >> 8) & 0377;
X-  start1 = (XINT (value) >> 16) & 1;
X-  start2 = (XINT (value) >> 17) & 1;
X-  end1 = (XINT (value) >> 18) & 1;
X-  end2 = (XINT (value) >> 19) & 1;
X 
X+  start1 = (XINT (value) >> 16) & SYNTAX_FIRST_OF_START_A;
X+  start2 = (XINT (value) >> 16) & SYNTAX_SECOND_OF_START_A;
X+  end1 = (XINT (value) >> 16) & SYNTAX_FIRST_OF_END_A;
X+  end2 = (XINT (value) >> 16) & SYNTAX_SECOND_OF_END_A;
X+  start1b = (XINT (value) >> 16) & SYNTAX_FIRST_OF_START_B;
X+  start2b = (XINT (value) >> 16) & SYNTAX_SECOND_OF_START_B;
X+  end1b = (XINT (value) >> 16) & SYNTAX_FIRST_OF_END_B;
X+  end2b = (XINT (value) >> 16) & SYNTAX_SECOND_OF_END_B;
X+  prefix = (XINT (value) >> 7) & 1;
X+
X   if ((int) code < 0 || (int) code >= (int) Smax)
X     {
X       InsStr ("invalid");
X@@ -447,17 +602,45 @@
X   str[0] = match ? match : ' ';
X   insert (str, 1);
X 
X-
X   if (start1)
X-    insert ("1", 1);
X+    if (code==Scomment)
X+      insert ("a", 1);
X+    else
X+      insert ("1", 1);
X+
X   if (start2)
X     insert ("2", 1);
X 
X   if (end1)
X-    insert ("3", 1);
X+    if (code==Sendcomment)
X+      insert ("a", 1);
X+    else
X+      insert ("3", 1);
X+
X   if (end2)
X     insert ("4", 1);
X 
X+  if (start1b)
X+    if (code==Scomment)
X+      insert ("b", 1);
X+    else
X+      insert ("5", 1);
X+
X+  if (start2b)
X+    insert ("6", 1);
X+
X+  if (end1b)
X+    if (code==Sendcomment)
X+      insert ("b", 1);
X+    else
X+      insert ("7", 1);
X+
X+  if (end2b)
X+    insert ("8", 1);
X+
X+  if (prefix)
X+    insert ("p", 1);
X+
X   InsStr ("\twhich means: ");
X 
X #ifdef SWITCH_ENUM_BUG
X@@ -508,15 +691,44 @@
X     }
X 
X   if (start1)
X-    InsStr (",\n\t  is the first character of a comment-start sequence");
X+    if (code==Scomment)
X+      InsStr (",\n\t  starts comment style-a");
X+    else
X+      InsStr (",\n\t  is the first char of a style-a, comment-start sequence");
X+
X   if (start2)
X-    InsStr (",\n\t  is the second character of a comment-start sequence");
X+    InsStr (",\n\t  is the second char of a style-a, comment-start sequence");
X 
X   if (end1)
X-    InsStr (",\n\t  is the first character of a comment-end sequence");
X+    if (code==Sendcomment)
X+      InsStr (",\n\t  ends comment style-a");
X+    else
X+      InsStr (",\n\t  is the first char of a style-a, comment-end sequence");
X+
X   if (end2)
X-    InsStr (",\n\t  is the second character of a comment-end sequence");
X+    InsStr (",\n\t  is the second char of a style-a, comment-end sequence");
X+
X+  if (start1b)
X+    if (code==Scomment)
X+      InsStr (",\n\t  starts comment style-b");
X+    else
X+      InsStr (",\n\t  is the first char of a style-b, comment-start sequence");
X+
X+  if (start2b)
X+    InsStr (",\n\t  is the second char of a style-b, comment-start sequence");
X+
X+  if (end1b)
X+    if (code==Sendcomment)
X+      InsStr (",\n\t  ends comment style-b");
X+    else
X+      InsStr (",\n\t  is the first char of a style-b, comment-end sequence");
X+
X+  if (end2b)
X+    InsStr (",\n\t  is the second char of a style-b, comment-end sequence");
X 
X+  if (prefix)
X+    InsStr (",\n\t  is a prefix character for `backward-prefix-chars'");
X+
X   InsStr ("\n");
X }
X 
X@@ -545,11 +757,15 @@
X   }
X }
X 
X-Lisp_Object
X+static Lisp_Object
X describe_syntax_1 (vector)
X      Lisp_Object vector;
X {
X   struct buffer *old = current_buffer;
X+  int i, size = XVECTOR (vector)->size, range_start = 0;
X+  Lisp_Object string, current_code = XVECTOR (vector)->contents[0];
X+  int top;
X+
X   set_buffer_internal (XBUFFER (Vstandard_output));
X   describe_syntax_2 (vector, 0); /* 93.6.7 by K.Handa */
X   set_buffer_internal (old);
X@@ -558,7 +774,7 @@
X 
X DEFUN ("describe-syntax", Fdescribe_syntax, Sdescribe_syntax, 0, 0, "",
X   "Describe the syntax specifications in the syntax table.\n\
X-The descriptions are inserted in a buffer, which is selected so you can see it.")
X+The descriptions are inserted in a buffer, which is then displayed.")
X   ()
X {
X   internal_with_output_to_temp_buffer
X@@ -567,10 +783,11 @@
X   return Qnil;
X }
X 
X-/* Return the position across `count' words from `from'.
X+/* Return the position across COUNT words from FROM.
X    If that many words cannot be found before the end of the buffer, return 0.
X    `count' negative means scan backward and stop at word beginning.  */
X 
X+int
X scan_words (from, count)
X      register int from, count;
X {
X@@ -579,6 +796,7 @@
X   register int temp;		/* 92.1.10 by K.Handa */
X   register unsigned int c;	/* 92.1.10 by K.Handa */
X   enum syntaxcode s;		/* 92.7.16 by K.Handa */
X+  enum syntaxcode code;
X 
X   immediate_quit = 1;
X   QUIT;
X@@ -593,8 +811,10 @@
X 	      return 0;
X 	    }
X 	  FETCH_MC_CHAR (c, from);
X-	  if ((s = SYNTAX(c)) == Sword
X-	      || s == Sextword) /* 92.7.16 by K.Handa */
X+	  s = SYNTAX (c);
X+	  if (words_include_escapes && (s == Sescape || s == Scharquote))
X+	    break;
X+	  if (s == Sword || s == Sextword) /* 92.7.16 by K.Handa */
X 	    break;
X 	  INC_POS (from);
X 	}
X@@ -602,9 +822,10 @@
X 	{
X 	  if (from == end) break;
X 	  FETCH_MC_CHAR (c, from);
X-	  if ((s = SYNTAX(c)) != Sword
X-	      && s != Sextword)	/* 92.7.16 by K.Handa */
X-	    break;
X+	  s = SYNTAX (c);
X+	  if (!(words_include_escapes && (s == Sescape || s == Scharquote)))
X+	    if (s != Sword && s != Sextword)	/* 92.7.16 by K.Handa */
X+	      break;
X 	  INC_POS (from);
X 	}
X       count--;
X@@ -621,9 +842,11 @@
X 	  temp = from;
X 	  DEC_POS (temp);
X 	  FETCH_MC_CHAR (c, temp);
X-	  if ((s = SYNTAX(c)) == Sword
X-	      || s == Sextword)	/* 92.7.16 by K.Handa */
X+	  s = SYNTAX (c);
X+	  if (words_include_escapes && (s == Sescape || s == Scharquote))
X 	    break;
X+	  if (s == Sword || s == Sextword)	/* 92.7.16 by K.Handa */
X+	    break;
X 	  from = temp;
X 	}
X       while (1)
X@@ -632,9 +855,10 @@
X 	  temp = from;
X 	  DEC_POS (temp);
X 	  FETCH_MC_CHAR (c, temp);
X-	  if ((s = SYNTAX(c)) != Sword
X-	      && s != Sextword)	/* 92.7.16 by K.Handa */
X-	    break;
X+	  s = SYNTAX (c);
X+	  if (!(words_include_escapes && (s == Sescape || s == Scharquote)))
X+	    if (s != Sword && s != Sextword)	/* 92.7.16 by K.Handa */
X+	      break;
X 	  from = temp;
X 	}
X       count++;
X@@ -685,8 +909,343 @@
X   return Qt;
X }
X 
X+static int char_quoted ();
X+static void scan_sexps_forward ();
X+
X+static int
X+find_start_of_comment (from, stop, mask)
X+    int from, stop, mask;
X+{
X+    int c, c1;
X+    int temp;
X+    enum syntaxcode code;
X+
X+    /* Look back, counting the parity of string-quotes,
X+       and recording the comment-starters seen.
X+       When we reach a safe place, assume that's not in a string;
X+       then step the main scan to the earliest comment-starter seen
X+       an even number of string quotes away from the safe place.
X+       
X+       OFROM[I] is position of the earliest comment-starter seen
X+       which is I+2X quotes from the comment-end.
X+       PARITY is current parity of quotes from the comment end.  */
X+    int parity = 0;
X+    char my_stringend = 0;
X+    int string_lossage = 0;
X+    int comment_end = from;
X+    int comstart_pos = 0;
X+    int comstart_parity = 0;
X+    int styles_match_p = 0;
X+
X+    /* At beginning of range to scan, we're outside of strings;
X+       that determines quote parity to the comment-end.  */
X+    while (from != stop)
X+      {
X+	/* Move back and examine a character.  */
X+	DEC_POS (from);
X+
X+	FETCH_MC_CHAR (c, from);
X+	code = SYNTAX (c);
X+
X+	temp = from;
X+	DEC_POS (temp);
X+	FETCH_MC_CHAR (c1, temp);
X+
X+	/* is this a 1-char comment end sequence? if so, try
X+	   to see if style matches previously extracted mask */
X+	if (code == Sendcomment)
X+	  {
X+	    styles_match_p = SYNTAX_STYLES_MATCH_1CHAR_P (c, mask);
X+	  }
X+
X+	/* otherwise, is this a 2-char comment end sequence?
X+	   if so, back up, and see if style matches previously
X+	   extracted mask */
X+	else if (from > stop && SYNTAX_END_P (c1, c))
X+	  {
X+	    code = Sendcomment;
X+	    styles_match_p = SYNTAX_STYLES_MATCH_END_P (c1, c, mask);
X+
X+	    from = temp;
X+	  }
X+			
X+	/* or are we looking at a 1-char comment start sequence
X+	   of the style matching mask? */
X+	else if (code == Scomment
X+		 && SYNTAX_STYLES_MATCH_1CHAR_P (c, mask))
X+	  {
X+	    styles_match_p = 1;
X+	  }
X+		    
X+	/* or possibly, a 2-char comment start sequence */
X+	else if (from > stop
X+		 && SYNTAX_STYLES_MATCH_START_P (c1, c, mask))
X+	  {
X+	    code = Scomment;
X+	    from = temp;
X+	    styles_match_p = 1;
X+	  }
X+
X+	/* Ignore escaped characters.  */
X+	if (char_quoted (from))
X+	  continue;
X+
X+	/* Track parity of quotes.  */
X+	if (code == Sstring)
X+	  {
X+	    parity ^= 1;
X+	    if (my_stringend == 0)
X+	      my_stringend = c;
X+	    /* If we have two kinds of string delimiters.
X+	       There's no way to grok this scanning backwards.  */
X+	    else if (my_stringend != c)
X+	      string_lossage = 1;
X+	  }
X+
X+	/* Record comment-starters according to that
X+	   quote-parity to the comment-end.  */
X+	if (code == Scomment && styles_match_p)
X+	  {
X+	    comstart_parity = parity;
X+	    comstart_pos = from;
X+	  }
X+
X+	/* If we find another earlier comment-ender,
X+	   any comment-starts earier than that don't count
X+	   (because they go with the earlier comment-ender).  */
X+	if (code == Sendcomment && styles_match_p)
X+	  break;
X+
X+	/* Assume a defun-start point is outside of strings.  */
X+	temp = from;
X+	DEC_POS (temp);
X+	FETCH_MC_CHAR (c1, temp);
X+	if (code == Sopen && (from == stop || c1 == '\n'))
X+	  break;
X+      }
X+
X+    if (comstart_pos == 0)
X+	from = comment_end;
X+    /* If the earliest comment starter
X+       is followed by uniform paired string quotes or none,
X+       we know it can't be inside a string
X+       since if it were then the comment ender would be inside one.
X+       So it does start a comment.  Skip back to it.  */
X+    else if (comstart_parity == 0 && !string_lossage)
X+	from = comstart_pos;
X+    else
X+    {
X+      /* We had two kinds of string delimiters mixed up
X+	 together.  Decode this going forwards.
X+	 Scan fwd from the previous comment ender
X+	 to the one in question; this records where we
X+	 last passed a comment starter.  */
X+
X+      struct lisp_parse_state state;
X+      scan_sexps_forward (&state, find_defun_start (comment_end),
X+			  comment_end - 1, -10000, 0, Qnil);
X+      if (state.incomment)
X+	from = state.comstart;
X+      else
X+      /* We can't grok this as a comment; scan it normally.  */
X+	from = comment_end;
X+    }
X+    return from;
X+}  
X+
X+static int
X+find_end_of_comment (from, stop, mask)
X+     int from, stop, mask;
X+{
X+  int c, c1;
X+
X+  while (1)
X+    {
X+      if (from == stop)
X+	{
X+	  return -1;
X+	}
X+      FETCH_MC_CHAR (c, from);
X+      if (SYNTAX (c) == Sendcomment
X+	  && SYNTAX_STYLES_MATCH_1CHAR_P (c, mask))
X+	/* we have encountered a comment end of the same style
X+	   as the comment sequence which began this comment
X+	   section */
X+	break;
X+
X+      INC_POS (from);
X+      FETCH_MC_CHAR (c1, from);
X+      if (from < stop
X+	  && SYNTAX_STYLES_MATCH_END_P (c, c1, mask))
X+	/* we have encountered a comment end of the same style
X+	   as the comment sequence which began this comment
X+	   section */
X+	{ INC_POS (from); break; }
X+    }
X+  return from;
X+}
X+
X+
X int parse_sexp_ignore_comments;
X 
X+DEFUN ("forward-comment", Fforward_comment, Sforward_comment, 1, 1, 0,
X+  "Move forward across up to N comments.  If N is negative, move backward.\n\
X+Set point to the far end of the last comment found.\n\
X+Stop scanning if we find something other than a comment or whitespace.\n\
X+If N comments are found as expected, with nothing except whitespace\n\
X+between them, return t; otherwise return nil.  Point is set in either case.")
X+  (cntarg)
X+     Lisp_Object cntarg;
X+{
X+  register int from, temp;
X+  register int stop;
X+  register int c, c1;
X+  register enum syntaxcode code;
X+  int count;
X+  int mask = 0;			/* mask for finding matching comment style */
X+
X+  CHECK_NUMBER (cntarg, 0);
X+  count = XINT (cntarg);
X+
X+  immediate_quit = 1;
X+  QUIT;
X+
X+  from = PT;
X+
X+  while (count > 0)
X+    {
X+      stop = ZV;
X+      while (from < stop)
X+	{
X+	  if (char_quoted (from))
X+	    { INC_POS (from); continue; }
X+
X+	  FETCH_MC_CHAR (c, from);
X+	  code = SYNTAX (c);
X+	  mask = 0x0;
X+
X+	  temp = from;
X+	  INC_POS (temp);
X+	  FETCH_MC_CHAR (c1, temp);
X+
X+	  if (code == Scomment)
X+	    {
X+	      /* we have encountered a single character comment start
X+		 sequence, and we are ignoring all text inside comments.
X+		 we must record the comment style this character begins
X+		 so that later, only a comment end of the same style actually
X+		 ends the comment section */
X+	      mask = SYNTAX_COMMENT_1CHAR_MASK (c);
X+	    }
X+
X+	  else if (from < stop && SYNTAX_START_P (c, c1))
X+	    {
X+	      /* we have encountered a 2char comment start sequence and we 
X+		 are ignoring all text inside comments. we must record
X+		 the comment style this sequence begins so that later,
X+		 only a comment end of the same style actually ends
X+		 the comment section */
X+	      code = Scomment;
X+	      mask = SYNTAX_COMMENT_MASK_START (c, c1);
X+	      from = temp;
X+	    }
X+
X+	  if (code == Scomment)
X+	    {
X+	      int newfrom;
X+
X+	      newfrom = find_end_of_comment (from, stop, mask);
X+	      if (newfrom < 0)
X+		{
X+		  /* we stopped because from==stop */
X+		  immediate_quit = 0;
X+		  SET_PT (stop);
X+		  return Qnil;
X+		}
X+	      from = newfrom;
X+
X+	      /* We have skipped one comment.  */
X+	      break;
X+	    }
X+	  else if (code != Swhitespace
X+		   && code != Sendcomment
X+		   && code != Scomment)
X+	    {
X+	      immediate_quit = 0;
X+	      SET_PT (from);
X+	      return Qnil;
X+	    }
X+	  INC_POS (from);
X+	}
X+
X+      /* End of comment reached */
X+      count--;
X+    }
X+
X+  while (count < 0)
X+    {
X+      stop = BEGV;
X+      while (from > stop)
X+	{
X+	  int quoted;
X+
X+	  DEC_POS (from);
X+	  if (char_quoted (from))
X+	    { DEC_POS (from); continue; }
X+	      
X+	  FETCH_MC_CHAR (c, from);
X+	  code = SYNTAX (c);
X+	  mask = 0x0;
X+
X+	  temp = from;
X+	  DEC_POS (temp);
X+	  FETCH_MC_CHAR (c1, temp);
X+
X+	  if (code == Sendcomment)
X+	    {
X+	      /* we have found a single char end comment. we must record
X+		 the comment style encountered so that later, we can match
X+		 only the proper comment begin sequence of the same style */
X+	      mask = SYNTAX_COMMENT_1CHAR_MASK (c);
X+	    }
X+
X+	  else if (from > stop
X+		   && SYNTAX_END_P (c1, c)
X+		   && !char_quoted (temp))
X+	    {
X+	      /* we must record the comment style encountered so that
X+		 later, we can match only the proper comment begin
X+		 sequence of the same style */
X+	      code = Sendcomment;
X+	      mask = SYNTAX_COMMENT_MASK_END (c1, c);
X+	      from = temp;
X+	    }
X+
X+	  if (code == Sendcomment)
X+	    {
X+	      from = find_start_of_comment (from, stop, mask);
X+	      break;
X+	    }
X+	  else if (code != Swhitespace &&
X+		   SYNTAX (c) != Scomment &&
X+		   SYNTAX (c) != Sendcomment)
X+	    {
X+	      immediate_quit = 0;
X+	      INC_POS (from);
X+	      SET_PT (from);
X+	      return Qnil;
X+	    }
X+	}
X+
X+      count++;
X+    }
X+
X+  SET_PT (from);
X+  immediate_quit = 0;
X+  return Qt;
X+}
X+
X+
X Lisp_Object
X scan_lists (from, count, depth, sexpflag)
X      register int from;
X@@ -700,6 +1259,7 @@
X   int mathexit = 0;
X   register enum syntaxcode code;
X   int min_depth = depth;    /* Err out if depth gets less than this. */
X+  int mask = 0x0;	    /* comment style mask */
X 
X   if (depth > 0) min_depth = 0;
X 
X@@ -712,16 +1272,33 @@
X       while (from < stop)
X 	{
X 	  FETCH_MC_CHAR (c, from);
X-	  code = SYNTAX(c);
X+	  code = SYNTAX (c);
X 	  INC_POS (from);
X-	  if (from < stop && SYNTAX_COMSTART_FIRST (c)) {
X-	    FETCH_MC_CHAR (c, from);
X-	    if (SYNTAX_COMSTART_SECOND (c)
X-		&& parse_sexp_ignore_comments) {
X-	      code = Scomment;
X-	      INC_POS (from);
X+
X+	  /* a 1-char comment start sequence */
X+	  if (code == Scomment && parse_sexp_ignore_comments)
X+	    {
X+	      mask = SYNTAX_COMMENT_1CHAR_MASK (c);
X 	    }
X-	  }
X+	  /* else, a 2-char comment start sequence? */
X+	  else if (from < stop)
X+	    {
X+	      FETCH_MC_CHAR (c1, from);
X+	      if (SYNTAX_START_P (c, c1) && parse_sexp_ignore_comments)
X+		{
X+		  /* we have encountered a comment start sequence and we 
X+		     are ignoring all text inside comments. we must record
X+		     the comment style this sequence begins so that later,
X+		     only a comment end of the same style actually ends
X+		     the comment section */
X+		  code = Scomment;
X+		  mask = SYNTAX_COMMENT_MASK_START (c, c1);
X+		  INC_POS (from);
X+		}
X+	    }
X+	  
X+	  if (SYNTAX_PREFIX (c))
X+	    continue;
X 
X #ifdef SWITCH_ENUM_BUG
X 	  switch ((int) code)
X@@ -767,18 +1344,16 @@
X 
X 	    case Scomment:
X 	      if (!parse_sexp_ignore_comments) break;
X-	      while (1)
X-		{
X-		  if (from == stop) goto done;
X-		  FETCH_MC_CHAR (c, from);
X-		  if (SYNTAX (c) == Sendcomment)
X-		    break;
X-		  INC_POS (from);
X-		  FETCH_MC_CHAR (c1, from);
X-		  if (from < stop && SYNTAX_COMEND_FIRST (c)
X-		       && SYNTAX_COMEND_SECOND (c1))
X-		    { INC_POS (from); break; }
X-		}
X+	      {
X+		int newfrom = find_end_of_comment (from, stop, mask);
X+		if (newfrom < 0)
X+		  {
X+		    /* we stopped because from == stop in search forward */
X+		    from = stop;
X+		    goto done;
X+		  }
X+		from = newfrom;
X+	      }
X 	      break;
X 
X 	    case Smath:
X@@ -849,20 +1424,41 @@
X 	  DEC_POS (from);
X 	  if (quoted = char_quoted (from))
X 	    DEC_POS (from);
X+
X 	  FETCH_MC_CHAR (c, from);
X 	  code = SYNTAX (c);
X-	  if (from > stop && SYNTAX_COMEND_SECOND (c)) {
X-	    temp = from;
X-	    DEC_POS (temp);
X-	    FETCH_MC_CHAR (c, temp);
X-	    if (SYNTAX_COMEND_FIRST (c)
X-		&& !char_quoted (temp)
X-		&& parse_sexp_ignore_comments) {
X-	      code = Sendcomment;
X-	      from = temp;
X+	  mask = 0x0;
X+
X+	  if (code == Sendcomment && parse_sexp_ignore_comments)
X+	    {
X+	      /* we have found a single char end comment. we must record
X+		 the comment style encountered so that later, we can match
X+		 only the proper comment begin sequence of the same style */
X+	      mask = SYNTAX_COMMENT_1CHAR_MASK (c);
X 	    }
X-	  }
X+
X+	  else if (from > stop)
X+	    {
X+	      temp = from;
X+	      DEC_POS (temp);
X+	      FETCH_MC_CHAR (c1, temp);
X+
X+	      if (SYNTAX_END_P (c1, c)
X+		  && !char_quoted (temp)
X+		  && parse_sexp_ignore_comments)
X+		{
X+		  /* we must record the comment style encountered so that
X+		     later, we can match only the proper comment begin
X+		     sequence of the same style */
X+		  code = Sendcomment;
X+		  mask = SYNTAX_COMMENT_MASK_END (c1, c);
X+		  from = temp;
X+		}
X+	    }
X 
X+	  if (SYNTAX_PREFIX (c))
X+	    continue;
X+
X #ifdef SWITCH_ENUM_BUG
X 	  switch ((int) (quoted ? Sword : code))
X #else
X@@ -873,7 +1469,8 @@
X 	    case Sextword:	/* 92.7.16 by K.Handa */
X 	    case Ssymbol:
X 	      if (depth || !sexpflag) break;
X-	      /* This word counts as a sexp; count object finished after passing it. */
X+	      /* This word counts as a sexp; count object finished after 
X+		 passing it. */
X 	      while (from > stop)
X 		{
X 		  enum syntaxcode s; /* 92.7.16 by K.Handa */
X@@ -921,6 +1518,7 @@
X 	      break;
X 
X 	    case Sendcomment:
X+#if 0
X 	      if (!parse_sexp_ignore_comments) break;
X 	      if (from != stop) DEC_POS (from);
X 	      while (1)
X@@ -936,6 +1534,10 @@
X 		      && !char_quoted (from))
X 		    break;
X 		}
X+#else
X+	      if (parse_sexp_ignore_comments)
X+		from = find_start_of_comment (from, stop, mask);
X+#endif
X 	      break;
X 
X 	    case Sstring:
X@@ -974,8 +1576,10 @@
X  lose:
X   error ("Unbalanced parentheses");
X   /* NOTREACHED */
X+  return Qnil; /* warning suppression */
X }
X 
X+static int
X char_quoted (pos)
X      register int pos;
X {
X@@ -1002,9 +1606,9 @@
X are candidates for stopping; COUNT such places are counted.\n\
X Thus, a positive value for DEPTH means go out levels.\n\
X \n\
X-Comments are ignored if parse-sexp-ignore-comments is non-nil.\n\
X+Comments are ignored if `parse-sexp-ignore-comments' is non-nil.\n\
X \n\
X-If the beginning or end of (the visible part of) the buffer is reached\n\
X+If the beginning or end of (the accessible part of) the buffer is reached\n\
X and the depth is wrong, an error is signaled.\n\
X If the depth is right but the count is not used up, nil is returned.")
X   (from, count, depth)
X@@ -1019,14 +1623,15 @@
X 
X DEFUN ("scan-sexps", Fscan_sexps, Sscan_sexps, 2, 2, 0,
X   "Scan from character number FROM by COUNT balanced expressions.\n\
X+If COUNT is negative, scan backwards.\n\
X Returns the character number of the position thus found.\n\
X \n\
X-Comments are ignored if parse-sexp-ignore-comments is non-nil.\n\
X+Comments are ignored if `parse-sexp-ignore-comments' is non-nil.\n\
X \n\
X-If the beginning or end of (the visible part of) the buffer is reached\n\
X+If the beginning or end of (the accessible part of) the buffer is reached\n\
X in the middle of a parenthetical grouping, an error is signaled.\n\
X-If the beginning or end is reached between groupings but before count is used up,\n\
X-nil is returned.")
X+If the beginning or end is reached between groupings\n\
X+but before count is used up, nil is returned.")
X   (from, count)
X      Lisp_Object from, count;
X {
X@@ -1038,40 +1643,36 @@
X 
X DEFUN ("backward-prefix-chars", Fbackward_prefix_chars, Sbackward_prefix_chars,
X   0, 0, 0,
X-  "Move point backward over any number of chars with syntax \"prefix\".")
X+  "Move point backward over any number of chars with prefix syntax.\n\
X+This includes chars with \"quote\" or \"prefix\" syntax (' or p).")
X   ()
X {
X   int beg = BEGV;
X-  int pos = point;
X+  int pos, prev;
X+  int c;
X 
X-  while (pos > beg && !char_quoted (pos - 1) && SYNTAX (FETCH_CHAR (pos - 1)) == Squote)
X-    pos--;
X+  pos = prev = point;
X+  while (pos > beg)
X+    {
X+      pos = prev;
X+      DEC_POS (prev);
X+      FETCH_MC_CHAR (c, prev);
X+      if (char_quoted (prev) || !(SYNTAX (c) == Squote || SYNTAX_PREFIX (c)))
X+	break;
X+    }
X 
X   SET_PT (pos);
X 
X   return Qnil;
X }
X 
X-struct lisp_parse_state
X-  {
X-    int depth;		/* Depth at end of parsing */
X-    int instring;	/* -1 if not within string, else desired terminator. */
X-    int incomment;	/* Nonzero if within a comment at end of parsing */
X-    int quoted;		/* Nonzero if just after an escape char at end of parsing */
X-    int thislevelstart;	/* Char number of most recent start-of-expression at current level */
X-    int prevlevelstart; /* Char number of start of containing expression */
X-    int location;	/* Char number at which parsing stopped. */
X-    int mindepth;	/* Minimum depth seen while scanning.  */
X-  };
X-
X /* Parse forward from FROM to END,
X    assuming that FROM is the start of a function, 
X    and return a description of the state of the parse at END. */
X 
X-struct lisp_parse_state val_scan_sexps_forward;
X-
X-struct lisp_parse_state *
X-scan_sexps_forward (from, end, targetdepth, stopbefore, oldstate)
X+static void
X+scan_sexps_forward (stateptr, from, end, targetdepth, stopbefore, oldstate)
X+     struct lisp_parse_state *stateptr;
X      register int from;
X      int end, targetdepth, stopbefore;
X      Lisp_Object oldstate;
X@@ -1090,6 +1691,7 @@
X   int mindepth;		/* Lowest DEPTH value seen.  */
X   int start_quoted = 0;		/* Nonzero means starting after a char quote */
X   Lisp_Object tem;
X+  int mask;				     /* comment mask */
X 
X   immediate_quit = 1;
X   QUIT;
X@@ -1099,6 +1701,8 @@
X       depth = 0;
X       state.instring = -1;
X       state.incomment = 0;
X+      state.comstyle = 0;	/* default comstyle is a */
X+      mask = SYNTAX_COMMENT_STYLE_A;
X     }
X   else
X     {
X@@ -1121,6 +1725,15 @@
X       oldstate = Fcdr (oldstate);
X       tem = Fcar (oldstate);
X       start_quoted = !NULL (tem);
X+
X+      /* if eighth element of the list is nil, we are in comment style
X+	 a. if it is non-nil, we are in comment style b */
X+      oldstate = Fcdr (oldstate);
X+      oldstate = Fcdr (oldstate);
X+      oldstate = Fcdr (oldstate);
X+      tem = Fcar (oldstate);
X+      state.comstyle = !NULL (tem);
X+      mask = state.comstyle ? SYNTAX_COMMENT_STYLE_B : SYNTAX_COMMENT_STYLE_A;
X     }
X   state.quoted = 0;
X   mindepth = depth;
X@@ -1140,11 +1753,39 @@
X 
X   while (from < end)
X     {
X-      code = SYNTAX(FETCH_CHAR (from));
X-      from++;
X-      if (from < end && SYNTAX_COMSTART_FIRST (FETCH_CHAR (from - 1))
X-	   && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from)))
X-	code = Scomment, from++;
X+      int c, c1, temp;
X+
X+      FETCH_MC_CHAR (c1, from);
X+      code = SYNTAX (c1);
X+      temp = from;
X+      INC_POS (from);
X+      FETCH_MC_CHAR (c, from);
X+
X+      if (code == Scomment)
X+	{
X+	  /* record the comment style we have entered so that only the
X+	     comment-ender sequence (or single char) of the same style
X+	     actually terminates the comment section. */
X+	  mask = SYNTAX_COMMENT_1CHAR_MASK (c1);
X+	  state.comstyle = (mask == SYNTAX_COMMENT_STYLE_B);
X+	  state.comstart = temp;
X+	}
X+      
X+      else if (from < end && SYNTAX_START_P (c1, c))
X+	{
X+	  /* Record the comment style we have entered so that only
X+	     the comment-end sequence of the same style actually
X+	     terminates the comment section.  */
X+	  code = Scomment;
X+	  mask = SYNTAX_COMMENT_MASK_START (c1, c);
X+	  state.comstyle = (mask == SYNTAX_COMMENT_STYLE_B);
X+	  state.comstart = temp;
X+	  INC_POS (from);
X+	}
X+
X+      if (SYNTAX_PREFIX (c1))
X+	continue;
X+
X #ifdef SWITCH_ENUM_BUG
X       switch ((int) code)
X #else
X@@ -1154,29 +1795,32 @@
X 	case Sescape:
X 	case Scharquote:
X 	  if (stopbefore) goto stop;  /* this arg means stop at sexp start */
X-	  curlevel->last = from - 1;
X+	  curlevel->last = from;
X+	  DEC_POS (curlevel->last);
X 	startquoted:
X 	  if (from == end) goto endquoted;
X-	  from++;
X+	  INC_POS (from);
X 	  goto symstarted;
X 	  /* treat following character as a word constituent */
X 	case Sword:
X 	case Sextword:		/* 92.7.16 by K.Handa */
X 	case Ssymbol:
X 	  if (stopbefore) goto stop;  /* this arg means stop at sexp start */
X-	  curlevel->last = from - 1;
X+	  curlevel->last = from;
X+	  DEC_POS (curlevel->last);
X 	symstarted:
X 	  while (from < end)
X 	    {
X+	      FETCH_MC_CHAR (c, from);
X #ifdef SWITCH_ENUM_BUG
X-	      switch ((int) SYNTAX(FETCH_CHAR (from)))
X+	      switch ((int) SYNTAX (c))
X #else
X-	      switch (SYNTAX(FETCH_CHAR (from)))
X+	      switch (SYNTAX (c))
X #endif
X 		{
X 		case Scharquote:
X 		case Sescape:
X-		  from++;
X+		  INC_POS (from);
X 		  if (from == end) goto endquoted;
X 		  break;
X 		case Sword:
X@@ -1187,7 +1831,7 @@
X 		default:
X 		  goto symdone;
X 		}
X-	      from++;
X+	      INC_POS (from);
X 	    }
X 	symdone:
X 	  curlevel->prev = curlevel->last;
X@@ -1196,24 +1840,28 @@
X 	case Scomment:
X 	  state.incomment = 1;
X 	startincomment:
X-	  while (1)
X-	    {
X-	      if (from == end) goto done;
X-	      if (SYNTAX (prev = FETCH_CHAR (from)) == Sendcomment)
X-		break;
X-	      from++;
X-	      if (from < end && SYNTAX_COMEND_FIRST (prev)
X-		   && SYNTAX_COMEND_SECOND (FETCH_CHAR (from)))
X-		{ from++; break; }
X-	    }
X+	  {
X+	    int newfrom = find_end_of_comment (from, end, mask);
X+	    if (newfrom < 0)
X+	      {
X+		/* we terminated search because from == end */
X+		from = end;
X+		goto done;
X+	      }
X+	    from = newfrom;
X+	  }
X 	  state.incomment = 0;
X+	  state.comstyle = 0;		     /* reset the comment style */
X+	  mask = 0;
X 	  break;
X 
X 	case Sopen:
X 	  if (stopbefore) goto stop;  /* this arg means stop at sexp start */
X 	  depth++;
X 	  /* curlevel++->last ran into compiler bug on Apollo */
X-	  curlevel->last = from - 1;
X+	  temp = from;
X+	  DEC_POS (temp);
X+	  curlevel->last = temp;
X 	  if (++curlevel == endlevel)
X 	    error ("Nesting too deep for parser");
X 	  curlevel->prev = -1;
X@@ -1233,30 +1881,35 @@
X 
X 	case Sstring:
X 	  if (stopbefore) goto stop;  /* this arg means stop at sexp start */
X-	  curlevel->last = from - 1;
X-	  state.instring = FETCH_CHAR (from - 1);
X+	  temp = from;
X+	  DEC_POS (temp);
X+	  FETCH_MC_CHAR (c, temp);
X+	  curlevel->last = temp;
X+	  state.instring = c;
X 	startinstring:
X 	  while (1)
X 	    {
X 	      if (from >= end) goto done;
X-	      if (FETCH_CHAR (from) == state.instring) break;
X+
X+	      FETCH_MC_CHAR (c, from);
X+	      if (c == state.instring) break;
X #ifdef SWITCH_ENUM_BUG
X-	      switch ((int) SYNTAX(FETCH_CHAR (from)))
X+	      switch ((int) SYNTAX (c))
X #else
X-	      switch (SYNTAX(FETCH_CHAR (from)))
X+	      switch (SYNTAX (c))
X #endif
X 		{
X 		case Scharquote:
X 		case Sescape:
X-		  from++;
X+		  INC_POS (from);
X 		startquotedinstring:
X 		  if (from >= end) goto endquoted;
X 		}
X-	      from++;
X+	      INC_POS (from);
X 	    }
X 	  state.instring = -1;
X 	  curlevel->prev = curlevel->last;
X-	  from++;
X+	  INC_POS (from);
X 	  break;
X 
X 	case Smath:
X@@ -1266,7 +1919,7 @@
X   goto done;
X 
X  stop:   /* Here if stopping before start of sexp. */
X-  from--;    /* We have just fetched the char that starts it; */
X+  DEC_POS (from);    /* We have just fetched the char that starts it; */
X   goto done; /* but return the position before it. */
X 
X  endquoted:
X@@ -1280,21 +1933,20 @@
X   state.location = from;
X   immediate_quit = 0;
X 
X-  val_scan_sexps_forward = state;
X-  return &val_scan_sexps_forward;
X+  *stateptr = state;
X }
X 
X /* This comment supplies the doc string for parse-partial-sexp,
X    for make-docfile to see.  We cannot put this in the real DEFUN
X    due to limits in the Unix cpp.
X 
X-DEFUN ("parse-partial-sexp", Ffoo, Sfoo, 0, 0, 0,
X+DEFUN ("parse-partial-sexp", Ffoo, Sfoo, 2, 5, 0,
X   "Parse Lisp syntax starting at FROM until TO; return status of parse at TO.\n\
X Parsing stops at TO or when certain criteria are met;\n\
X  point is set to where parsing stops.\n\
X If fifth arg STATE is omitted or nil,\n\
X  parsing assumes that FROM is the beginning of a function.\n\
X-Value is a list of seven elements describing final state of parsing:\n\
X+Value is a list of eight elements describing final state of parsing:\n\
X  1. depth in parens.\n\
X  2. character address of start of innermost containing list; nil if none.\n\
X  3. character address of start of last complete sexp terminated.\n\
X@@ -1303,13 +1955,14 @@
X  5. t if inside a comment.\n\
X  6. t if following a quote character.\n\
X  7. the minimum paren-depth encountered during this scan.\n\
X+ 8. nil if in comment style a, or not in a comment; t if in comment style b\n\
X If third arg TARGETDEPTH is non-nil, parsing stops if the depth\n\
X in parentheses becomes equal to TARGETDEPTH.\n\
X Fourth arg STOPBEFORE non-nil means stop when come to\n\
X  any character that starts a sexp.\n\
X Fifth arg STATE is a seven-list like what this function returns.\n\
X It is used to initialize the state of the parse.")
X-
X+  (from, to, targetdepth, stopbefore, oldstate)
X */
X 
X DEFUN ("parse-partial-sexp", Fparse_partial_sexp, Sparse_partial_sexp, 2, 5, 0,
X@@ -1329,8 +1982,8 @@
X     target = -100000;		/* We won't reach this depth */
X 
X   validate_region (&from, &to);
X-  state = *scan_sexps_forward (XINT (from), XINT (to),
X-			       target, !NULL (stopbefore), oldstate);
X+  scan_sexps_forward (&state, XINT (from), XINT (to),
X+		      target, !NULL (stopbefore), oldstate);
X 
X   SET_PT (state.location);
X   
X@@ -1340,9 +1993,12 @@
X 	       Fcons (state.instring >= 0 ? make_number (state.instring) : Qnil,
X 		 Fcons (state.incomment ? Qt : Qnil,
X 		   Fcons (state.quoted ? Qt : Qnil,
X-			  Fcons (make_number (state.mindepth), Qnil)))))));
X+		     Fcons (make_number (state.mindepth), 
X+		       Fcons (state.comstyle ? Qt : Qnil,
X+			    Qnil))))))));
X }
X 
X+void
X init_syntax_once ()
X {
X   register int i;
X@@ -1381,18 +2037,19 @@
X     XFASTINT (v->contents[".,;:?!#@~^'`"[i]]) = (int) Spunct;
X }
X 
X+void
X syms_of_syntax ()
X {
X   Qsyntax_table_p = intern ("syntax-table-p");
X   staticpro (&Qsyntax_table_p);
X 
X   DEFVAR_BOOL ("parse-sexp-ignore-comments", &parse_sexp_ignore_comments,
X-    "Non-nil means forward-sexp, etc., should treat comments as whitespace.\n\
X-Non-nil works only when the comment terminator is something like *\/,\n\
X-and appears only when it ends a comment.\n\
X-If comments are terminated by newlines,\n\
X-you must make this variable nil.");
X+    "Non-nil means `forward-sexp', etc., should treat comments as whitespace.");
X 
X+  words_include_escapes = 0;
X+  DEFVAR_BOOL ("words-include-escapes", &words_include_escapes,
X+    "Non-nil means `forward-word', etc., should treat escape chars part of words.");
X+
X   defsubr (&Ssyntax_table_p);
X   defsubr (&Ssyntax_table);
X   defsubr (&Sstandard_syntax_table);
X@@ -1407,10 +2064,12 @@
X   defsubr (&Sdescribe_syntax);
X 
X   defsubr (&Sforward_word);
X+  defsubr (&Sforward_comment);
X 
X   defsubr (&Sscan_lists);
X   defsubr (&Sscan_sexps);
X   defsubr (&Sbackward_prefix_chars);
X+
X   defsubr (&Sparse_partial_sexp);
X }
X 
X--- orig/syntax.h	Tue Jun 15 08:08:47 1993
X+++ syntax.h	Wed Jun 16 08:02:23 1993
X@@ -1,11 +1,11 @@
X /* Declarations having to do with GNU Emacs syntax tables.
X-   Copyright (C) 1985 Free Software Foundation, Inc.
X+   Copyright (C) 1985, 1992, 1993 Free Software Foundation, Inc.
X 
X This file is part of GNU Emacs.
X 
X GNU Emacs is free software; you can redistribute it and/or modify
X it under the terms of the GNU General Public License as published by
X-the Free Software Foundation; either version 1, or (at your option)
X+the Free Software Foundation; either version 2, or (at your option)
X any later version.
X 
X GNU Emacs is distributed in the hope that it will be useful,
X@@ -22,6 +22,8 @@
X /* 92.7.16  modified for Mule Ver.0.9.5 by K.Handa <handa@etl.go.jp>
X 	Sextword is appended in syntaxcode. */
X 
X+#ifndef _EMACS_SYNTAX_H_
X+#define _EMACS_SYNTAX_H_
X 
X extern Lisp_Object Qsyntax_table_p;
X extern Lisp_Object Fsyntax_table_p (), Fsyntax_table (), Fset_syntax_table ();
X@@ -30,9 +32,11 @@
X    be used in all new buffers.  */
X #define Vstandard_syntax_table buffer_defaults.syntax_table
X 
X+
X /* A syntax table is a Lisp vector of length 0400, whose elements are integers.
X 
X-The low 8 bits of the integer is a code, as follows:
X+The low 7 bits of the integer is a code, as follows. The 8th bit is
X+used as the prefix bit flag (see below).
X */
X 
X enum syntaxcode
X@@ -57,40 +61,108 @@
X /* 92.1.10 by K.Handa */
X extern Lisp_Object char_syntax(), char_syntax_at();
X 
X-#define SYNTAX(c) ((enum syntaxcode) (XFASTINT (char_syntax(c)) & 0xFF))
X+#define SYNTAX(c) ((enum syntaxcode) (XFASTINT (char_syntax(c)) & 0177))
X 
X #define SYNTAX_AT(p,len) \
X   ((enum syntaxcode) (XFASTINT (char_syntax_at(p, len)) & 0xFF))
X 
X+/* If emacs was compiled with the NEW_SYNTAX flag, then the prefix
X+   flag bit for backward-prefix-chars is put into bit 7. */
X+#define SYNTAX_PREFIX(c) \
X+  ((XUINT (char_syntax (c)) >> 7) & 1)
X+
X /* The next 8 bits of the number is a character,
X  the matching delimiter in the case of Sopen or Sclose. */
X 
X #define SYNTAX_MATCH(c) \
X-  ((XFASTINT (char_syntax(c)) >> 8) & 0377)
X-
X-/* Then there are four single-bit flags that have the following meanings:
X-  1. This character is the first of a two-character comment-start sequence.
X-  2. This character is the second of a two-character comment-start sequence.
X-  3. This character is the first of a two-character comment-end sequence.
X-  4. This character is the second of a two-character comment-end sequence.
X- Note that any two-character sequence whose first character has flag 1
X-  and whose second character has flag 2 will be interpreted as a comment start. */
X-
X-#define SYNTAX_COMSTART_FIRST(c) \
X-  ((XFASTINT (char_syntax(c)) >> 16) & 1)
X-
X-#define SYNTAX_COMSTART_SECOND(c) \
X-  ((XFASTINT (char_syntax(c)) >> 17) & 1)
X+  ((XUINT (char_syntax(c)) >> 8) & 0377)
X 
X-#define SYNTAX_COMEND_FIRST(c) \
X-  ((XFASTINT (char_syntax(c)) >> 18) & 1)
X+/* The next 8 bits are used to implement up to two comment styles
X+   in a single buffer. They have the following meanings:
X+  
X+  1. first of a one or two character comment-start sequence of style a.
X+  2. first of a one or two character comment-start sequence of style b.
X+  3. second of a two-character comment-start sequence of style a.
X+  4. second of a two-character comment-start sequence of style b.
X+  5. first of a one or two character comment-end sequence of style a.
X+  6. first of a one or two character comment-end sequence of style b.
X+  7. second of a two-character comment-end sequence of style a.
X+  8. second of a two-character comment-end sequence of style b.
X+ */
X+
X+#define SYNTAX_COMMENT_BITS(c) \
X+  ((XUINT (char_syntax (c)) >> 16) & 0xff)
X+
X+#define SYNTAX_FIRST_OF_START_A  0x80
X+#define SYNTAX_FIRST_OF_START_B  0x40
X+#define SYNTAX_SECOND_OF_START_A 0x20
X+#define SYNTAX_SECOND_OF_START_B 0x10
X+#define SYNTAX_FIRST_OF_END_A    0x08
X+#define SYNTAX_FIRST_OF_END_B    0x04
X+#define SYNTAX_SECOND_OF_END_A   0x02
X+#define SYNTAX_SECOND_OF_END_B   0x01
X+
X+#define SYNTAX_COMMENT_STYLE_A   0xaa
X+#define SYNTAX_COMMENT_STYLE_B   0x55
X+#define SYNTAX_FIRST_CHAR_START  0xc0
X+#define SYNTAX_FIRST_CHAR_END    0x0c
X+#define SYNTAX_FIRST_CHAR        0xcc
X+#define SYNTAX_SECOND_CHAR_START 0x30
X+#define SYNTAX_SECOND_CHAR_END   0x03
X+#define SYNTAX_SECOND_CHAR       0x33
X+
X+#define SYNTAX_START_P(a,b) \
X+((SYNTAX_COMMENT_BITS(a)&SYNTAX_FIRST_CHAR_START) \
X+ &&(SYNTAX_COMMENT_BITS(b)&SYNTAX_SECOND_CHAR_START))
X+
X+#define SYNTAX_END_P(a,b) \
X+((SYNTAX_COMMENT_BITS(a)&SYNTAX_FIRST_CHAR_END) \
X+ &&(SYNTAX_COMMENT_BITS(b)&SYNTAX_SECOND_CHAR_END))
X+
X+#define SYNTAX_STYLES_MATCH_START_P(a,b,mask) \
X+((SYNTAX_COMMENT_BITS(a)&SYNTAX_FIRST_CHAR_START&(mask)) \
X+ &&(SYNTAX_COMMENT_BITS(b)&SYNTAX_SECOND_CHAR_START&(mask)))
X+
X+#define SYNTAX_STYLES_MATCH_END_P(a,b,mask) \
X+((SYNTAX_COMMENT_BITS(a)&SYNTAX_FIRST_CHAR_END&(mask)) \
X+ &&(SYNTAX_COMMENT_BITS(b)&SYNTAX_SECOND_CHAR_END&(mask)))
X+
X+#define SYNTAX_STYLES_MATCH_1CHAR_P(a,mask) \
X+((SYNTAX_COMMENT_BITS(a)&(mask)))
X+
X+#define STYLE_FOUND_P(a,b,startp,style) \
X+((SYNTAX_COMMENT_BITS(a) & \
X+  ((startp) ? SYNTAX_FIRST_CHAR_START : SYNTAX_FIRST_CHAR_END) & (style)) \
X+ &&(SYNTAX_COMMENT_BITS(b) & \
X+	((startp) ? SYNTAX_SECOND_CHAR_START : SYNTAX_SECOND_CHAR_END) &(style)))
X+
X+#define SYNTAX_COMMENT_MASK_START(a,b) \
X+((STYLE_FOUND_P((a),(b),1,SYNTAX_COMMENT_STYLE_A) ? SYNTAX_COMMENT_STYLE_A \
X+  : (STYLE_FOUND_P((a),(b),1,SYNTAX_COMMENT_STYLE_B) ? SYNTAX_COMMENT_STYLE_B \
X+	 : 0)))
X+
X+#define SYNTAX_COMMENT_MASK_END(a,b) \
X+((STYLE_FOUND_P((a),(b),0,SYNTAX_COMMENT_STYLE_A) ? SYNTAX_COMMENT_STYLE_A \
X+  : (STYLE_FOUND_P((a),(b),0,SYNTAX_COMMENT_STYLE_B) ? SYNTAX_COMMENT_STYLE_B \
X+	 : 0)))
X+
X+#define STYLE_FOUND_1CHAR_P(a,style) \
X+((SYNTAX_COMMENT_BITS(a)&(style)))
X+
X+#define SYNTAX_COMMENT_1CHAR_MASK(a) \
X+((STYLE_FOUND_1CHAR_P((a),SYNTAX_COMMENT_STYLE_A) ? SYNTAX_COMMENT_STYLE_A \
X+  : (STYLE_FOUND_1CHAR_P((a),SYNTAX_COMMENT_STYLE_B) ? SYNTAX_COMMENT_STYLE_B \
X+	 : 0)))
X 
X-#define SYNTAX_COMEND_SECOND(c) \
X-  ((XFASTINT (char_syntax(c)) >> 19) & 1)
X-
X /* This array, indexed by a character, contains the syntax code which that
X  character signifies (as a char).  For example,
X  (enum syntaxcode) syntax_spec_code['w'] is Sword. */
X 
X extern unsigned char syntax_spec_code[0400];
X+
X+/* Indexed by syntax code, give the letter that describes it. */
X+
X+extern unsigned char syntax_code_spec[14];
X+
X+#endif /* _EMACS_SYNTAX_H_ */
X 
END_OF_FILE
if test 49926 -ne `wc -c <'syntax.MULE-0.9.8'`; then
    echo shar: \"'syntax.MULE-0.9.8'\" unpacked with wrong size!
fi
# end of 'syntax.MULE-0.9.8'
fi
echo shar: End of shell archive.
exit 0


